github.com/AbhinandanKurakure/podman/v3@v3.4.10/libpod/lock/file_lock_manager.go (about)

     1  package lock
     2  
     3  import (
     4  	"github.com/containers/podman/v3/libpod/lock/file"
     5  )
     6  
     7  // FileLockManager manages shared memory locks.
     8  type FileLockManager struct {
     9  	locks *file.FileLocks
    10  }
    11  
    12  // NewFileLockManager makes a new FileLockManager at the specified directory.
    13  func NewFileLockManager(lockPath string) (Manager, error) {
    14  	locks, err := file.CreateFileLock(lockPath)
    15  	if err != nil {
    16  		return nil, err
    17  	}
    18  
    19  	manager := new(FileLockManager)
    20  	manager.locks = locks
    21  
    22  	return manager, nil
    23  }
    24  
    25  // OpenFileLockManager opens an existing FileLockManager at the specified directory.
    26  func OpenFileLockManager(path string) (Manager, error) {
    27  	locks, err := file.OpenFileLock(path)
    28  	if err != nil {
    29  		return nil, err
    30  	}
    31  
    32  	manager := new(FileLockManager)
    33  	manager.locks = locks
    34  
    35  	return manager, nil
    36  }
    37  
    38  // AllocateLock allocates a new lock from the manager.
    39  func (m *FileLockManager) AllocateLock() (Locker, error) {
    40  	semIndex, err := m.locks.AllocateLock()
    41  	if err != nil {
    42  		return nil, err
    43  	}
    44  
    45  	lock := new(FileLock)
    46  	lock.lockID = semIndex
    47  	lock.manager = m
    48  
    49  	return lock, nil
    50  }
    51  
    52  // AllocateAndRetrieveLock allocates the lock with the given ID and returns it.
    53  // If the lock is already allocated, error.
    54  func (m *FileLockManager) AllocateAndRetrieveLock(id uint32) (Locker, error) {
    55  	lock := new(FileLock)
    56  	lock.lockID = id
    57  	lock.manager = m
    58  
    59  	if err := m.locks.AllocateGivenLock(id); err != nil {
    60  		return nil, err
    61  	}
    62  
    63  	return lock, nil
    64  }
    65  
    66  // RetrieveLock retrieves a lock from the manager given its ID.
    67  func (m *FileLockManager) RetrieveLock(id uint32) (Locker, error) {
    68  	lock := new(FileLock)
    69  	lock.lockID = id
    70  	lock.manager = m
    71  
    72  	return lock, nil
    73  }
    74  
    75  // FreeAllLocks frees all locks in the manager.
    76  // This function is DANGEROUS. Please read the full comment in locks.go before
    77  // trying to use it.
    78  func (m *FileLockManager) FreeAllLocks() error {
    79  	return m.locks.DeallocateAllLocks()
    80  }
    81  
    82  // FileLock is an individual shared memory lock.
    83  type FileLock struct {
    84  	lockID  uint32
    85  	manager *FileLockManager
    86  }
    87  
    88  // ID returns the ID of the lock.
    89  func (l *FileLock) ID() uint32 {
    90  	return l.lockID
    91  }
    92  
    93  // Lock acquires the lock.
    94  func (l *FileLock) Lock() {
    95  	if err := l.manager.locks.LockFileLock(l.lockID); err != nil {
    96  		panic(err.Error())
    97  	}
    98  }
    99  
   100  // Unlock releases the lock.
   101  func (l *FileLock) Unlock() {
   102  	if err := l.manager.locks.UnlockFileLock(l.lockID); err != nil {
   103  		panic(err.Error())
   104  	}
   105  }
   106  
   107  // Free releases the lock, allowing it to be reused.
   108  func (l *FileLock) Free() error {
   109  	return l.manager.locks.DeallocateLock(l.lockID)
   110  }