github.com/markusbkk/elvish@v0.0.0-20231204143114-91dc52438621/pkg/sys/ewindows/wait.go (about) 1 //go:build windows 2 // +build windows 3 4 package ewindows 5 6 import ( 7 "errors" 8 "unsafe" 9 10 "golang.org/x/sys/windows" 11 ) 12 13 const ( 14 INFINITE = 0xFFFFFFFF 15 ) 16 17 const ( 18 WAIT_OBJECT_0 = 0 19 WAIT_ABANDONED_0 = 0x00000080 20 WAIT_TIMEOUT = 0x00000102 21 WAIT_FAILED = 0xFFFFFFFF 22 ) 23 24 var ( 25 waitForMultipleObjects = kernel32.NewProc("WaitForMultipleObjects") 26 errTimeout = errors.New("WaitForMultipleObjects timeout") 27 ) 28 29 // WaitForMultipleObjects blocks until any of the objects is triggered or 30 // timeout. 31 // 32 // DWORD WINAPI WaitForMultipleObjects( 33 // _In_ DWORD nCount, 34 // _In_ const HANDLE *lpHandles, 35 // _In_ BOOL bWaitAll, 36 // _In_ DWORD dwMilliseconds 37 // ); 38 func WaitForMultipleObjects(handles []windows.Handle, waitAll bool, 39 timeout uint32) (trigger int, abandoned bool, err error) { 40 41 count := uintptr(len(handles)) 42 ret, _, err := waitForMultipleObjects.Call(count, 43 uintptr(unsafe.Pointer(&handles[0])), boolToUintptr(waitAll), uintptr(timeout)) 44 switch { 45 case WAIT_OBJECT_0 <= ret && ret < WAIT_OBJECT_0+count: 46 return int(ret - WAIT_OBJECT_0), false, nil 47 case WAIT_ABANDONED_0 <= ret && ret < WAIT_ABANDONED_0+count: 48 return int(ret - WAIT_ABANDONED_0), true, nil 49 case ret == WAIT_TIMEOUT: 50 return -1, false, errTimeout 51 default: 52 return -1, false, err 53 } 54 } 55 56 func boolToUintptr(b bool) uintptr { 57 if b { 58 return 1 59 } 60 return 0 61 }