• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lightningnetwork / lnd / 15205630088

23 May 2025 08:14AM UTC coverage: 57.45% (-11.5%) from 68.996%
15205630088

Pull #9784

github

web-flow
Merge f8b9f36a3 into c52a6ddeb
Pull Request #9784: [wip] lnwallet+walletrpc: add SubmitPackage and related RPC call

47 of 96 new or added lines in 5 files covered. (48.96%)

30087 existing lines in 459 files now uncovered.

95586 of 166380 relevant lines covered (57.45%)

0.61 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.11
/multimutex/multimutex.go
1
package multimutex
2

3
import (
4
        "fmt"
5
        "sync"
6
)
7

8
// cntMutex is a struct that wraps a counter and a mutex, and is used to keep
9
// track of the number of goroutines waiting for access to the
10
// mutex, such that we can forget about it when the counter is zero.
11
type cntMutex struct {
12
        cnt int
13
        sync.Mutex
14
}
15

16
// Mutex is a struct that keeps track of a set of mutexes with a given ID. It
17
// can be used for making sure only one goroutine gets given the mutex per ID.
18
type Mutex[T comparable] struct {
19
        // mutexes is a map of IDs to a cntMutex. The cntMutex for a given ID
20
        // will hold the mutex to be used by all callers requesting access for
21
        // the ID, in addition to the count of callers.
22
        mutexes map[T]*cntMutex
23

24
        // mapMtx is used to give synchronize concurrent access to the mutexes
25
        // map.
26
        mapMtx sync.Mutex
27
}
28

29
// NewMutex creates a new Mutex.
30
func NewMutex[T comparable]() *Mutex[T] {
1✔
31
        return &Mutex[T]{
1✔
32
                mutexes: make(map[T]*cntMutex),
1✔
33
        }
1✔
34
}
1✔
35

36
// Lock locks the mutex by the given ID. If the mutex is already locked by this
37
// ID, Lock blocks until the mutex is available.
38
func (c *Mutex[T]) Lock(id T) {
1✔
39
        c.mapMtx.Lock()
1✔
40
        mtx, ok := c.mutexes[id]
1✔
41
        if ok {
2✔
42
                // If the mutex already existed in the map, we increment its
1✔
43
                // counter, to indicate that there now is one more goroutine
1✔
44
                // waiting for it.
1✔
45
                mtx.cnt++
1✔
46
        } else {
2✔
47
                // If it was not in the map, it means no other goroutine has
1✔
48
                // locked the mutex for this ID, and we can create a new mutex
1✔
49
                // with count 1 and add it to the map.
1✔
50
                mtx = &cntMutex{
1✔
51
                        cnt: 1,
1✔
52
                }
1✔
53
                c.mutexes[id] = mtx
1✔
54
        }
1✔
55
        c.mapMtx.Unlock()
1✔
56

1✔
57
        // Acquire the mutex for this ID.
1✔
58
        mtx.Lock()
1✔
59
}
60

61
// Unlock unlocks the mutex by the given ID. It is a run-time error if the
62
// mutex is not locked by the ID on entry to Unlock.
63
func (c *Mutex[T]) Unlock(id T) {
1✔
64
        // Since we are done with all the work for this update, we update the
1✔
65
        // map to reflect that.
1✔
66
        c.mapMtx.Lock()
1✔
67

1✔
68
        mtx, ok := c.mutexes[id]
1✔
69
        if !ok {
1✔
UNCOV
70
                // The mutex not existing in the map means an unlock for an ID
×
UNCOV
71
                // not currently locked was attempted.
×
UNCOV
72
                panic(fmt.Sprintf("double unlock for id %v",
×
UNCOV
73
                        id))
×
74
        }
75

76
        // Decrement the counter. If the count goes to zero, it means this
77
        // caller was the last one to wait for the mutex, and we can delete it
78
        // from the map. We can do this safely since we are under the mapMtx,
79
        // meaning that all other goroutines waiting for the mutex already have
80
        // incremented it, or will create a new mutex when they get the mapMtx.
81
        mtx.cnt--
1✔
82
        if mtx.cnt == 0 {
2✔
83
                delete(c.mutexes, id)
1✔
84
        }
1✔
85
        c.mapMtx.Unlock()
1✔
86

1✔
87
        // Unlock the mutex for this ID.
1✔
88
        mtx.Unlock()
1✔
89
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc