update file lock

This commit is contained in:
siddontang 2014-10-22 09:37:15 +08:00
parent ada3cebe10
commit c7a17e4e4a
5 changed files with 10 additions and 178 deletions

View File

@ -1,51 +0,0 @@
// Copyright 2012 The LevelDB-Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package filelock
import (
"io"
"os"
"syscall"
"unsafe"
)
// lockCloser hides all of an os.File's methods, except for Close.
type lockCloser struct {
f *os.File
}
func (l lockCloser) Close() error {
return l.f.Close()
}
func Lock(name string) (io.Closer, error) {
f, err := os.Create(name)
if err != nil {
return nil, err
}
// This type matches C's "struct flock" defined in /usr/include/sys/fcntl.h.
// TODO: move this into the standard syscall package.
k := struct {
Start uint64 // sizeof(off_t): 8
Len uint64 // sizeof(off_t): 8
Pid uint32 // sizeof(pid_t): 4
Type uint16 // sizeof(short): 2
Whence uint16 // sizeof(short): 2
}{
Type: syscall.F_WRLCK,
Whence: uint16(os.SEEK_SET),
Start: 0,
Len: 0, // 0 means to lock the entire file.
Pid: uint32(os.Getpid()),
}
_, _, errno := syscall.Syscall(syscall.SYS_FCNTL, f.Fd(), uintptr(syscall.F_SETLK), uintptr(unsafe.Pointer(&k)))
if errno != 0 {
f.Close()
return nil, errno
}
return lockCloser{f}, nil
}

View File

@ -2,11 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build !linux,!amd64 // +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
// +build !darwin,!amd64
// +build !openbsd,!amd64
// +build !freebsd
// +build !windows
package filelock package filelock

View File

@ -1,51 +0,0 @@
// Copyright 2012 The LevelDB-Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package filelock
import (
"io"
"os"
"syscall"
"unsafe"
)
// lockCloser hides all of an os.File's methods, except for Close.
type lockCloser struct {
f *os.File
}
func (l lockCloser) Close() error {
return l.f.Close()
}
func Lock(name string) (io.Closer, error) {
f, err := os.Create(name)
if err != nil {
return nil, err
}
// This type matches C's "struct flock" defined in /usr/include/bits/fcntl.h.
// TODO: move this into the standard syscall package.
k := struct {
Type uint32
Whence uint32
Start uint64
Len uint64
Pid uint32
}{
Type: syscall.F_WRLCK,
Whence: uint32(os.SEEK_SET),
Start: 0,
Len: 0, // 0 means to lock the entire file.
Pid: uint32(os.Getpid()),
}
_, _, errno := syscall.Syscall(syscall.SYS_FCNTL, f.Fd(), uintptr(syscall.F_SETLK), uintptr(unsafe.Pointer(&k)))
if errno != 0 {
f.Close()
return nil, errno
}
return lockCloser{f}, nil
}

View File

@ -1,51 +0,0 @@
// Copyright 2013 The LevelDB-Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package filelock
import (
"io"
"os"
"syscall"
"unsafe"
)
// lockCloser hides all of an os.File's methods, except for Close.
type lockCloser struct {
f *os.File
}
func (l lockCloser) Close() error {
return l.f.Close()
}
func Lock(name string) (io.Closer, error) {
f, err := os.Create(name)
if err != nil {
return nil, err
}
// This type matches C's "struct flock" defined in /usr/include/fcntl.h.
// TODO: move this into the standard syscall package.
k := struct {
Start uint64
Len uint64
Pid uint32
Type uint32
Whence uint32
}{
Type: syscall.F_WRLCK,
Whence: uint32(os.SEEK_SET),
Start: 0,
Len: 0, // 0 means to lock the entire file.
Pid: uint32(os.Getpid()),
}
_, _, errno := syscall.Syscall(syscall.SYS_FCNTL, f.Fd(), uintptr(syscall.F_SETLK), uintptr(unsafe.Pointer(&k)))
if errno != 0 {
f.Close()
return nil, errno
}
return lockCloser{f}, nil
}

View File

@ -2,13 +2,14 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
package filelock package filelock
import ( import (
"io" "io"
"os" "os"
"syscall" "syscall"
"unsafe"
) )
// lockCloser hides all of an os.File's methods, except for Close. // lockCloser hides all of an os.File's methods, except for Close.
@ -25,29 +26,17 @@ func Lock(name string) (io.Closer, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
spec := syscall.Flock_t{
// This type matches C's "struct flock" defined in /usr/include/fcntl.h. Type: syscall.F_WRLCK,
// TODO: move this into the standard syscall package. Whence: int16(os.SEEK_SET),
k := struct {
Start int64 /* off_t starting offset */
Len int64 /* off_t len = 0 means until end of file */
Pid int32 /* pid_t lock owner */
Type int16 /* short lock type: read/write, etc. */
Whence int16 /* short type of l_start */
Sysid int32 /* int remote system id or zero for local */
}{
Start: 0, Start: 0,
Len: 0, // 0 means to lock the entire file. Len: 0, // 0 means to lock the entire file.
Pid: int32(os.Getpid()), Pid: int32(os.Getpid()),
Type: syscall.F_WRLCK, }
Whence: int16(os.SEEK_SET), if err := syscall.FcntlFlock(f.Fd(), syscall.F_SETLK, &spec); err != nil {
Sysid: 0, f.Close()
return nil, err
} }
_, _, errno := syscall.Syscall(syscall.SYS_FCNTL, f.Fd(), uintptr(syscall.F_SETLK), uintptr(unsafe.Pointer(&k)))
if errno != 0 {
f.Close()
return nil, errno
}
return lockCloser{f}, nil return lockCloser{f}, nil
} }