aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/go-patches
diff options
context:
space:
mode:
Diffstat (limited to 'go-patches')
-rw-r--r--go-patches/highres-timer.patch395
-rw-r--r--go-patches/no-ctrlc-handler.patch184
2 files changed, 0 insertions, 579 deletions
diff --git a/go-patches/highres-timer.patch b/go-patches/highres-timer.patch
deleted file mode 100644
index 87dd6b17..00000000
--- a/go-patches/highres-timer.patch
+++ /dev/null
@@ -1,395 +0,0 @@
-From 2975b381dc3f559a2eef875582d73cec00ab6b17 Mon Sep 17 00:00:00 2001
-From: Alex Brainman <alex.brainman@gmail.com>
-Date: Sun, 19 Jul 2020 16:06:48 +1000
-Subject: [PATCH] runtime: use CreateWaitableTimerEx to implement usleep
-
-@jstarks suggested that recent versions of Windows provide access to high resolution timers. See
-
-https://github.com/golang/go/issues/8687#issuecomment-656259353
-
-for details.
-
-I tried to run this C program on my Windows 10 computer
-
-```
- #include <stdio.h>
- #include <Windows.h>
-
- #pragma comment(lib, "Winmm.lib")
-
-// Apparently this is already defined when I use msvc cl.
-//#define CREATE_WAITABLE_TIMER_HIGH_RESOLUTION = 0x00000002;
-
-int usleep(HANDLE timer, LONGLONG d) {
- LARGE_INTEGER liDueTime;
- DWORD ret;
- LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
- LARGE_INTEGER Frequency;
-
- QueryPerformanceFrequency(&Frequency);
- QueryPerformanceCounter(&StartingTime);
-
- liDueTime.QuadPart = d;
- liDueTime.QuadPart = liDueTime.QuadPart * 10; // us into 100 of ns units
- liDueTime.QuadPart = -liDueTime.QuadPart; // negative for relative dure time
-
- if (!SetWaitableTimer(timer, &liDueTime, 0, NULL, NULL, 0)) {
- printf("SetWaitableTimer failed: errno=%d\n", GetLastError());
- return 1;
- }
-
- ret = WaitForSingleObject(timer, INFINITE);
- if (ret != WAIT_OBJECT_0) {
- printf("WaitForSingleObject failed: ret=%d errno=%d\n", ret, GetLastError());
- return 1;
- }
-
- QueryPerformanceCounter(&EndingTime);
- ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;
- ElapsedMicroseconds.QuadPart *= 1000000;
- ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;
-
- printf("delay is %lld us - slept for %lld us\n", d, ElapsedMicroseconds.QuadPart);
-
- return 0;
-}
-
-int testTimer(DWORD createFlag)
-{
- HANDLE timer;
-
- timer = CreateWaitableTimerEx(NULL, NULL, createFlag, TIMER_ALL_ACCESS);
- if (timer == NULL) {
- printf("CreateWaitableTimerEx failed: errno=%d\n", GetLastError());
- return 1;
- }
-
- usleep(timer, 1000LL);
- usleep(timer, 100LL);
- usleep(timer, 10LL);
- usleep(timer, 1LL);
-
- CloseHandle(timer);
-
- return 0;
-}
-
-int main()
-{
- printf("\n1. CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is off - timeBeginPeriod is off\n");
- testTimer(0);
-
- printf("\n2. CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is on - timeBeginPeriod is off\n");
- testTimer(CREATE_WAITABLE_TIMER_HIGH_RESOLUTION);
-
- timeBeginPeriod(1);
-
- printf("\n3. CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is off - timeBeginPeriod is on\n");
- testTimer(0);
-
- printf("\n4. CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is on - timeBeginPeriod is on\n");
- testTimer(CREATE_WAITABLE_TIMER_HIGH_RESOLUTION);
-}
-```
-
-and I see this output
-
-```
-1. CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is off - timeBeginPeriod is off
-delay is 1000 us - slept for 4045 us
-delay is 100 us - slept for 3915 us
-delay is 10 us - slept for 3291 us
-delay is 1 us - slept for 2234 us
-
-2. CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is on - timeBeginPeriod is off
-delay is 1000 us - slept for 1076 us
-delay is 100 us - slept for 569 us
-delay is 10 us - slept for 585 us
-delay is 1 us - slept for 17 us
-
-3. CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is off - timeBeginPeriod is on
-delay is 1000 us - slept for 742 us
-delay is 100 us - slept for 893 us
-delay is 10 us - slept for 414 us
-delay is 1 us - slept for 920 us
-
-4. CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is on - timeBeginPeriod is on
-delay is 1000 us - slept for 1466 us
-delay is 100 us - slept for 559 us
-delay is 10 us - slept for 535 us
-delay is 1 us - slept for 5 us
-```
-
-That shows, that indeed using CREATE_WAITABLE_TIMER_HIGH_RESOLUTION
-will provide sleeps as low as about 500 microseconds, while our
-current approach provides about 1 millisecond sleep.
-
-New approach also does not require for timeBeginPeriod to be on,
-so this change solves long standing problem with go programs draining
-laptop battery, because it calls timeBeginPeriod.
-
-This change will only run on systems where
-CREATE_WAITABLE_TIMER_HIGH_RESOLUTION flag is available. If not
-available, the runtime will fallback to original code that uses
-timeBeginPeriod.
-
-This is how this change affects benchmark reported in issue #14790
-
-name               old time/op  new time/op  delta
-ChanToSyscallPing  1.05ms ± 2%  0.68ms ±11%  -35.43%  (p=0.000 n=10+10)
-
-The benchmark was run with GOMAXPROCS set to 1.
-
-Fixes #8687
-Updates #14790
-
-Change-Id: I5b97ba58289c088c17c05292e12e45285c467eae
----
-
-diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go
-index a62e941..46f4a23 100644
---- a/src/runtime/os_windows.go
-+++ b/src/runtime/os_windows.go
-@@ -21,6 +21,7 @@
- //go:cgo_import_dynamic runtime._CreateIoCompletionPort CreateIoCompletionPort%4 "kernel32.dll"
- //go:cgo_import_dynamic runtime._CreateThread CreateThread%6 "kernel32.dll"
- //go:cgo_import_dynamic runtime._CreateWaitableTimerA CreateWaitableTimerA%3 "kernel32.dll"
-+//go:cgo_import_dynamic runtime._CreateWaitableTimerExW CreateWaitableTimerExW%4 "kernel32.dll"
- //go:cgo_import_dynamic runtime._DuplicateHandle DuplicateHandle%7 "kernel32.dll"
- //go:cgo_import_dynamic runtime._ExitProcess ExitProcess%1 "kernel32.dll"
- //go:cgo_import_dynamic runtime._FreeEnvironmentStringsW FreeEnvironmentStringsW%1 "kernel32.dll"
-@@ -68,6 +69,7 @@
- _CreateIoCompletionPort,
- _CreateThread,
- _CreateWaitableTimerA,
-+ _CreateWaitableTimerExW,
- _DuplicateHandle,
- _ExitProcess,
- _FreeEnvironmentStringsW,
-@@ -151,6 +153,8 @@
- waitsema uintptr // semaphore for parking on locks
- resumesema uintptr // semaphore to indicate suspend/resume
-
-+ highResTimer uintptr // high resolution timer handle used in usleep
-+
- // preemptExtLock synchronizes preemptM with entry/exit from
- // external C code.
- //
-@@ -407,6 +411,12 @@
- // if we're already using the CPU, but if all Ps are idle there's no
- // need to consume extra power to drive the high-res timer.
- func osRelax(relax bool) uint32 {
-+ if haveHighResTimer {
-+ // Only call timeBeginPeriod/timeEndPeriod, if
-+ // high resolution timer is not available.
-+ return 0
-+ }
-+
- if relax {
- return uint32(stdcall1(_timeEndPeriod, 1))
- } else {
-@@ -414,6 +424,37 @@
- }
- }
-
-+// haveHighResTimer determines, if CreateWaitableTimerEx
-+// CREATE_WAITABLE_TIMER_HIGH_RESOLUTION flag is available.
-+var haveHighResTimer = false
-+
-+// createHighResTimer calls CreateWaitableTimerEx with
-+// CREATE_WAITABLE_TIMER_HIGH_RESOLUTION flag to create high
-+// resolution timer. createHighResTimer returns new timer
-+// handle or 0, if CreateWaitableTimerEx failed.
-+func createHighResTimer() uintptr {
-+ const (
-+ // As per @jstarks, see
-+ // https://github.com/golang/go/issues/8687#issuecomment-656259353
-+ _CREATE_WAITABLE_TIMER_HIGH_RESOLUTION = 0x00000002
-+ _TIMER_ALL_ACCESS = 0x1F0003
-+ )
-+ return stdcall4(_CreateWaitableTimerExW, 0, 0, _CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, _TIMER_ALL_ACCESS)
-+}
-+
-+func initHighResTimer() {
-+ if GOARCH == "arm" {
-+ // TODO: Not yet implemented.
-+ return
-+ }
-+ h := createHighResTimer()
-+ if h != 0 {
-+ haveHighResTimer = true
-+ usleep2Addr = unsafe.Pointer(funcPC(usleep2HighRes))
-+ stdcall1(_CloseHandle, h)
-+ }
-+}
-+
- func osinit() {
- asmstdcallAddr = unsafe.Pointer(funcPC(asmstdcall))
- usleep2Addr = unsafe.Pointer(funcPC(usleep2))
-@@ -429,6 +470,7 @@
-
- stdcall2(_SetConsoleCtrlHandler, funcPC(ctrlhandler), 1)
-
-+ initHighResTimer()
- timeBeginPeriodRetValue = osRelax(false)
-
- ncpu = getproccount()
-@@ -844,9 +886,20 @@
- var thandle uintptr
- stdcall7(_DuplicateHandle, currentProcess, currentThread, currentProcess, uintptr(unsafe.Pointer(&thandle)), 0, 0, _DUPLICATE_SAME_ACCESS)
-
-+ // Configure usleep timer, if possible.
-+ var timer uintptr
-+ if haveHighResTimer {
-+ timer = createHighResTimer()
-+ if timer == 0 {
-+ print("runtime: CreateWaitableTimerEx failed; errno=", getlasterror(), "\n")
-+ throw("CreateWaitableTimerEx when creating timer failed")
-+ }
-+ }
-+
- mp := getg().m
- lock(&mp.threadLock)
- mp.thread = thandle
-+ mp.highResTimer = timer
- unlock(&mp.threadLock)
-
- // Query the true stack base from the OS. Currently we're
-@@ -884,6 +937,10 @@
- lock(&mp.threadLock)
- stdcall1(_CloseHandle, mp.thread)
- mp.thread = 0
-+ if mp.highResTimer != 0 {
-+ stdcall1(_CloseHandle, mp.highResTimer)
-+ mp.highResTimer = 0
-+ }
- unlock(&mp.threadLock)
- }
-
-@@ -979,6 +1036,7 @@
- // in sys_windows_386.s and sys_windows_amd64.s
- func onosstack(fn unsafe.Pointer, arg uint32)
- func usleep2(usec uint32)
-+func usleep2HighRes(usec uint32)
- func switchtothread()
-
- var usleep2Addr unsafe.Pointer
-diff --git a/src/runtime/sys_windows_386.s b/src/runtime/sys_windows_386.s
-index 9e1f409..4ac1527 100644
---- a/src/runtime/sys_windows_386.s
-+++ b/src/runtime/sys_windows_386.s
-@@ -428,6 +428,42 @@
- MOVL BP, SP
- RET
-
-+// Runs on OS stack. duration (in 100ns units) is in BX.
-+TEXT runtime·usleep2HighRes(SB),NOSPLIT,$36
-+ // Want negative 100ns units.
-+ NEGL BX
-+ MOVL $-1, hi-4(SP)
-+ MOVL BX, lo-8(SP)
-+
-+ get_tls(CX)
-+ MOVL g(CX), CX
-+ MOVL g_m(CX), CX
-+ MOVL (m_mOS+mOS_highResTimer)(CX), CX
-+ MOVL CX, saved_timer-12(SP)
-+
-+ MOVL $0, fResume-16(SP)
-+ MOVL $0, lpArgToCompletionRoutine-20(SP)
-+ MOVL $0, pfnCompletionRoutine-24(SP)
-+ MOVL $0, lPeriod-28(SP)
-+ LEAL lo-8(SP), BX
-+ MOVL BX, lpDueTime-32(SP)
-+ MOVL CX, hTimer-36(SP)
-+ MOVL SP, BP
-+ MOVL runtime·_SetWaitableTimer(SB), AX
-+ CALL AX
-+ MOVL BP, SP
-+
-+ MOVL $0, ptime-28(SP)
-+ MOVL $0, alertable-32(SP)
-+ MOVL saved_timer-12(SP), CX
-+ MOVL CX, handle-36(SP)
-+ MOVL SP, BP
-+ MOVL runtime·_NtWaitForSingleObject(SB), AX
-+ CALL AX
-+ MOVL BP, SP
-+
-+ RET
-+
- // Runs on OS stack.
- TEXT runtime·switchtothread(SB),NOSPLIT,$0
- MOVL SP, BP
-diff --git a/src/runtime/sys_windows_amd64.s b/src/runtime/sys_windows_amd64.s
-index 6c8eecd..8475425 100644
---- a/src/runtime/sys_windows_amd64.s
-+++ b/src/runtime/sys_windows_amd64.s
-@@ -457,6 +457,38 @@
- MOVQ 40(SP), SP
- RET
-
-+// Runs on OS stack. duration (in 100ns units) is in BX.
-+TEXT runtime·usleep2HighRes(SB),NOSPLIT|NOFRAME,$72
-+ MOVQ SP, AX
-+ ANDQ $~15, SP // alignment as per Windows requirement
-+ MOVQ AX, 64(SP)
-+
-+ get_tls(CX)
-+ MOVQ g(CX), CX
-+ MOVQ g_m(CX), CX
-+ MOVQ (m_mOS+mOS_highResTimer)(CX), CX // hTimer
-+ MOVQ CX, 48(SP) // save hTimer for later
-+ // Want negative 100ns units.
-+ NEGQ BX
-+ LEAQ 56(SP), DX // lpDueTime
-+ MOVQ BX, (DX)
-+ MOVQ $0, R8 // lPeriod
-+ MOVQ $0, R9 // pfnCompletionRoutine
-+ MOVQ $0, AX
-+ MOVQ AX, 32(SP) // lpArgToCompletionRoutine
-+ MOVQ AX, 40(SP) // fResume
-+ MOVQ runtime·_SetWaitableTimer(SB), AX
-+ CALL AX
-+
-+ MOVQ 48(SP), CX // handle
-+ MOVQ $0, DX // alertable
-+ MOVQ $0, R8 // ptime
-+ MOVQ runtime·_NtWaitForSingleObject(SB), AX
-+ CALL AX
-+
-+ MOVQ 64(SP), SP
-+ RET
-+
- // Runs on OS stack.
- TEXT runtime·switchtothread(SB),NOSPLIT|NOFRAME,$0
- MOVQ SP, AX
-diff --git a/src/runtime/sys_windows_arm.s b/src/runtime/sys_windows_arm.s
-index 256b5ff..e6c61a4 100644
---- a/src/runtime/sys_windows_arm.s
-+++ b/src/runtime/sys_windows_arm.s
-@@ -468,6 +468,24 @@
- MOVW R4, R13 // Restore SP
- MOVM.IA.W (R13), [R4, R15] // pop {R4, pc}
-
-+// Runs on OS stack. Duration (in 100ns units) is in R0.
-+// TODO: neeeds to be implemented properly.
-+TEXT runtime·usleep2HighRes(SB),NOSPLIT|NOFRAME,$0
-+ MOVM.DB.W [R4, R14], (R13) // push {r4, lr}
-+ MOVW R13, R4 // Save SP
-+ SUB $8, R13 // R13 = R13 - 8
-+ BIC $0x7, R13 // Align SP for ABI
-+ RSB $0, R0, R3 // R3 = -R0
-+ MOVW $0, R1 // R1 = FALSE (alertable)
-+ MOVW $-1, R0 // R0 = handle
-+ MOVW R13, R2 // R2 = pTime
-+ MOVW R3, 0(R2) // time_lo
-+ MOVW R0, 4(R2) // time_hi
-+ MOVW runtime·_NtWaitForSingleObject(SB), R3
-+ BL (R3)
-+ MOVW R4, R13 // Restore SP
-+ MOVM.IA.W (R13), [R4, R15] // pop {R4, pc}
-+
- // Runs on OS stack.
- TEXT runtime·switchtothread(SB),NOSPLIT|NOFRAME,$0
- MOVM.DB.W [R4, R14], (R13) // push {R4, lr}
diff --git a/go-patches/no-ctrlc-handler.patch b/go-patches/no-ctrlc-handler.patch
deleted file mode 100644
index 157ed88f..00000000
--- a/go-patches/no-ctrlc-handler.patch
+++ /dev/null
@@ -1,184 +0,0 @@
-From 8bc7bff3bff8f61312f8d2307cfe2e433d356c31 Mon Sep 17 00:00:00 2001
-From: "Jason A. Donenfeld" <Jason@zx2c4.com>
-Date: Fri, 11 Sep 2020 13:04:11 +0200
-Subject: [PATCH 1/2] Revert "[release-branch.go1.15] runtime: detect services
- in signal handler"
-
-This reverts commit b1253d24e159129c778377c3a2a0bde15904a417.
----
- src/runtime/os_windows.go | 73 +++------------------------------------
- 1 file changed, 4 insertions(+), 69 deletions(-)
-
-diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go
-index 769197db46..a584ada702 100644
---- a/src/runtime/os_windows.go
-+++ b/src/runtime/os_windows.go
-@@ -36,10 +36,7 @@ const (
- //go:cgo_import_dynamic runtime._SetThreadContext SetThreadContext%2 "kernel32.dll"
- //go:cgo_import_dynamic runtime._LoadLibraryW LoadLibraryW%1 "kernel32.dll"
- //go:cgo_import_dynamic runtime._LoadLibraryA LoadLibraryA%1 "kernel32.dll"
--//go:cgo_import_dynamic runtime._OpenProcess OpenProcess%3 "kernel32.dll"
- //go:cgo_import_dynamic runtime._PostQueuedCompletionStatus PostQueuedCompletionStatus%4 "kernel32.dll"
--//go:cgo_import_dynamic runtime._ProcessIdToSessionId ProcessIdToSessionId%2 "kernel32.dll"
--//go:cgo_import_dynamic runtime._QueryFullProcessImageNameA QueryFullProcessImageNameA%4 "kernel32.dll"
- //go:cgo_import_dynamic runtime._ResumeThread ResumeThread%1 "kernel32.dll"
- //go:cgo_import_dynamic runtime._SetConsoleCtrlHandler SetConsoleCtrlHandler%2 "kernel32.dll"
- //go:cgo_import_dynamic runtime._SetErrorMode SetErrorMode%1 "kernel32.dll"
-@@ -87,10 +84,7 @@ var (
- _SetThreadContext,
- _LoadLibraryW,
- _LoadLibraryA,
-- _OpenProcess,
- _PostQueuedCompletionStatus,
-- _ProcessIdToSessionId,
-- _QueryFullProcessImageNameA,
- _QueryPerformanceCounter,
- _QueryPerformanceFrequency,
- _ResumeThread,
-@@ -134,8 +128,7 @@ var (
- // Load ntdll.dll manually during startup, otherwise Mingw
- // links wrong printf function to cgo executable (see issue
- // 12030 for details).
-- _NtWaitForSingleObject stdFunction
-- _NtQueryInformationProcess stdFunction
-+ _NtWaitForSingleObject stdFunction
-
- // These are from non-kernel32.dll, so we prefer to LoadLibraryEx them.
- _timeBeginPeriod,
-@@ -262,7 +255,6 @@ func loadOptionalSyscalls() {
- throw("ntdll.dll not found")
- }
- _NtWaitForSingleObject = windowsFindfunc(n32, []byte("NtWaitForSingleObject\000"))
-- _NtQueryInformationProcess = windowsFindfunc(n32, []byte("NtQueryInformationProcess\000"))
-
- if GOARCH == "arm" {
- _QueryPerformanceCounter = windowsFindfunc(k32, []byte("QueryPerformanceCounter\000"))
-@@ -1003,63 +995,6 @@ func usleep(us uint32) {
- onosstack(usleep2Addr, 10*us)
- }
-
--// isWindowsService returns whether the process is currently executing as a
--// Windows service. The below technique looks a bit hairy, but it's actually
--// exactly what the .NET framework does for the similarly named function:
--// https://github.com/dotnet/extensions/blob/f4066026ca06984b07e90e61a6390ac38152ba93/src/Hosting/WindowsServices/src/WindowsServiceHelpers.cs#L26-L31
--// Specifically, it looks up whether the parent process has session ID zero
--// and is called "services".
--func isWindowsService() bool {
-- const (
-- _CURRENT_PROCESS = ^uintptr(0)
-- _PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
-- )
-- // pbi is a PROCESS_BASIC_INFORMATION struct, where we just care about
-- // the 6th pointer inside of it, which contains the pid of the process
-- // parent:
-- // https://github.com/wine-mirror/wine/blob/42cb7d2ad1caba08de235e6319b9967296b5d554/include/winternl.h#L1294
-- var pbi [6]uintptr
-- var pbiLen uint32
-- err := stdcall5(_NtQueryInformationProcess, _CURRENT_PROCESS, 0, uintptr(unsafe.Pointer(&pbi[0])), uintptr(unsafe.Sizeof(pbi)), uintptr(unsafe.Pointer(&pbiLen)))
-- if err != 0 {
-- return false
-- }
-- var psid uint32
-- err = stdcall2(_ProcessIdToSessionId, pbi[5], uintptr(unsafe.Pointer(&psid)))
-- if err == 0 || psid != 0 {
-- return false
-- }
-- pproc := stdcall3(_OpenProcess, _PROCESS_QUERY_LIMITED_INFORMATION, 0, pbi[5])
-- if pproc == 0 {
-- return false
-- }
-- defer stdcall1(_CloseHandle, pproc)
-- // exeName gets the path to the executable image of the parent process
-- var exeName [261]byte
-- exeNameLen := uint32(len(exeName) - 1)
-- err = stdcall4(_QueryFullProcessImageNameA, pproc, 0, uintptr(unsafe.Pointer(&exeName[0])), uintptr(unsafe.Pointer(&exeNameLen)))
-- if err == 0 || exeNameLen == 0 {
-- return false
-- }
-- servicesLower := "services.exe"
-- servicesUpper := "SERVICES.EXE"
-- i := int(exeNameLen) - 1
-- j := len(servicesLower) - 1
-- if i < j {
-- return false
-- }
-- for {
-- if j == -1 {
-- return i == -1 || exeName[i] == '\\'
-- }
-- if exeName[i] != servicesLower[j] && exeName[i] != servicesUpper[j] {
-- return false
-- }
-- i--
-- j--
-- }
--}
--
- func ctrlhandler1(_type uint32) uint32 {
- var s uint32
-
-@@ -1075,9 +1010,9 @@ func ctrlhandler1(_type uint32) uint32 {
- if sigsend(s) {
- return 1
- }
-- if !islibrary && !isarchive && !isWindowsService() {
-- // Only exit the program if we don't have a DLL or service.
-- // See https://golang.org/issues/35965 and https://golang.org/issues/40167
-+ if !islibrary && !isarchive {
-+ // Only exit the program if we don't have a DLL.
-+ // See https://golang.org/issues/35965.
- exit(2) // SIGINT, SIGTERM, etc
- }
- return 0
---
-2.28.0
-
-From 84cc2046962e754af08f99327561be2e979eaf16 Mon Sep 17 00:00:00 2001
-From: "Jason A. Donenfeld" <Jason@zx2c4.com>
-Date: Tue, 14 Jul 2020 01:41:03 -0600
-Subject: [PATCH 2/2] runtime: do not explicitly exit on ctrl handler
-
-The default ctrl+c handler should process exits in situations where it
-makes sense, like console apps, but not in situations where it doesn't,
-like libraries or services. Therefore, we should remove the exit(2) so
-that the default handler is used for this. This also uses the more
-proper windows exit code of STATUS_CONTROL_C_EXIT, with the base case
-handler installed by KernelBase.dll. In particular, this helps in the
-case of services, which previously would terminate when receiving
-shutdown signals, instead of passing them onward to the service program.
-In this CL, contrary to CL 244959, we do not need to special case
-services with expensive detection algorithms, or rely on hard-coded
-library/archive flags.
-
-Fixes #40167.
-Fixes #40074.
-
-Change-Id: I9bf6ed6f65cefeff754d270aa33fa4df8d0b451f
-Reviewed-on: https://go-review.googlesource.com/c/go/+/243597
-Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
-TryBot-Result: Gobot Gobot <gobot@golang.org>
-Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
-Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>
----
- src/runtime/os_windows.go | 5 -----
- 1 file changed, 5 deletions(-)
-
-diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go
-index a584ada702..a62e941229 100644
---- a/src/runtime/os_windows.go
-+++ b/src/runtime/os_windows.go
-@@ -1010,11 +1010,6 @@ func ctrlhandler1(_type uint32) uint32 {
- if sigsend(s) {
- return 1
- }
-- if !islibrary && !isarchive {
-- // Only exit the program if we don't have a DLL.
-- // See https://golang.org/issues/35965.
-- exit(2) // SIGINT, SIGTERM, etc
-- }
- return 0
- }
-
---
-2.28.0
-