summaryrefslogtreecommitdiff
path: root/libpod/lock/file_lock_manager.go
diff options
context:
space:
mode:
Diffstat (limited to 'libpod/lock/file_lock_manager.go')
-rw-r--r--libpod/lock/file_lock_manager.go110
1 files changed, 110 insertions, 0 deletions
diff --git a/libpod/lock/file_lock_manager.go b/libpod/lock/file_lock_manager.go
new file mode 100644
index 000000000..8a4d939d3
--- /dev/null
+++ b/libpod/lock/file_lock_manager.go
@@ -0,0 +1,110 @@
+package lock
+
+import (
+ "github.com/containers/libpod/libpod/lock/file"
+)
+
+// FileLockManager manages shared memory locks.
+type FileLockManager struct {
+ locks *file.FileLocks
+}
+
+// NewFileLockManager makes a new FileLockManager at the specified directory.
+func NewFileLockManager(lockPath string) (Manager, error) {
+ locks, err := file.CreateFileLock(lockPath)
+ if err != nil {
+ return nil, err
+ }
+
+ manager := new(FileLockManager)
+ manager.locks = locks
+
+ return manager, nil
+}
+
+// OpenFileLockManager opens an existing FileLockManager at the specified directory.
+func OpenFileLockManager(path string) (Manager, error) {
+ locks, err := file.OpenFileLock(path)
+ if err != nil {
+ return nil, err
+ }
+
+ manager := new(FileLockManager)
+ manager.locks = locks
+
+ return manager, nil
+}
+
+// AllocateLock allocates a new lock from the manager.
+func (m *FileLockManager) AllocateLock() (Locker, error) {
+ semIndex, err := m.locks.AllocateLock()
+ if err != nil {
+ return nil, err
+ }
+
+ lock := new(FileLock)
+ lock.lockID = semIndex
+ lock.manager = m
+
+ return lock, nil
+}
+
+// AllocateAndRetrieveLock allocates the lock with the given ID and returns it.
+// If the lock is already allocated, error.
+func (m *FileLockManager) AllocateAndRetrieveLock(id uint32) (Locker, error) {
+ lock := new(FileLock)
+ lock.lockID = id
+ lock.manager = m
+
+ if err := m.locks.AllocateGivenLock(id); err != nil {
+ return nil, err
+ }
+
+ return lock, nil
+}
+
+// RetrieveLock retrieves a lock from the manager given its ID.
+func (m *FileLockManager) RetrieveLock(id uint32) (Locker, error) {
+ lock := new(FileLock)
+ lock.lockID = id
+ lock.manager = m
+
+ return lock, nil
+}
+
+// FreeAllLocks frees all locks in the manager.
+// This function is DANGEROUS. Please read the full comment in locks.go before
+// trying to use it.
+func (m *FileLockManager) FreeAllLocks() error {
+ return m.locks.DeallocateAllLocks()
+}
+
+// FileLock is an individual shared memory lock.
+type FileLock struct {
+ lockID uint32
+ manager *FileLockManager
+}
+
+// ID returns the ID of the lock.
+func (l *FileLock) ID() uint32 {
+ return l.lockID
+}
+
+// Lock acquires the lock.
+func (l *FileLock) Lock() {
+ if err := l.manager.locks.LockFileLock(l.lockID); err != nil {
+ panic(err.Error())
+ }
+}
+
+// Unlock releases the lock.
+func (l *FileLock) Unlock() {
+ if err := l.manager.locks.UnlockFileLock(l.lockID); err != nil {
+ panic(err.Error())
+ }
+}
+
+// Free releases the lock, allowing it to be reused.
+func (l *FileLock) Free() error {
+ return l.manager.locks.DeallocateLock(l.lockID)
+}