lockfile

package module
v0.0.0-...-a66de41 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 18, 2014 License: MIT Imports: 4 Imported by: 0

README

lockfile

Lockfile provides a simple wrapper for fcntl and flock based advisory file locking.

Installation

go get github.com/rubyist/lockfile

Examples

lockfile provides a function NewLockfile() which will use an fcntl based lock, if it is available on the system. fcntl based locks are available in Go 1.3 and later. If fcntl is not available it will fall back to an flock based lock.

lock := lockfile.NewLockfile("myfile")

A fcntl based lock can be built explicitly:

lock := lockfile.NewFcntlLockfile("myfile")

A flock based lock can be built explicitly:

lock := lockfile.NewFLockfile("myfile")

An os.File can also be used.

file, _ := os.Open("myfile")
lock := lockfile.NewLockfileFromFile(file)
lock2 := lockfile.NewFcntlLockfileFromFile(file)
lock3 := lockfile.NewFLockfileFromFile(file)
Read Locks

The LockRead() function will lock a file for reading. When a file is locked for reading, other processes will be able to obtain read locks on the file. Write locks cannot be obtained on files locked for reading. If the lock cannot be obtained, LockRead() will return an error immediately

The LockReadB() function provides the same read locking functionality but will block until the lock can be obtained.

err := lock.LockRead()
if err != nil {
  // Lock not obtained
}

lock.LockReadB() // blocks until lock can be obtained
Write Locks

The LockWrite() function will lock a file for writing. When a file is locked for writing, other processes will not be able to obtain read or write locks on the file. If the lock cannot be obtained, LockWrite() will return an error immediately.

The LockWriteB() function provides the same write locking functionality but will block until the lock can be obtained.

err := lock.LockWrite()
if err != nil {
  // Lock not obtained
}

lock.LockWriteB() // blocks until the lock can be obtained
Releasing locks

The Unlock() function will release a lock. Closing a file or exiting the process will also release any locks held on the file.

Caveat: If the locking process opens a locked file and then closes it, all locks on that file will be released.

lock := lockfile.NewLockfile("foobar.lock")
lock.LockWrite() // lock obtained

f, _ := os.Open("foobar.lock")
f.Close() // lock released
Locking Byte Ranges

When using an fcntl based lock, byte ranges within the file can be locked and unlocked. The functions availble to do this are:

LockReadRange(offset int64, whence int, len int64) error
LockWriteRange(offset int64, whence int, len int64) error
LockReadRangeB(offset int64, whence int, len int64) error
LockWriteRangeB(offset int64, whence int, len int64) error
UnlockRange(offset int64, whence int, len int64)
  • whence: 0, 1, or 2 where:
    • 0: relative to the origin of the file
    • 1: relative to the current offset of the file
    • 2: relative to the end of the file
  • offset: The offset, in bytes, from whence
  • len: The number of bytes to lock

Bugs and Issues

Issues and pull requests on GitHub

Documentation

Overview

Package lockfile provides a simple wrapper around a system's file locking capabilities. It provides wrappers around both flock and fcntl type locks. Fcntl based locks are only available with go 1.3 or later.

Both flock and fcntl based locks can be explicitly created. lockfile also provides a generic creator which will use fcntl if it is available, otherwise it will provide a flock based lock.

Here is an example using the generic creator to lock a file for writing.

lock := NewLockfile("myfile.lock")
err := lock.LockWrite()
if err != nil {
        log.Fatal(err)
}
lock.Unlock()

Here is an example of creating an flock based lock file.

lock := NewFLockfile("myfile.lock")
err := lock.LockWrite()
if err != nil {
        log.Fatal(err)
}
lock.Unlock()

Here is an example of creating a fcntl based lock file. This function is only available if the system supports it and Go is version 1.3 or greater.

lock := NewFcntlLockfile("myfile.lock")
err := lock.LockWrite()
if err != nil {
        log.Fatal(err)
}
lock.Unlock()

Both functions return a lock that conforms to the Locker interface.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrFailedToLock = errors.New("failed to obtain lock")
)

Functions

This section is empty.

Types

type FLockfile

type FLockfile struct {
	Path string
	// contains filtered or unexported fields
}

func NewFLockfile

func NewFLockfile(path string) *FLockfile

func NewFLockfileFromFile

func NewFLockfileFromFile(file *os.File) *FLockfile

func (*FLockfile) LockRead

func (l *FLockfile) LockRead() error

func (*FLockfile) LockReadB

func (l *FLockfile) LockReadB() error

func (*FLockfile) LockWrite

func (l *FLockfile) LockWrite() error

func (*FLockfile) LockWriteB

func (l *FLockfile) LockWriteB() error

func (*FLockfile) Unlock

func (l *FLockfile) Unlock()

type FcntlLockfile

type FcntlLockfile struct {
	Path string
	// contains filtered or unexported fields
}

func NewFcntlLockfile

func NewFcntlLockfile(path string) *FcntlLockfile

func NewFcntlLockfileFromFile

func NewFcntlLockfileFromFile(file *os.File) *FcntlLockfile

func (*FcntlLockfile) LockRead

func (l *FcntlLockfile) LockRead() error

func (*FcntlLockfile) LockReadB

func (l *FcntlLockfile) LockReadB() error

func (*FcntlLockfile) LockReadRange

func (l *FcntlLockfile) LockReadRange(offset int64, whence int, len int64) error

func (*FcntlLockfile) LockReadRangeB

func (l *FcntlLockfile) LockReadRangeB(offset int64, whence int, len int64) error

func (*FcntlLockfile) LockWrite

func (l *FcntlLockfile) LockWrite() error

func (*FcntlLockfile) LockWriteB

func (l *FcntlLockfile) LockWriteB() error

func (*FcntlLockfile) LockWriteRange

func (l *FcntlLockfile) LockWriteRange(offset int64, whence int, len int64) error

func (*FcntlLockfile) LockWriteRangeB

func (l *FcntlLockfile) LockWriteRangeB(offset int64, whence int, len int64) error

func (*FcntlLockfile) Owner

func (l *FcntlLockfile) Owner() int

Owner will return the pid of the process that owns an fcntl based lock on the file. If the file is not locked it will return -1. If a lock is owned by the current process, it will return -1.

func (*FcntlLockfile) Unlock

func (l *FcntlLockfile) Unlock()

func (*FcntlLockfile) UnlockRange

func (l *FcntlLockfile) UnlockRange(offset int64, whence int, len int64)

type Locker

type Locker interface {
	LockRead() error
	LockWrite() error
	LockReadB() error
	LockWriteB() error
	Unlock()
}

Locker is the interface that wraps file locking functionality.

LockRead locks the file for reading. When a file is locked for reading, other processes may lock the file for reading, but are unable to lock the file for writing. If LockRead cannot obtain the lock it will return an error.

LockWrite locks the file for writing. When a file is locked for writing, other processes cannot obtain read or write locks on the file. If LockWrite cannot obtain the lock it will return an error.

LockReadB is a blocking version of LockRead. If it cannot obtain the lock it will block until it is able to.

LockWriteB is a blocking version of LockWrite. If it cannot obtain the lock it will block until it is able to.

Unlock releases the lock on the file.

type RangeLocker

type RangeLocker interface {
	Locker
	LockReadRange(int64, int, int64) error
	LockWriteRange(int64, int, int64) error
	LockReadRangeB(int64, int, int64) error
	LockWriteRangeB(int64, int, int64) error
	UnlockRange(int64, int, int64)
}

func NewLockfile

func NewLockfile(path string) RangeLocker

NewLockfile creates a Locker for a file path. The underlying Locker created will be either a FLockfile or a FcntlLockfile, depending on system capabilities. If the fcntl based function is available it will use that, otherwise it will use flock.

func NewLockfileFromFile

func NewLockfileFromFile(file *os.File) RangeLocker

NewLockfile creates a Locker from an *os.File. The underlying Locker created will be either a FLockfile or a FcntlLockfile, depending on system capabilities. If the fcntl based function is available it will use that, otherwise it will use flock.

The file must be opened with the capabilities needed by the lock. e.g. if the file is open for reading only, a write lock cannot be obtained.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL