mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
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.
This commit is contained in:
parent
a65f525aed
commit
cbdd3a279e
@ -16,8 +16,10 @@ limitations under the License.
|
|||||||
|
|
||||||
package promise
|
package promise
|
||||||
|
|
||||||
// This file defines interfaces for promsies and futures and related
|
// This file defines interfaces for promises and futures and related
|
||||||
// things.
|
// things. These are about coordination among multiple goroutines and
|
||||||
|
// so are safe for concurrent calls --- although moderated in some
|
||||||
|
// cases by a requirement that the caller hold a certain lock.
|
||||||
|
|
||||||
// Readable represents a variable that is initially not set and later
|
// Readable represents a variable that is initially not set and later
|
||||||
// becomes set. Some instances may be set to multiple values in
|
// becomes set. Some instances may be set to multiple values in
|
||||||
@ -39,10 +41,16 @@ type Readable interface {
|
|||||||
type LockingReadable interface {
|
type LockingReadable interface {
|
||||||
Readable
|
Readable
|
||||||
|
|
||||||
// GetLocked is like Get but the caller must already hold the lock
|
// GetLocked is like Get but the caller must already hold the
|
||||||
|
// lock. GetLocked may release, and later re-acquire, the lock
|
||||||
|
// any number of times. Get may acquire, and later release, the
|
||||||
|
// lock any number of times.
|
||||||
GetLocked() interface{}
|
GetLocked() interface{}
|
||||||
|
|
||||||
// IsSetLocked is like IsSet but the caller must already hold the lock
|
// IsSetLocked is like IsSet but the caller must already hold the
|
||||||
|
// lock. IsSetLocked may release, and later re-acquire, the lock
|
||||||
|
// any number of times. IsSet may acquire, and later release, the
|
||||||
|
// lock any number of times.
|
||||||
IsSetLocked() bool
|
IsSetLocked() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +60,8 @@ type WriteOnceOnly interface {
|
|||||||
// Set normally writes a value into this variable, unblocks every
|
// Set normally writes a value into this variable, unblocks every
|
||||||
// goroutine waiting for this variable to have a value, and
|
// goroutine waiting for this variable to have a value, and
|
||||||
// returns true. In the unhappy case that this variable is
|
// returns true. In the unhappy case that this variable is
|
||||||
// already set, this method returns false.
|
// already set, this method returns false without modifying the
|
||||||
|
// variable's value.
|
||||||
Set(interface{}) bool
|
Set(interface{}) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,14 +73,23 @@ type WriteOnce interface {
|
|||||||
WriteOnceOnly
|
WriteOnceOnly
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LockingWriteOnceOnly is a WriteOnceOnly whose implementation is
|
||||||
|
// protected by a lock.
|
||||||
|
type LockingWriteOnceOnly interface {
|
||||||
|
WriteOnceOnly
|
||||||
|
|
||||||
|
// SetLocked is like Set but the caller must already hold the
|
||||||
|
// lock. SetLocked may release, and later re-acquire, the lock
|
||||||
|
// any number of times. Set may acquire, and later release, the
|
||||||
|
// lock any number of times
|
||||||
|
SetLocked(interface{}) bool
|
||||||
|
}
|
||||||
|
|
||||||
// LockingWriteOnce is a WriteOnce whose implementation is protected
|
// LockingWriteOnce is a WriteOnce whose implementation is protected
|
||||||
// by a lock.
|
// by a lock.
|
||||||
type LockingWriteOnce interface {
|
type LockingWriteOnce interface {
|
||||||
LockingReadable
|
LockingReadable
|
||||||
WriteOnceOnly
|
LockingWriteOnceOnly
|
||||||
|
|
||||||
// SetLocked is like Set but the caller must already hold the lock
|
|
||||||
SetLocked(interface{}) bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteMultipleOnly represents a variable that is initially not set
|
// WriteMultipleOnly represents a variable that is initially not set
|
||||||
@ -91,12 +109,21 @@ type WriteMultiple interface {
|
|||||||
WriteMultipleOnly
|
WriteMultipleOnly
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LockingWriteMultipleOnly is a WriteMultipleOnly whose
|
||||||
|
// implementation is protected by a lock.
|
||||||
|
type LockingWriteMultipleOnly interface {
|
||||||
|
WriteMultipleOnly
|
||||||
|
|
||||||
|
// SetLocked is like Set but the caller must already hold the
|
||||||
|
// lock. SetLocked may release, and later re-acquire, the lock
|
||||||
|
// any number of times. Set may acquire, and later release, the
|
||||||
|
// lock any number of times
|
||||||
|
SetLocked(interface{})
|
||||||
|
}
|
||||||
|
|
||||||
// LockingWriteMultiple is a WriteMultiple whose implementation is
|
// LockingWriteMultiple is a WriteMultiple whose implementation is
|
||||||
// protected by a lock.
|
// protected by a lock.
|
||||||
type LockingWriteMultiple interface {
|
type LockingWriteMultiple interface {
|
||||||
LockingReadable
|
LockingReadable
|
||||||
WriteMultipleOnly
|
LockingWriteMultipleOnly
|
||||||
|
|
||||||
// SetLocked is like Set but the caller must already hold the lock
|
|
||||||
SetLocked(interface{})
|
|
||||||
}
|
}
|
||||||
|
@ -23,12 +23,12 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise"
|
"k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise"
|
||||||
)
|
)
|
||||||
|
|
||||||
// promisoid is the data and reading behavior common to all the
|
// promisoid is the data and behavior common to all the promise-like
|
||||||
// promise-like abstractions implemented here. This implementation is
|
// abstractions implemented here. This implementation is based on a
|
||||||
// based on a condition variable. This implementation tracks active
|
// condition variable. This implementation tracks active goroutines:
|
||||||
// goroutines: the given counter is decremented for a goroutine
|
// the given counter is decremented for a goroutine waiting for this
|
||||||
// waiting for this varible to be set and incremented when such a
|
// varible to be set and incremented when such a goroutine is
|
||||||
// goroutine is unblocked.
|
// unblocked.
|
||||||
type promisoid struct {
|
type promisoid struct {
|
||||||
lock sync.Locker
|
lock sync.Locker
|
||||||
cond sync.Cond
|
cond sync.Cond
|
||||||
@ -63,6 +63,16 @@ func (pr *promisoid) IsSetLocked() bool {
|
|||||||
return pr.isSet
|
return pr.isSet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pr *promisoid) SetLocked(value interface{}) {
|
||||||
|
pr.isSet = true
|
||||||
|
pr.value = value
|
||||||
|
if pr.waitingCount > 0 {
|
||||||
|
pr.activeCounter.Add(pr.waitingCount)
|
||||||
|
pr.waitingCount = 0
|
||||||
|
pr.cond.Broadcast()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type writeOnce struct {
|
type writeOnce struct {
|
||||||
promisoid
|
promisoid
|
||||||
}
|
}
|
||||||
@ -88,13 +98,7 @@ func (wr *writeOnce) SetLocked(value interface{}) bool {
|
|||||||
if wr.isSet {
|
if wr.isSet {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
wr.isSet = true
|
wr.promisoid.SetLocked(value)
|
||||||
wr.value = value
|
|
||||||
if wr.waitingCount > 0 {
|
|
||||||
wr.activeCounter.Add(wr.waitingCount)
|
|
||||||
wr.waitingCount = 0
|
|
||||||
wr.cond.Broadcast()
|
|
||||||
}
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,13 +122,3 @@ func (wr *writeMultiple) Set(value interface{}) {
|
|||||||
defer wr.lock.Unlock()
|
defer wr.lock.Unlock()
|
||||||
wr.SetLocked(value)
|
wr.SetLocked(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wr *writeMultiple) SetLocked(value interface{}) {
|
|
||||||
wr.isSet = true
|
|
||||||
wr.value = value
|
|
||||||
if wr.waitingCount > 0 {
|
|
||||||
wr.activeCounter.Add(wr.waitingCount)
|
|
||||||
wr.waitingCount = 0
|
|
||||||
wr.cond.Broadcast()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user