gofslock: github.com/danjacques/gofslock/fslock Index | Files

package fslock

import "github.com/danjacques/gofslock/fslock"

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

Package Files

interface.go lock.go lock_posix.go

Variables

var ErrLockHeld = errors.New("fslock: lock is held")

ErrLockHeld is a sentinel error returned when the lock could not be acquired.

func With Uses

func With(path string, fn func() error) error

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 Uses

func WithBlocking(path string, b Blocker, fn func() error) error

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 Uses

func WithShared(path string, fn func() error) error

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 Uses

func WithSharedBlocking(path string, b Blocker, fn func() error) error

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.

type Blocker Uses

type Blocker func() error

Blocker is used for the Delay field in a Lock.

type Handle Uses

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
}

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 Uses

func Lock(path string) (Handle, error)

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 Uses

func LockBlocking(path string, b Blocker) (Handle, error)

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 Uses

func LockShared(path string) (Handle, error)

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 Uses

func LockSharedBlocking(path string, b Blocker) (Handle, error)

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 Uses

type L struct {
    // Path is the path of the file to lock.
    Path string

    // Shared, if true, indicates that this should be a shared lock rather than
    // 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.

func (*L) Lock Uses

func (l *L) Lock() (Handle, error)

Lock attempts to acquire the configured lock.

func (*L) With Uses

func (l *L) With(fn func() error) (err error)

With is a convenience method to acquire a lock via Lock, call fn, and release the lock on completion (via defer).

If an error is encountered, it will be returned. Otherwise, the return value from fn will be returned.

Package fslock imports 6 packages (graph) and is imported by 5 packages. Updated 2019-10-30. Refresh now. Tools for package owners.