Skip to content

Commit 24d372c

Browse files
committed
leveldb: file locking for OSX/amd64.
This was tested by running two instances of the program in manualtest/filelock. Also add a very basic test to ease implementation for other systems. R=nigeltao CC=golang-dev http://codereview.appspot.com/6446087 Committer: Nigel Tao <nigeltao@golang.org> --HG-- rename : leveldb/db/file_lock_linux_amd64.go => leveldb/db/file_lock_darwin_amd64.go
1 parent 33f57a0 commit 24d372c

File tree

3 files changed

+55
-4
lines changed

3 files changed

+55
-4
lines changed

leveldb/db/file.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ type FileSystem interface {
4545
// A nil Closer is returned if an error occurred. Otherwise, close that
4646
// Closer to release the lock.
4747
//
48-
// On Linux, a lock has the same semantics as fcntl(2)'s advisory locks.
49-
// In particular, closing any other file descriptor for the same file will
50-
// release the lock prematurely.
48+
// On Linux and OSX, a lock has the same semantics as fcntl(2)'s advisory
49+
// locks. In particular, closing any other file descriptor for the same
50+
// file will release the lock prematurely.
5151
//
5252
// Attempting to lock a file that is already locked by the current process
5353
// has undefined behavior.

leveldb/db/file_lock_darwin_amd64.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright 2012 The LevelDB-Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package db
6+
7+
import (
8+
"io"
9+
"os"
10+
"syscall"
11+
"unsafe"
12+
)
13+
14+
// lockCloser hides all of an os.File's methods, except for Close.
15+
type lockCloser struct {
16+
f *os.File
17+
}
18+
19+
func (l lockCloser) Close() error {
20+
return l.f.Close()
21+
}
22+
23+
func (defFS) Lock(name string) (io.Closer, error) {
24+
f, err := os.Create(name)
25+
if err != nil {
26+
return nil, err
27+
}
28+
29+
// This type matches C's "struct flock" defined in /usr/include/sys/fcntl.h.
30+
// TODO: move this into the standard syscall package.
31+
k := struct {
32+
Start uint64 // sizeof(off_t): 8
33+
Len uint64 // sizeof(off_t): 8
34+
Pid uint32 // sizeof(pid_t): 4
35+
Type uint16 // sizeof(short): 2
36+
Whence uint16 // sizeof(short): 2
37+
}{
38+
Type: syscall.F_WRLCK,
39+
Whence: uint16(os.SEEK_SET),
40+
Start: 0,
41+
Len: 0, // 0 means to lock the entire file.
42+
Pid: uint32(os.Getpid()),
43+
}
44+
45+
_, _, errno := syscall.Syscall(syscall.SYS_FCNTL, f.Fd(), uintptr(syscall.F_SETLK), uintptr(unsafe.Pointer(&k)))
46+
if errno != 0 {
47+
f.Close()
48+
return nil, errno
49+
}
50+
return lockCloser{f}, nil
51+
}

leveldb/db/file_lock_generic.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
// +build !linux !amd64
5+
// +build !linux,!darwin !amd64
66

77
package db
88

0 commit comments

Comments
 (0)