Add Lockfile.AssertLocked and AssertLockedForWriting
This will replace Lockfile.Locked for the sanity-checking purposes. It is, just like Locked never was, NOT a way for a caller to check the current state. Hence the panic() instead of an error return. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This commit is contained in:
parent
db44035e3c
commit
5791b9d6af
|
|
@ -42,6 +42,14 @@ type Locker interface {
|
||||||
|
|
||||||
// Locked() checks if lock is locked for writing by a thread in this process
|
// Locked() checks if lock is locked for writing by a thread in this process
|
||||||
Locked() bool
|
Locked() bool
|
||||||
|
|
||||||
|
// AssertLocked() can be used by callers that _know_ that they hold the lock (for reading or writing), for sanity checking.
|
||||||
|
// It might do nothing at all, or it may panic if the caller is not the owner of this lock.
|
||||||
|
AssertLocked()
|
||||||
|
|
||||||
|
// AssertLocked() can be used by callers that _know_ that they hold the lock locked for writing, for sanity checking.
|
||||||
|
// It might do nothing at all, or it may panic if the caller is not the owner of this lock for writing.
|
||||||
|
AssertLockedForWriting()
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
||||||
|
|
@ -220,6 +220,35 @@ func (l *lockfile) Locked() bool {
|
||||||
return l.locked && (l.locktype == unix.F_WRLCK)
|
return l.locked && (l.locktype == unix.F_WRLCK)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *lockfile) AssertLocked() {
|
||||||
|
// DO NOT provide a variant that returns the value of l.locked.
|
||||||
|
//
|
||||||
|
// If the caller does not hold the lock, l.locked might nevertheless be true because another goroutine does hold it, and
|
||||||
|
// we can’t tell the difference.
|
||||||
|
//
|
||||||
|
// Hence, this “AssertLocked” method, which exists only for sanity checks.
|
||||||
|
|
||||||
|
// Don’t even bother with l.stateMutex: The caller is expected to hold the lock, and in that case l.locked is constant true
|
||||||
|
// with no possible writers.
|
||||||
|
// If the caller does not hold the lock, we are violating the locking/memory model anyway, and accessing the data
|
||||||
|
// without the lock is more efficient for callers, and potentially more visible to lock analysers for incorrect callers.
|
||||||
|
if !l.locked {
|
||||||
|
panic("internal error: lock is not held by the expected owner")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *lockfile) AssertLockedForWriting() {
|
||||||
|
// DO NOT provide a variant that returns the current lock state.
|
||||||
|
//
|
||||||
|
// The same caveats as for AssertLocked apply equally.
|
||||||
|
|
||||||
|
l.AssertLocked()
|
||||||
|
// Like AssertLocked, don’t even bother with l.stateMutex.
|
||||||
|
if l.locktype != unix.F_WRLCK {
|
||||||
|
panic("internal error: lock is not held for writing")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Touch updates the lock file with the UID of the user.
|
// Touch updates the lock file with the UID of the user.
|
||||||
func (l *lockfile) Touch() error {
|
func (l *lockfile) Touch() error {
|
||||||
l.stateMutex.Lock()
|
l.stateMutex.Lock()
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,25 @@ func (l *lockfile) Locked() bool {
|
||||||
return l.locked
|
return l.locked
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *lockfile) AssertLocked() {
|
||||||
|
// DO NOT provide a variant that returns the value of l.locked.
|
||||||
|
//
|
||||||
|
// If the caller does not hold the lock, l.locked might nevertheless be true because another goroutine does hold it, and
|
||||||
|
// we can’t tell the difference.
|
||||||
|
//
|
||||||
|
// Hence, this “AssertLocked” method, which exists only for sanity checks.
|
||||||
|
if !l.locked {
|
||||||
|
panic("internal error: lock is not held by the expected owner")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *lockfile) AssertLockedForWriting() {
|
||||||
|
// DO NOT provide a variant that returns the current lock state.
|
||||||
|
//
|
||||||
|
// The same caveats as for AssertLocked apply equally.
|
||||||
|
l.AssertLocked() // The current implementation does not distinguish between read and write locks.
|
||||||
|
}
|
||||||
|
|
||||||
func (l *lockfile) Modified() (bool, error) {
|
func (l *lockfile) Modified() (bool, error) {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue