Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make boot great again #83

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
10 changes: 9 additions & 1 deletion lib/win32/daemon.rb
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,13 @@ class Daemon
# Main loop for the service.
while WaitForSingleObject(@@hStopCompletedEvent, 1000) != WAIT_OBJECT_0
end
ensure

# Stop the service.
SetTheServiceStatus.call(SERVICE_STOPPED, NO_ERROR, 0, 0)
ensure
# Stop the service.
# This ensures that if the main thread crashes and Service_Main thread is terminated, we will set nonzero win32exitCode
SetTheServiceStatus.call(SERVICE_STOPPED, 1, 0, 0)
end
end

Expand Down Expand Up @@ -265,6 +269,10 @@ def mainloop
events.put_pointer(FFI::Pointer.size, FFI::Pointer.new(@@hStartEvent))

while (index = WaitForMultipleObjects(2, events, 0, 1000)) == WAIT_TIMEOUT
# applying some magic to delay things, as somehow this while loop
# can enter some kind of deadlock state without this, leading
# to our service not being able to boot
sleep(0.1)
end

if index == WAIT_FAILED
Expand Down
20 changes: 18 additions & 2 deletions lib/win32/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ class Service
# * failure_command => nil,
# * failure_actions => nil,
# * failure_delay => 0
# * failure_flag => nil
#
# Example:
#
Expand Down Expand Up @@ -317,6 +318,7 @@ def initialize(options = {})
"failure_command" => nil,
"failure_actions" => nil,
"failure_delay" => 0,
"failure_flag" => nil,
"host" => nil,
"service_name" => nil,
}
Expand Down Expand Up @@ -396,7 +398,7 @@ def initialize(options = {})
end

if opts["failure_reset_period"] || opts["failure_reboot_message"] ||
opts["failure_command"] || opts["failure_actions"]
opts["failure_command"] || opts["failure_actions"] || !opts["failure_flag"].nil?
self.class.configure_failure_actions(handle_scs, opts)
end
ensure
Expand Down Expand Up @@ -425,6 +427,7 @@ def initialize(options = {})
# * failure_reboot_message
# * failure_command
# * failure_actions
# * failure_flag
# * failure_delay
#
# Examples:
Expand Down Expand Up @@ -475,6 +478,7 @@ def self.configure(options = {})
"failure_command" => nil,
"failure_actions" => nil,
"failure_delay" => 0,
"failure_flag" => nil,
"service_name" => nil,
"host" => nil,
"delayed_start" => false,
Expand Down Expand Up @@ -579,7 +583,7 @@ def self.configure(options = {})
end

if opts["failure_reset_period"] || opts["failure_reboot_message"] ||
opts["failure_command"] || opts["failure_actions"]
opts["failure_command"] || opts["failure_actions"] || !opts["failure_flag"].nil?
configure_failure_actions(handle_scs, opts)
end
ensure
Expand Down Expand Up @@ -1397,6 +1401,18 @@ def self.configure_failure_actions(handle_scs, opts)
close_service_handle(handle_scs)
raise SystemCallError.new("ChangeServiceConfig2", error)
end

unless opts["failure_flag"].nil?
sfaf = SERVICE_FAILURE_ACTIONS_FLAG.new
sfaf[:fFailureActionsOnNonCrashFailures] = opts["failure_flag"] ? 1 : 0
bool = ChangeServiceConfig2(
handle_scs,
SERVICE_CONFIG_FAILURE_ACTIONS_FLAG,
sfaf
)

FFI.raise_windows_error("ChangeServiceConfig2") unless bool
end
end

# Returns a human readable string indicating the action type.
Expand Down
6 changes: 6 additions & 0 deletions lib/win32/windows/structs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@ class SERVICE_FAILURE_ACTIONS < FFI::Struct
)
end

class SERVICE_FAILURE_ACTIONS_FLAG < FFI::Struct
layout(
:fFailureActionsOnNonCrashFailures, :int
)
end

class SERVICE_TABLE_ENTRY < FFI::Struct
layout(
:lpServiceName, :pointer,
Expand Down
2 changes: 1 addition & 1 deletion lib/win32/windows/version.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module Win32
class Service
VERSION = "2.3.2".freeze
VERSION = "2.3.2sf".freeze
MAJOR, MINOR, TINY = VERSION.split(".")
end
end