Documentation ¶
Overview ¶
Package fslock is a cross-platform filesystem locking implementation.
fslock aims to implement workable filesystem-based locking semantics. Each implementation offers its own nuances, and not all of those nuances are addressed by this package.
Locks can either be exclusive (default) or shared. For a given file, exactly one of the following circumstances may be true at a given moment:
- No locks are held.
- A single exclusive lock may be held.
- Multiple shared locks may be held.
Notably, an exclusive lock may not be held on a file that has shared locks, and a shared lock may not be held on a file that has an exclusive lock.
fslock will work as long as you don't do anything particularly weird, such as:
- Manually forking your Go process.
- Circumventing the fslock package and opening and/or manipulating the lock file directly.
An attempt to take a filesystem lock is non-blocking, and will return ErrLockHeld if the lock is already held elsewhere.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrLockHeld = errors.New("fslock: lock is held")
ErrLockHeld is a sentinel error returned when the lock could not be acquired.
Functions ¶
func With ¶
With is a convenience function to create a lock, execute a function while holding that lock, and then release the lock on completion.
See L's With method for details.
func WithBlocking ¶
WithBlocking is a convenience function to create a lock, execute a function while holding that lock, and then release the lock on completion. The supplied block function is used to retry (see L's Block field).
See L's With method for details.
func WithShared ¶
WithShared is a convenience function to create a lock, execute a function while holding that lock, and then release the lock on completion.
See L's With method for details.
func WithSharedBlocking ¶
WithSharedBlocking is a convenience function to create a lock, execute a function while holding that lock, and then release the lock on completion. The supplied block function is used to retry (see L's Block field).
See L's With method for details.
Types ¶
type Handle ¶
type Handle interface { // Unlock releases the held lock. // // This can error if the underlying filesystem operations fail. This should // not happen unless something has gone externally wrong, or the lock was // mishandled. Unlock() error // LockFile returns the underlying lock File. This is not generally useful, // and should be used circumstantially. Operating on the file occurs outside // of the scope of this package, and can result in unintended consequences. // // The file should NOT be directly closed or modified. // // The file will be valid for the duration of the Handle. Once the Handle is // closed with Unlock, the file's state is implementation-specific and // unspecified. LockFile() *os.File // PreserveExec preserves the lock across execve syscall. // // The lock will be held even after call execve. It is not possible to // acquire a handle for the lock unless manually passing the fd as an // argument. // // On Windows, the behaviour is not promised unless CreateProcess with // bInheritHandles. PreserveExec() error }
Handle is a reference to a held lock. It must be released via Unlock when finished. Multiple calls to Unlock will panic.
Handle is NOT safe for concurrent use.
func Lock ¶
Lock acquires a filesystem lock for the given path.
If the lock could not be acquired because it is held by another entity, ErrLockHeld will be returned. If an error is encountered while locking, that error will be returned.
Lock is a convenience method for L's Lock.
func LockBlocking ¶
LockBlocking acquires an exclusive filesystem lock for the given path. If the lock is already held, LockBlocking will repeatedly attempt to acquire it using the supplied Blocker in between attempts.
If no Blocker is provided and the lock could not be acquired because it is held by another entity, ErrLockHeld will be returned. If an error is encountered while locking, or an error is returned by b, that error will be returned.
LockBlocking is a convenience method for L's Lock.
func LockShared ¶
Lock acquires a filesystem lock for the given path.
If the lock could not be acquired because it is held by another entity, ErrLockHeld will be returned. If an error is encountered while locking, that error will be returned.
Lock is a convenience method for L's Lock.
func LockSharedBlocking ¶
LockSharedBlocking acquires a shared filesystem lock for the given path. If the lock is already held, LockSharedBlocking will repeatedly attempt to acquire it using the supplied Blocker in between attempts.
If no Blocker is provided and the lock could not be acquired because it is held by another entity, ErrLockHeld will be returned. If an error is encountered while locking, or an error is returned by b, that error will be returned.
LockSharedBlocking is a convenience method for L's Lock.
type L ¶
type L struct { // Path is the path of the file to lock. Path string // an exclusive lock. // // See package documentation for details. Shared bool // Content, if populated, is the lock file content. Content is written to the // file when the lock call creates it, and only if the lock call actually // creates the file. Failure to write Content is non-fatal. // // Content should be used only as a convenience hint for users who want to // know what the lock file is, and not for actual programmatic management. // Several code paths can result in successful file locking and still fail to // write Content to that file. // // Content is not synchronized with the actual locking. Failure to write // Content to the lock file is considered non-fatal. Content []byte // Block is the configured blocking function. // // If not nil, an attempt to acquire the lock will loop indefinitely until an // error other than ErrLockHeld is encountered (fatal) or the lock is // acquired. Block will be called each time a lock attempt returns // ErrLockHeld, and should delay and/or cancel the acquisition by returning // nil or an error code respectively. // // If Block returns an error, it will be propagated as the error result of the // locking attempt. Block Blocker }
L describes a filesystem lock.
L's fields should not be modified concurrently, but L's methods are safe for concurrent use.