mirror of
https://git.sr.ht/~sircmpwn/tokidoki
synced 2025-12-12 06:07:22 +01:00
storage/filesystem: add R/W locking
This commit adds read/write locking for individual files, so that concurrent requests (e.g. to read and write the same file) cannot interfere with one another. The locking is not very fine-grained at the moment, and can probably be improved upon. But it does ensure consistency.
This commit is contained in:
parent
7969df1a38
commit
6eeea854be
3 changed files with 88 additions and 2 deletions
|
|
@ -10,6 +10,7 @@ import (
|
|||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
|
|
@ -20,9 +21,13 @@ import (
|
|||
|
||||
type filesystemBackend struct {
|
||||
webdav.UserPrincipalBackend
|
||||
|
||||
path string
|
||||
caldavPrefix string
|
||||
carddavPrefix string
|
||||
|
||||
// maps file path to *sync.RWMutex
|
||||
locks sync.Map
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
@ -47,6 +52,36 @@ func NewFilesystem(fsPath, caldavPrefix, carddavPrefix string, userPrincipalBack
|
|||
return backend, backend, nil
|
||||
}
|
||||
|
||||
func (b *filesystemBackend) RLock(filename string) {
|
||||
lock_, _ := b.locks.LoadOrStore(filename, &sync.RWMutex{})
|
||||
lock := lock_.(*sync.RWMutex)
|
||||
lock.RLock()
|
||||
}
|
||||
|
||||
func (b *filesystemBackend) RUnlock(filename string) {
|
||||
lock_, ok := b.locks.Load(filename)
|
||||
if !ok {
|
||||
panic("attempt to unlock non-existing lock")
|
||||
}
|
||||
lock := lock_.(*sync.RWMutex)
|
||||
lock.RUnlock()
|
||||
}
|
||||
|
||||
func (b *filesystemBackend) Lock(filename string) {
|
||||
lock_, _ := b.locks.LoadOrStore(filename, &sync.RWMutex{})
|
||||
lock := lock_.(*sync.RWMutex)
|
||||
lock.Lock()
|
||||
}
|
||||
|
||||
func (b *filesystemBackend) Unlock(filename string) {
|
||||
lock_, ok := b.locks.Load(filename)
|
||||
if !ok {
|
||||
panic("attempt to unlock non-existing lock")
|
||||
}
|
||||
lock := lock_.(*sync.RWMutex)
|
||||
lock.Unlock()
|
||||
}
|
||||
|
||||
func ensureLocalDir(path string) error {
|
||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||
err = os.MkdirAll(path, 0755)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue