Skip to content

Commit 12bc8e7

Browse files
committed
file.Lock/Unlock added mutex to avoid problems with concurrent calls
Signed-off-by: Máximo Cuadros <[email protected]>
1 parent 3e7b6f8 commit 12bc8e7

File tree

4 files changed

+30
-16
lines changed

4 files changed

+30
-16
lines changed

memfs/memory.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,11 +297,12 @@ func (f *file) Stat() (os.FileInfo, error) {
297297
}, nil
298298
}
299299

300-
// Lock protects file from access from other processes. Which is a no-op
301-
// for this memory only filesystem.
300+
// Lock is a no-op in memfs.
302301
func (f *file) Lock() error {
303302
return nil
304303
}
304+
305+
// Unlock is a no-op in memfs.
305306
func (f *file) Unlock() error {
306307
return nil
307308
}

osfs/os.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"io/ioutil"
66
"os"
77
"path/filepath"
8+
"sync"
89

910
"gopkg.in/src-d/go-billy.v3"
1011
"gopkg.in/src-d/go-billy.v3/helper/chroot"
@@ -23,11 +24,6 @@ func New(baseDir string) billy.Filesystem {
2324
return chroot.New(&OS{}, baseDir)
2425
}
2526

26-
// file is a wrapper for an os.File which adds support for file locking.
27-
type file struct {
28-
*os.File
29-
}
30-
3127
func (fs *OS) Create(filename string) (billy.File, error) {
3228
return fs.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, defaultCreateMode)
3329
}
@@ -43,7 +39,7 @@ func (fs *OS) OpenFile(filename string, flag int, perm os.FileMode) (billy.File,
4339
if err != nil {
4440
return nil, err
4541
}
46-
return file{f}, err
42+
return &file{File: f}, err
4743
}
4844

4945
func (fs *OS) createDir(fullpath string) error {
@@ -100,7 +96,7 @@ func (fs *OS) TempFile(dir, prefix string) (billy.File, error) {
10096
if err != nil {
10197
return nil, err
10298
}
103-
return file{f}, nil
99+
return &file{File: f}, nil
104100
}
105101

106102
func (fs *OS) Join(elem ...string) string {
@@ -126,3 +122,9 @@ func (fs *OS) Symlink(target, link string) error {
126122
func (fs *OS) Readlink(link string) (string, error) {
127123
return os.Readlink(link)
128124
}
125+
126+
// file is a wrapper for an os.File which adds support for file locking.
127+
type file struct {
128+
*os.File
129+
m sync.Mutex
130+
}

osfs/os_posix.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,20 @@ import (
77
"syscall"
88
)
99

10-
// Stat returns the FileInfo structure describing file.
1110
func (fs *OS) Stat(filename string) (os.FileInfo, error) {
1211
return os.Stat(filename)
1312
}
1413

15-
// Lock protects file from access from other processes.
16-
func (f file) Lock() error {
14+
func (f *file) Lock() error {
15+
f.m.Lock()
16+
defer f.m.Unlock()
17+
1718
return syscall.Flock(int(f.File.Fd()), syscall.LOCK_EX)
1819
}
19-
func (f file) Unlock() error {
20+
21+
func (f *file) Unlock() error {
22+
f.m.Lock()
23+
defer f.m.Unlock()
24+
2025
return syscall.Flock(int(f.File.Fd()), syscall.LOCK_UN)
2126
}

osfs/os_windows.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,10 @@ const (
5454
lockfileExclusiveLock = 0x2
5555
)
5656

57-
// Lock protects file from access from other processes.
58-
func (f file) Lock() error {
57+
func (f *file) Lock() error {
58+
f.m.Lock()
59+
defer f.m.Unlock()
60+
5961
var overlapped windows.Overlapped
6062
// err is always non-nil as per sys/windows semantics.
6163
ret, _, err := lockFileExProc.Call(f.File.Fd(), lockfileExclusiveLock, 0, 0xFFFFFFFF, 0,
@@ -66,7 +68,11 @@ func (f file) Lock() error {
6668
}
6769
return nil
6870
}
69-
func (f file) Unlock() error {
71+
72+
func (f *file) Unlock() error {
73+
f.m.Lock()
74+
defer f.m.Unlock()
75+
7076
// err is always non-nil as per sys/windows semantics.
7177
ret, _, err := unlockFileProc.Call(f.File.Fd(), 0, 0, 0xFFFFFFFF, 0)
7278
if ret == 0 {

0 commit comments

Comments
 (0)