mirror of
https://github.com/TeaOSLab/EdgeNode.git
synced 2025-11-19 04:10:30 +08:00
对本地数据库文件进行加锁
This commit is contained in:
82
internal/utils/fileutils/locker.go
Normal file
82
internal/utils/fileutils/locker.go
Normal file
@@ -0,0 +1,82 @@
|
||||
// Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package fileutils
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Locker struct {
|
||||
path string
|
||||
fp *os.File
|
||||
}
|
||||
|
||||
func NewLocker(path string) *Locker {
|
||||
return &Locker{
|
||||
path: path + ".lock",
|
||||
}
|
||||
}
|
||||
|
||||
func (this *Locker) TryLock() (ok bool, err error) {
|
||||
if this.fp == nil {
|
||||
fp, err := os.OpenFile(this.path, os.O_CREATE|os.O_WRONLY, 0666)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
this.fp = fp
|
||||
}
|
||||
return this.tryLock()
|
||||
}
|
||||
|
||||
func (this *Locker) Lock() error {
|
||||
if this.fp == nil {
|
||||
fp, err := os.OpenFile(this.path, os.O_CREATE|os.O_WRONLY, 0666)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
this.fp = fp
|
||||
}
|
||||
|
||||
for {
|
||||
b, err := this.tryLock()
|
||||
if err != nil {
|
||||
_ = this.fp.Close()
|
||||
return err
|
||||
}
|
||||
if b {
|
||||
return nil
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
func (this *Locker) Release() error {
|
||||
err := this.fp.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
this.fp = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *Locker) tryLock() (ok bool, err error) {
|
||||
err = syscall.Flock(int(this.fp.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
|
||||
if err == nil {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
errno, isErrNo := err.(syscall.Errno)
|
||||
if !isErrNo {
|
||||
return
|
||||
}
|
||||
|
||||
if !errno.Temporary() {
|
||||
return
|
||||
}
|
||||
|
||||
err = nil // 不提示错误
|
||||
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user