@@ -4,79 +4,26 @@ package locks
44
55import (
66 "context"
7- "sync"
8- "sync/atomic"
97
10- . "github.com/netapp/trident/logging"
8+ "github.com/netapp/trident/logging"
119)
1210
13- // sync.Map is like a Go map[interface{}]interface{} but is safe for concurrent use by multiple
14- // goroutines without additional locking or coordination.
15- var sharedLocks , waitQueue sync.Map
11+ // sharedLocks provides garbage-collected named locks for package-level Lock/Unlock.
12+ var sharedLocks = NewGCNamedMutex ()
1613
17- // getLock returns a mutex with the specified ID. If the lock does not exist, one is created.
18- // This method uses sync.Map primitive (concurrency safe map) to defend against race conditions where multiple
19- // callers try to get a lock at the same time.
20- func getLock (ctx context.Context , lockID string ) * sync.Mutex {
21- newLock := & sync.Mutex {}
22- storedLock , loaded := sharedLocks .LoadOrStore (lockID , newLock )
23- if ! loaded {
24- Logc (ctx ).WithField ("lock" , lockID ).Debug ("Created shared lock." )
25- }
26- return storedLock .(* sync.Mutex )
27- }
28-
29- // Lock acquires a mutex with the specified ID. The mutex does not need to exist before
30- // calling this method. The semantics of this method are intentionally identical to sync.Mutex.Lock().
14+ // Lock acquires a mutex with the specified ID. The mutex does not need to exist
15+ // before calling this method. Semantics match sync.Mutex.Lock().
16+ //
17+ // ctx is used for logging only; acquisition is not cancelled when ctx is done.
3118func Lock (ctx context.Context , lockContext , lockID string ) {
32- IncrementQueueSize (lockID )
33- Logc (ctx ).WithField ("lockContext" , lockContext ).Debugf ("Attempting to acquire shared lock (%s); %d position in the queue." ,
34- lockID , WaitQueueSize (lockID ))
35-
36- getLock (ctx , lockID ).Lock ()
37-
38- DecrementQueueSize (lockID )
39- Logc (ctx ).WithField ("lockContext" , lockContext ).Debugf ("Acquired shared lock (%s)." , lockID )
19+ logging .Logc (ctx ).WithField ("lockContext" , lockContext ).Debugf (
20+ "Attempting to acquire shared lock (%s)." , lockID )
21+ sharedLocks .Lock (lockID )
22+ logging .Logc (ctx ).WithField ("lockContext" , lockContext ).Debugf ("Acquired shared lock (%s)." , lockID )
4023}
4124
42- // Unlock releases a mutex with the specified ID. The semantics of this method are intentionally
43- // identical to sync.Mutex.Unlock().
25+ // Unlock releases a mutex with the specified ID. Semantics match sync.Mutex.Unlock().
4426func Unlock (ctx context.Context , lockContext , lockID string ) {
45- getLock (ctx , lockID ).Unlock ()
46- Logc (ctx ).WithField ("lockContext" , lockContext ).Debugf ("Released shared lock (%s)." , lockID )
47- }
48-
49- // IncrementQueueSize increments the wait queue size by 1
50- func IncrementQueueSize (lockID string ) {
51- currentWait , ok := waitQueue .Load (lockID )
52- if ! ok {
53- valPtr := new (uint32 (1 ))
54- waitQueue .Store (lockID , valPtr )
55- } else {
56- if ptr , ok := currentWait .(* uint32 ); ok {
57- atomic .AddUint32 (ptr , 1 )
58- }
59- }
60- }
61-
62- // DecrementQueueSize decrements the wait queue size by 1
63- func DecrementQueueSize (lockID string ) {
64- currentWait , ok := waitQueue .Load (lockID )
65- if ok {
66- if ptr , ok := currentWait .(* uint32 ); ok {
67- if atomic .LoadUint32 (ptr ) > 0 {
68- atomic .AddUint32 (ptr , ^ uint32 (0 ))
69- }
70- }
71- }
72- }
73-
74- // WaitQueueSize returns the wait queue size
75- func WaitQueueSize (lockID string ) uint32 {
76- currentWait , ok := waitQueue .Load (lockID )
77- if ! ok {
78- return 0
79- }
80-
81- return atomic .LoadUint32 (currentWait .(* uint32 ))
27+ sharedLocks .Unlock (lockID )
28+ logging .Logc (ctx ).WithField ("lockContext" , lockContext ).Debugf ("Released shared lock (%s)." , lockID )
8229}
0 commit comments