github.com/hy3/cuto@v0.9.8-0.20160830082821-aa6652f877b7/util/lock_windows.go (about) 1 // Copyright 2015 unirita Inc. 2 // Created 2015/04/10 shanxia 3 4 package util 5 6 import ( 7 "errors" 8 "fmt" 9 "os" 10 "syscall" 11 "unsafe" 12 ) 13 14 // ミューテックスハンドルを保持する。 15 type LockHandle struct { 16 handle uintptr 17 isLock bool 18 } 19 20 const ( 21 wAIT_OBJECT_0 int = 0 22 wAIT_ABANDONED int = 128 23 wAIT_TIMEOUT int = 258 24 ) 25 26 var ErrBusy = errors.New("Locked by other process.") 27 28 // プロセス間で共通に使用する名前を指定する。 29 func InitLock(name string) (*LockHandle, error) { 30 mutexName := fmt.Sprintf("Global\\%s", name) 31 hMutex, _, _ := procCreateMutexW.Call( 32 0, 0, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(mutexName)))) 33 if hMutex == 0 { 34 lastErr := syscall.GetLastError() 35 fmt.Fprintf(os.Stderr, "Failed InitMutexW() EC = %v", lastErr) 36 return nil, lastErr 37 } 38 return &LockHandle{hMutex, false}, nil 39 } 40 41 // ロックを開始する。 42 // 引数でタイムアウト時間(ミリ秒)を指定する。 43 func (l *LockHandle) Lock(timeout_milisec int) error { 44 r1, _, _ := procWaitForSingleObject.Call(l.handle, uintptr(timeout_milisec)) 45 if int(r1) == wAIT_OBJECT_0 || int(r1) == wAIT_ABANDONED { 46 // Lock成功 47 l.isLock = true 48 return nil 49 } else if int(r1) == wAIT_TIMEOUT { 50 fmt.Fprintf(os.Stderr, "Lock Timeout.\n") 51 return ErrBusy 52 } 53 return fmt.Errorf("Lock Unknown Error. EC( %v )", syscall.GetLastError()) 54 } 55 56 // ロック中であれば、解除する。 57 func (l *LockHandle) Unlock() error { 58 if l.isLock { 59 r1, _, _ := procReleaseMutex.Call(l.handle) 60 if int(r1) == 0 { // 失敗 61 return fmt.Errorf("Unlock Error. EC( %v )", syscall.GetLastError()) 62 } 63 l.isLock = false 64 return nil 65 } 66 return nil 67 } 68 69 // 自プロセスがロックしているかの確認 70 func (l *LockHandle) IsLock() bool { 71 isLock := false 72 r1, _, _ := procWaitForSingleObject.Call(l.handle, 0) 73 if int(r1) == wAIT_OBJECT_0 || int(r1) == wAIT_ABANDONED { 74 isLock = l.isLock 75 procReleaseMutex.Call(l.handle) 76 return isLock 77 } 78 return isLock 79 } 80 81 // InitMutexで確保したミューテックスオブジェクトを破棄する。 82 func (l *LockHandle) TermLock() error { 83 procCloseHandle.Call(l.handle) 84 return nil 85 }