Skip to content

Instantly share code, notes, and snippets.

@madprog
Created March 25, 2015 09:40
Show Gist options
  • Save madprog/0cbfd83b6ae64c4f7d29 to your computer and use it in GitHub Desktop.
Save madprog/0cbfd83b6ae64c4f7d29 to your computer and use it in GitHub Desktop.
Signal handling in haxe
package;
import tools.Signal;
class Main
{
public static function main():Void
{
var isRunning:Bool = true;
Signal.onInterrupt(function ():Void { isRunning = false; });
while (isRunning)
{
Sys.sleep(100);
}
trace("Exited cleanly!");
}
}
package tools;
#if linux
@:headerCode("#include <csignal>")
@:cppFileCode("
void _handler(int sig)
{
::tools::Signal_obj::handle(sig);
}
")
#elseif windows
@:headerCode("#include <windows.h>")
@:cppFileCode("
BOOL WINAPI _handler(DWORD sig)
{
::tools::Signal_obj::handle(sig);
return TRUE;
}
")
#end
/**
* Handle system signals
*
* @author Paul Morelle <[email protected]>
*/
class Signal
{
/**
* Store for the registered handlers, classified by signal code.
*/
private static var _handlers:Map<Int, Array<Void->Void>> = new Map<Int, Array<Void->Void>>();
#if windows
/**
* Will be set to true to track if the ConsoleCtrlHandler
* has already been set by us for this process.
*/
private static var _handle_set:Bool = false;
#end
/**
* Called when a signal was received
*
* Will call each signal handler in the order of registration
*/
@:keep
private static function handle(signal:Int)
{
if (_handlers.exists(signal))
{
for (handler in _handlers.get(signal))
{
handler();
}
}
else
{
throw ("Caught unhandled signal " + signal);
}
}
/**
* Register a new handler for a given signal
*/
@:keep
private static function onSignal(signal:Int, handler:Void->Void)
{
if (!_handlers.exists(signal))
{
#if linux
untyped __cpp__("::signal(signal, &_handler);");
#end
_handlers.set(signal, new Array<Void->Void>());
}
_handlers[signal].push(handler);
}
/**
* Add a handler for keyboard interrupts (Ctrl+C)
*/
public static function onInterrupt(handler:Void->Void)
{
#if linux
untyped __cpp__("onSignal(SIGINT, handler)");
#elseif windows
_handle_set = true;
untyped __cpp__("onSignal(CTRL_C_EVENT, handler)");
if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)ConsoleHandler, TRUE)) {
fprintf(stderr, "Unable to install handler!\n");
return EXIT_FAILURE;
}
#end
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment