Skip to content

Commit cbdd3a2

Browse files
committed
brushed up according to review
Added LockingWriteMultipleOnly and LockingWriteOnceOnly interfaces, so that further extensions are possible (in this package or others). Moved common SetLocked behavior into promisoid. Made comments say things that were implied.
1 parent a65f525 commit cbdd3a2

File tree

2 files changed

+57
-36
lines changed

2 files changed

+57
-36
lines changed

staging/src/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise/interface.go

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ limitations under the License.
1616

1717
package promise
1818

19-
// This file defines interfaces for promsies and futures and related
20-
// things.
19+
// This file defines interfaces for promises and futures and related
20+
// things. These are about coordination among multiple goroutines and
21+
// so are safe for concurrent calls --- although moderated in some
22+
// cases by a requirement that the caller hold a certain lock.
2123

2224
// Readable represents a variable that is initially not set and later
2325
// becomes set. Some instances may be set to multiple values in
@@ -39,10 +41,16 @@ type Readable interface {
3941
type LockingReadable interface {
4042
Readable
4143

42-
// GetLocked is like Get but the caller must already hold the lock
44+
// GetLocked is like Get but the caller must already hold the
45+
// lock. GetLocked may release, and later re-acquire, the lock
46+
// any number of times. Get may acquire, and later release, the
47+
// lock any number of times.
4348
GetLocked() interface{}
4449

45-
// IsSetLocked is like IsSet but the caller must already hold the lock
50+
// IsSetLocked is like IsSet but the caller must already hold the
51+
// lock. IsSetLocked may release, and later re-acquire, the lock
52+
// any number of times. IsSet may acquire, and later release, the
53+
// lock any number of times.
4654
IsSetLocked() bool
4755
}
4856

@@ -52,7 +60,8 @@ type WriteOnceOnly interface {
5260
// Set normally writes a value into this variable, unblocks every
5361
// goroutine waiting for this variable to have a value, and
5462
// returns true. In the unhappy case that this variable is
55-
// already set, this method returns false.
63+
// already set, this method returns false without modifying the
64+
// variable's value.
5665
Set(interface{}) bool
5766
}
5867

@@ -64,14 +73,23 @@ type WriteOnce interface {
6473
WriteOnceOnly
6574
}
6675

76+
// LockingWriteOnceOnly is a WriteOnceOnly whose implementation is
77+
// protected by a lock.
78+
type LockingWriteOnceOnly interface {
79+
WriteOnceOnly
80+
81+
// SetLocked is like Set but the caller must already hold the
82+
// lock. SetLocked may release, and later re-acquire, the lock
83+
// any number of times. Set may acquire, and later release, the
84+
// lock any number of times
85+
SetLocked(interface{}) bool
86+
}
87+
6788
// LockingWriteOnce is a WriteOnce whose implementation is protected
6889
// by a lock.
6990
type LockingWriteOnce interface {
7091
LockingReadable
71-
WriteOnceOnly
72-
73-
// SetLocked is like Set but the caller must already hold the lock
74-
SetLocked(interface{}) bool
92+
LockingWriteOnceOnly
7593
}
7694

7795
// WriteMultipleOnly represents a variable that is initially not set
@@ -91,12 +109,21 @@ type WriteMultiple interface {
91109
WriteMultipleOnly
92110
}
93111

112+
// LockingWriteMultipleOnly is a WriteMultipleOnly whose
113+
// implementation is protected by a lock.
114+
type LockingWriteMultipleOnly interface {
115+
WriteMultipleOnly
116+
117+
// SetLocked is like Set but the caller must already hold the
118+
// lock. SetLocked may release, and later re-acquire, the lock
119+
// any number of times. Set may acquire, and later release, the
120+
// lock any number of times
121+
SetLocked(interface{})
122+
}
123+
94124
// LockingWriteMultiple is a WriteMultiple whose implementation is
95125
// protected by a lock.
96126
type LockingWriteMultiple interface {
97127
LockingReadable
98-
WriteMultipleOnly
99-
100-
// SetLocked is like Set but the caller must already hold the lock
101-
SetLocked(interface{})
128+
LockingWriteMultipleOnly
102129
}

staging/src/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise/lockingpromise/lockingpromise.go

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ import (
2323
"k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise"
2424
)
2525

26-
// promisoid is the data and reading behavior common to all the
27-
// promise-like abstractions implemented here. This implementation is
28-
// based on a condition variable. This implementation tracks active
29-
// goroutines: the given counter is decremented for a goroutine
30-
// waiting for this varible to be set and incremented when such a
31-
// goroutine is unblocked.
26+
// promisoid is the data and behavior common to all the promise-like
27+
// abstractions implemented here. This implementation is based on a
28+
// condition variable. This implementation tracks active goroutines:
29+
// the given counter is decremented for a goroutine waiting for this
30+
// varible to be set and incremented when such a goroutine is
31+
// unblocked.
3232
type promisoid struct {
3333
lock sync.Locker
3434
cond sync.Cond
@@ -63,6 +63,16 @@ func (pr *promisoid) IsSetLocked() bool {
6363
return pr.isSet
6464
}
6565

66+
func (pr *promisoid) SetLocked(value interface{}) {
67+
pr.isSet = true
68+
pr.value = value
69+
if pr.waitingCount > 0 {
70+
pr.activeCounter.Add(pr.waitingCount)
71+
pr.waitingCount = 0
72+
pr.cond.Broadcast()
73+
}
74+
}
75+
6676
type writeOnce struct {
6777
promisoid
6878
}
@@ -88,13 +98,7 @@ func (wr *writeOnce) SetLocked(value interface{}) bool {
8898
if wr.isSet {
8999
return false
90100
}
91-
wr.isSet = true
92-
wr.value = value
93-
if wr.waitingCount > 0 {
94-
wr.activeCounter.Add(wr.waitingCount)
95-
wr.waitingCount = 0
96-
wr.cond.Broadcast()
97-
}
101+
wr.promisoid.SetLocked(value)
98102
return true
99103
}
100104

@@ -118,13 +122,3 @@ func (wr *writeMultiple) Set(value interface{}) {
118122
defer wr.lock.Unlock()
119123
wr.SetLocked(value)
120124
}
121-
122-
func (wr *writeMultiple) SetLocked(value interface{}) {
123-
wr.isSet = true
124-
wr.value = value
125-
if wr.waitingCount > 0 {
126-
wr.activeCounter.Add(wr.waitingCount)
127-
wr.waitingCount = 0
128-
wr.cond.Broadcast()
129-
}
130-
}

0 commit comments

Comments
 (0)