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