diff --git a/filemutex_test.go b/filemutex_test.go index 43cd6fa..585da1e 100644 --- a/filemutex_test.go +++ b/filemutex_test.go @@ -73,6 +73,18 @@ func TestClose(t *testing.T) { m.Close() } +func TestOnlyClose(t *testing.T) { + dir, err := ioutil.TempDir("", "") + require.NoError(t, err) + defer os.RemoveAll(dir) + + path := filepath.Join(dir, "x") + m, err := New(path) + require.NoError(t, err) + + require.NoError(t, m.Close()) +} + func TestLockErrorsAreRecoverable(t *testing.T) { dir, err := ioutil.TempDir("", "") require.NoError(t, err) diff --git a/filemutex_windows.go b/filemutex_windows.go index 3b6c6c4..468b9f0 100644 --- a/filemutex_windows.go +++ b/filemutex_windows.go @@ -4,7 +4,14 @@ package filemutex -import "golang.org/x/sys/windows" +import ( + "syscall" + + "golang.org/x/sys/windows" +) + +// see https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx +var errLockUnlocked syscall.Errno = 0x9E // FileMutex is similar to sync.RWMutex, but also synchronizes across processes. // This implementation is based on flock syscall. @@ -51,7 +58,7 @@ func (m *FileMutex) RUnlock() error { // Close unlocks the lock and closes the underlying file descriptor. func (m *FileMutex) Close() error { - if err := windows.UnlockFileEx(m.fd, 0, 1, 0, &windows.Overlapped{}); err != nil { + if err := windows.UnlockFileEx(m.fd, 0, 1, 0, &windows.Overlapped{}); err != nil && err != errLockUnlocked { return err } return windows.Close(m.fd)