Skip to content

Commit dca0640

Browse files
committed
Add windows version of lockutil from nerdctl
Also include netbsd, next to freebsd + linux Signed-off-by: Anders F Björklund <[email protected]>
1 parent 6410674 commit dca0640

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed
File renamed without changes.

pkg/lockutil/lockutil_windows.go

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// From https://github.com/containerd/nerdctl/blob/v0.13.0/pkg/lockutil/lockutil_windows.go
2+
/*
3+
Copyright The containerd Authors.
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
*/
17+
18+
package lockutil
19+
20+
import (
21+
"fmt"
22+
"os"
23+
"syscall"
24+
"unsafe"
25+
26+
"github.com/sirupsen/logrus"
27+
)
28+
29+
// LockFile modified from https://github.com/boltdb/bolt/blob/v1.3.1/bolt_windows.go using MIT
30+
var (
31+
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
32+
procLockFileEx = modkernel32.NewProc("LockFileEx")
33+
procUnlockFileEx = modkernel32.NewProc("UnlockFileEx")
34+
)
35+
36+
func WithDirLock(dir string, fn func() error) error {
37+
dirFile, err := os.OpenFile(dir+".lock", os.O_CREATE, 0644)
38+
if err != nil {
39+
return err
40+
}
41+
defer dirFile.Close()
42+
// see https://msdn.microsoft.com/en-us/library/windows/desktop/aa365203(v=vs.85).aspx
43+
// 1 lock immediately
44+
if err := lockFileEx(syscall.Handle(dirFile.Fd()), 1, 0, 1, 0, &syscall.Overlapped{}); err != nil {
45+
return fmt.Errorf("failed to lock %q: %w", dir, err)
46+
}
47+
48+
defer func() {
49+
if err := unlockFileEx(syscall.Handle(dirFile.Fd()), 0, 1, 0, &syscall.Overlapped{}); err != nil {
50+
logrus.WithError(err).Errorf("failed to unlock %q", dir)
51+
}
52+
}()
53+
return fn()
54+
}
55+
56+
func lockFileEx(h syscall.Handle, flags, reserved, locklow, lockhigh uint32, ol *syscall.Overlapped) (err error) {
57+
r, _, err := procLockFileEx.Call(uintptr(h), uintptr(flags), uintptr(reserved), uintptr(locklow), uintptr(lockhigh), uintptr(unsafe.Pointer(ol)))
58+
if r == 0 {
59+
return err
60+
}
61+
return nil
62+
}
63+
64+
func unlockFileEx(h syscall.Handle, reserved, locklow, lockhigh uint32, ol *syscall.Overlapped) (err error) {
65+
r, _, err := procUnlockFileEx.Call(uintptr(h), uintptr(reserved), uintptr(locklow), uintptr(lockhigh), uintptr(unsafe.Pointer(ol)), 0)
66+
if r == 0 {
67+
return err
68+
}
69+
return nil
70+
}

0 commit comments

Comments
 (0)