40 lines
840 B
Go
40 lines
840 B
Go
package lock
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"fmt"
|
||
|
|
"sync"
|
||
|
|
)
|
||
|
|
|
||
|
|
var (
|
||
|
|
locks = make(map[string]*sync.Mutex)
|
||
|
|
locksMu sync.Mutex
|
||
|
|
)
|
||
|
|
|
||
|
|
// Acquire acquires an advisory lock on a file.
|
||
|
|
// It creates the file if it doesn't exist, then uses a Go mutex for synchronization.
|
||
|
|
// This implementation is safe for single-process use; multi-process distributed locking
|
||
|
|
// would require OS-level file locking (fcntl/flock on Unix or LockFileEx on Windows).
|
||
|
|
func Acquire(path string) error {
|
||
|
|
locksMu.Lock()
|
||
|
|
defer locksMu.Unlock()
|
||
|
|
|
||
|
|
if locks[path] == nil {
|
||
|
|
locks[path] = &sync.Mutex{}
|
||
|
|
}
|
||
|
|
locks[path].Lock()
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// Release releases an advisory lock on a file.
|
||
|
|
func Release(path string) error {
|
||
|
|
locksMu.Lock()
|
||
|
|
defer locksMu.Unlock()
|
||
|
|
|
||
|
|
mu, exists := locks[path]
|
||
|
|
if !exists {
|
||
|
|
return fmt.Errorf("lock not acquired for path: %s", path)
|
||
|
|
}
|
||
|
|
mu.Unlock()
|
||
|
|
return nil
|
||
|
|
}
|