1 /++ 2 Signal handling 3 +/ 4 module socketplate.signal; 5 6 import core.thread : Thread; 7 import socketplate.log; 8 import std.string : format; 9 10 alias SignalFunc = void delegate(int) nothrow @nogc; 11 12 /// 13 void setupSignalHandlers(SignalFunc handler) @safe 14 in (handler !is null) 15 { 16 logTrace(format!"Setting up signal handlers for thread: 0x%X"(Thread.getThis().id)); 17 _onSignal = handler; 18 19 version (Posix) 20 { 21 import core.sys.posix.signal; 22 23 () @trusted { 24 signal(SIGINT, &_socketplate_posix_signal_handler); 25 signal(SIGTERM, &_socketplate_posix_signal_handler); 26 }(); 27 } 28 else 29 { 30 version (Windows) 31 { 32 // TODO 33 // SetConsoleCtrlHandler(…); 34 logError("ConsoleCtrlHandler not implemented yet"); 35 } 36 else 37 { 38 logError( 39 "Signal handlers either not available on or implemented for this platform." 40 ); 41 } 42 } 43 } 44 45 /// 46 void forwardSignal(int signal, Thread[] threads) @safe nothrow @nogc 47 { 48 foreach (thread; threads) 49 forwardSignal(signal, thread); 50 } 51 52 /// 53 void forwardSignal(int signal, Thread thread) @safe nothrow @nogc 54 { 55 version (Posix) 56 { 57 import core.sys.posix.pthread; 58 59 immutable bool isRunning = () @trusted { return thread.isRunning(); }(); 60 if (!isRunning) 61 return; 62 63 pthread_t threadID; 64 try 65 threadID = thread.id; 66 catch (Exception) 67 return; 68 69 () @trusted { pthread_kill(threadID, signal); }(); 70 } 71 else 72 { 73 logError("Signal forwarding not implemented on this platform"); 74 } 75 } 76 77 private 78 { 79 version (Posix) 80 { 81 // thread local signal handler 82 static SignalFunc _onSignal = null; 83 84 extern (C) void _socketplate_posix_signal_handler(int signal) nothrow @nogc 85 { 86 if (_onSignal is null) 87 return; 88 89 return _onSignal(signal); 90 } 91 } 92 }