Created
March 25, 2015 09:40
-
-
Save madprog/0cbfd83b6ae64c4f7d29 to your computer and use it in GitHub Desktop.
Signal handling in haxe
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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!"); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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