Skip to content

Commit 1a3b739

Browse files
jboelterintcrsc
authored andcommitted
runtime: check for errors returned by windows sema calls
Add checks for failure of CreateEvent, SetEvent or WaitForSingleObject. Any failures are considered fatal and will throw() after printing an informative message. Updates #16646 Change-Id: I3bacf9001d2abfa8667cc3aff163ff2de1c99915 Reviewed-on: https://go-review.googlesource.com/26655 Reviewed-by: Russ Cox <[email protected]> Run-TryBot: Russ Cox <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent 9d36ab2 commit 1a3b739

File tree

1 file changed

+47
-4
lines changed

1 file changed

+47
-4
lines changed

src/runtime/os_windows.go

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,13 @@ func writeConsoleUTF16(handle uintptr, b []uint16) {
437437

438438
//go:nosplit
439439
func semasleep(ns int64) int32 {
440+
const (
441+
_WAIT_ABANDONED = 0x00000080
442+
_WAIT_OBJECT_0 = 0x00000000
443+
_WAIT_TIMEOUT = 0x00000102
444+
_WAIT_FAILED = 0xFFFFFFFF
445+
)
446+
440447
// store ms in ns to save stack space
441448
if ns < 0 {
442449
ns = _INFINITE
@@ -446,15 +453,44 @@ func semasleep(ns int64) int32 {
446453
ns = 1
447454
}
448455
}
449-
if stdcall2(_WaitForSingleObject, getg().m.waitsema, uintptr(ns)) != 0 {
450-
return -1 // timeout
456+
457+
result := stdcall2(_WaitForSingleObject, getg().m.waitsema, uintptr(ns))
458+
switch result {
459+
case _WAIT_OBJECT_0: //signaled
460+
return 0
461+
462+
case _WAIT_TIMEOUT:
463+
return -1
464+
465+
case _WAIT_ABANDONED:
466+
systemstack(func() {
467+
throw("runtime.semasleep wait_abandoned")
468+
})
469+
470+
case _WAIT_FAILED:
471+
systemstack(func() {
472+
print("runtime: waitforsingleobject wait_failed; errno=", getlasterror(), "\n")
473+
throw("runtime.semasleep wait_failed")
474+
})
475+
476+
default:
477+
systemstack(func() {
478+
print("runtime: waitforsingleobject unexpected; result=", result, "\n")
479+
throw("runtime.semasleep unexpected")
480+
})
451481
}
452-
return 0
482+
483+
return -1 // unreachable
453484
}
454485

455486
//go:nosplit
456487
func semawakeup(mp *m) {
457-
stdcall1(_SetEvent, mp.waitsema)
488+
if stdcall1(_SetEvent, mp.waitsema) == 0 {
489+
systemstack(func() {
490+
print("runtime: setevent failed; errno=", getlasterror(), "\n")
491+
throw("runtime.semawakeup")
492+
})
493+
}
458494
}
459495

460496
//go:nosplit
@@ -463,6 +499,12 @@ func semacreate(mp *m) {
463499
return
464500
}
465501
mp.waitsema = stdcall4(_CreateEventA, 0, 0, 0, 0)
502+
if mp.waitsema == 0 {
503+
systemstack(func() {
504+
print("runtime: createevent failed; errno=", getlasterror(), "\n")
505+
throw("runtime.semacreate")
506+
})
507+
}
466508
}
467509

468510
// May run with m.p==nil, so write barriers are not allowed. This
@@ -475,6 +517,7 @@ func newosproc(mp *m, stk unsafe.Pointer) {
475517
thandle := stdcall6(_CreateThread, 0, 0x20000,
476518
funcPC(tstart_stdcall), uintptr(unsafe.Pointer(mp)),
477519
_STACK_SIZE_PARAM_IS_A_RESERVATION, 0)
520+
478521
if thandle == 0 {
479522
print("runtime: failed to create new OS thread (have ", mcount(), " already; errno=", getlasterror(), ")\n")
480523
throw("runtime.newosproc")

0 commit comments

Comments
 (0)