Browse code

libcontainerd: reuse our pkg/locker

it fixes race with access to containerMutexes

Signed-off-by: Alexander Morozov <lk4d4@docker.com>
(cherry picked from commit a7851e2556edb3e5333b6fe53160755fb5b7d616)

Alexander Morozov authored on 2016/03/30 01:43:12
Showing 3 changed files
... ...
@@ -4,35 +4,23 @@ import (
4 4
 	"fmt"
5 5
 	"sync"
6 6
 
7
-	"github.com/Sirupsen/logrus"
7
+	"github.com/docker/docker/pkg/locker"
8 8
 )
9 9
 
10 10
 // clientCommon contains the platform agnostic fields used in the client structure
11 11
 type clientCommon struct {
12
-	backend          Backend
13
-	containers       map[string]*container
14
-	containerMutexes map[string]*sync.Mutex // lock by container ID
15
-	mapMutex         sync.RWMutex           // protects read/write oprations from containers map
16
-	sync.Mutex                              // lock for containerMutexes map access
12
+	backend    Backend
13
+	containers map[string]*container
14
+	locker     *locker.Locker
15
+	mapMutex   sync.RWMutex // protects read/write oprations from containers map
17 16
 }
18 17
 
19 18
 func (clnt *client) lock(containerID string) {
20
-	clnt.Lock()
21
-	if _, ok := clnt.containerMutexes[containerID]; !ok {
22
-		clnt.containerMutexes[containerID] = &sync.Mutex{}
23
-	}
24
-	clnt.Unlock()
25
-	clnt.containerMutexes[containerID].Lock()
19
+	clnt.locker.Lock(containerID)
26 20
 }
27 21
 
28 22
 func (clnt *client) unlock(containerID string) {
29
-	clnt.Lock()
30
-	if l, ok := clnt.containerMutexes[containerID]; ok {
31
-		l.Unlock()
32
-	} else {
33
-		logrus.Warnf("unlock of non-existing mutex: %s", containerID)
34
-	}
35
-	clnt.Unlock()
23
+	clnt.locker.Unlock(containerID)
36 24
 }
37 25
 
38 26
 // must hold a lock for cont.containerID
... ...
@@ -16,6 +16,7 @@ import (
16 16
 
17 17
 	"github.com/Sirupsen/logrus"
18 18
 	containerd "github.com/docker/containerd/api/grpc/types"
19
+	"github.com/docker/docker/pkg/locker"
19 20
 	sysinfo "github.com/docker/docker/pkg/system"
20 21
 	"github.com/docker/docker/utils"
21 22
 	"golang.org/x/net/context"
... ...
@@ -169,9 +170,9 @@ func (r *remote) Cleanup() {
169 169
 func (r *remote) Client(b Backend) (Client, error) {
170 170
 	c := &client{
171 171
 		clientCommon: clientCommon{
172
-			backend:          b,
173
-			containerMutexes: make(map[string]*sync.Mutex),
174
-			containers:       make(map[string]*container),
172
+			backend:    b,
173
+			containers: make(map[string]*container),
174
+			locker:     locker.New(),
175 175
 		},
176 176
 		remote:        r,
177 177
 		exitNotifiers: make(map[string]*exitNotifier),
... ...
@@ -1,6 +1,6 @@
1 1
 package libcontainerd
2 2
 
3
-import "sync"
3
+import "github.com/docker/docker/pkg/locker"
4 4
 
5 5
 type remote struct {
6 6
 }
... ...
@@ -8,9 +8,9 @@ type remote struct {
8 8
 func (r *remote) Client(b Backend) (Client, error) {
9 9
 	c := &client{
10 10
 		clientCommon: clientCommon{
11
-			backend:          b,
12
-			containerMutexes: make(map[string]*sync.Mutex),
13
-			containers:       make(map[string]*container),
11
+			backend:    b,
12
+			containers: make(map[string]*container),
13
+			locker:     locker.New(),
14 14
 		},
15 15
 	}
16 16
 	return c, nil