From d3f0e20f92a9b368208e5527d38e3004667c8a63 Mon Sep 17 00:00:00 2001 From: Christian Franco Date: Tue, 7 May 2024 13:00:18 -0700 Subject: [PATCH] fix(puppet-agent): Fixes #9208 - puppet agent windows daemon startup inconsistency --- lib/puppet/util/windows/daemon.rb | 50 +++++++++++-------------------- 1 file changed, 17 insertions(+), 33 deletions(-) diff --git a/lib/puppet/util/windows/daemon.rb b/lib/puppet/util/windows/daemon.rb index 4c8c949aee0..7f8dda29106 100644 --- a/lib/puppet/util/windows/daemon.rb +++ b/lib/puppet/util/windows/daemon.rb @@ -187,25 +187,6 @@ class Daemon SetTheServiceStatus.call(SERVICE_STOPPED, NO_ERROR, 0, 0) end - ThreadProc = FFI::Function.new(:ulong, [:pointer]) do |lpParameter| - ste = FFI::MemoryPointer.new(SERVICE_TABLE_ENTRYW, 2) - - s = SERVICE_TABLE_ENTRYW.new(ste[0]) - s[:lpServiceName] = FFI::MemoryPointer.from_string('') - s[:lpServiceProc] = lpParameter - - s = SERVICE_TABLE_ENTRYW.new(ste[1]) - s[:lpServiceName] = nil - s[:lpServiceProc] = nil - - # No service to step, no service handle, no ruby exceptions, just terminate the thread.. - unless StartServiceCtrlDispatcherW(ste) - return 1 - end - - return 0 - end - # This is a shortcut for Daemon.new + Daemon#mainloop. # def self.mainloop @@ -255,26 +236,29 @@ def mainloop raise SystemCallError.new('CreateEvent', FFI.errno) end - hThread = CreateThread(nil, 0, ThreadProc, Service_Main, 0, nil) + hThread = Thread.new(Service_Main) do |lp_proc| + ste = FFI::MemoryPointer.new(SERVICE_TABLE_ENTRYW, 2) - if hThread == 0 - raise SystemCallError.new('CreateThread', FFI.errno) - end + s = SERVICE_TABLE_ENTRYW.new(ste[0]) + s[:lpServiceName] = FFI::MemoryPointer.from_string("") + s[:lpServiceProc] = lp_proc - events = FFI::MemoryPointer.new(:pointer, 2) - events.put_pointer(0, FFI::Pointer.new(hThread)) - events.put_pointer(FFI::Pointer.size, FFI::Pointer.new(@@hStartEvent)) + s = SERVICE_TABLE_ENTRYW.new(ste[1]) + s[:lpServiceName] = nil + s[:lpServiceProc] = nil - while (index = WaitForMultipleObjects(2, events, 0, 1000)) == WAIT_TIMEOUT + # When returning 'false', there is no service to stop, no service handle, + # no ruby exceptions, just terminate the thread. + StartServiceCtrlDispatcherW(ste) end - if index == WAIT_FAILED - raise SystemCallError.new('WaitForMultipleObjects', FFI.errno) + while (index = WaitForSingleObject(@@hStartEvent, 1000)) == WAIT_TIMEOUT + # The thread exited, so the show is off. + raise "Service_Main thread exited abnormally" unless hThread.alive? end - # The thread exited, so the show is off. - if index == WAIT_OBJECT_0 - raise "Service_Main thread exited abnormally" + if index == WAIT_FAILED + raise SystemCallError.new("WaitForSingleObject", FFI.errno) end thr = Thread.new do @@ -354,4 +338,4 @@ def running? [SERVICE_RUNNING, SERVICE_PAUSED, 0].include?(@@dwServiceState) end end -end +end \ No newline at end of file