github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/tools/dashboard/builder/filemutex_flock.go (about) 1 // Copyright 2013 The 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 // +build darwin dragonfly freebsd linux netbsd openbsd 6 7 package main 8 9 import ( 10 "sync" 11 "syscall" 12 ) 13 14 // FileMutex is similar to sync.RWMutex, but also synchronizes across processes. 15 // This implementation is based on flock syscall. 16 type FileMutex struct { 17 mu sync.RWMutex 18 fd int 19 } 20 21 func MakeFileMutex(filename string) *FileMutex { 22 if filename == "" { 23 return &FileMutex{fd: -1} 24 } 25 fd, err := syscall.Open(filename, syscall.O_CREAT|syscall.O_RDONLY, mkdirPerm) 26 if err != nil { 27 panic(err) 28 } 29 return &FileMutex{fd: fd} 30 } 31 32 func (m *FileMutex) Lock() { 33 m.mu.Lock() 34 if m.fd != -1 { 35 if err := syscall.Flock(m.fd, syscall.LOCK_EX); err != nil { 36 panic(err) 37 } 38 } 39 } 40 41 func (m *FileMutex) Unlock() { 42 if m.fd != -1 { 43 if err := syscall.Flock(m.fd, syscall.LOCK_UN); err != nil { 44 panic(err) 45 } 46 } 47 m.mu.Unlock() 48 } 49 50 func (m *FileMutex) RLock() { 51 m.mu.RLock() 52 if m.fd != -1 { 53 if err := syscall.Flock(m.fd, syscall.LOCK_SH); err != nil { 54 panic(err) 55 } 56 } 57 } 58 59 func (m *FileMutex) RUnlock() { 60 if m.fd != -1 { 61 if err := syscall.Flock(m.fd, syscall.LOCK_UN); err != nil { 62 panic(err) 63 } 64 } 65 m.mu.RUnlock() 66 }