| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354 |
- //go:build !windows
- package core
- // Unix (Linux / macOS 等) 跨进程文件锁: 用 flock 对整个文件加排他锁。
- // 纯标准库 syscall。flock 锁关联打开的文件描述符, 不同进程 (或同进程不同
- // open 得到的 fd) 对同一文件加 LOCK_EX 互斥; 进程退出 / fd 关闭自动释放。
- import (
- "syscall"
- )
- // tryLock 非阻塞 (LOCK_NB) 地加排他锁 (LOCK_EX); 文件已被锁定时返回
- // ErrDatabaseLocked (flock 冲突 errno = EWOULDBLOCK)。
- func (ff *File) tryLock() error {
- if ff.fileLocked {
- return nil
- }
- err := syscall.Flock(int(ff.f.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
- if err != nil {
- if err == syscall.EWOULDBLOCK {
- return ErrDatabaseLocked
- }
- return err
- }
- ff.fileLocked = true
- return nil
- }
- // tryRLock 非阻塞 (LOCK_NB) 地加共享锁 (LOCK_SH, 只读打开): 共享锁之间可共存,
- // 与排他锁 (LOCK_EX) 互斥; 冲突 errno EWOULDBLOCK → ErrDatabaseLocked。
- func (ff *File) tryRLock() error {
- if ff.fileLocked {
- return nil
- }
- err := syscall.Flock(int(ff.f.Fd()), syscall.LOCK_SH|syscall.LOCK_NB)
- if err != nil {
- if err == syscall.EWOULDBLOCK {
- return ErrDatabaseLocked
- }
- return err
- }
- ff.fileLocked = true
- return nil
- }
- // unlock 释放文件锁 (Close 路径调用; 错误忽略 —— 句柄关闭同样会释放)。
- func (ff *File) unlock() {
- if !ff.fileLocked {
- return
- }
- _ = syscall.Flock(int(ff.f.Fd()), syscall.LOCK_UN)
- ff.fileLocked = false
- }
|