1 /** 2 * ae.sys.process 3 * 4 * License: 5 * This Source Code Form is subject to the terms of 6 * the Mozilla Public License, v. 2.0. If a copy of 7 * the MPL was not distributed with this file, You 8 * can obtain one at http://mozilla.org/MPL/2.0/. 9 * 10 * Authors: 11 * Vladimir Panteleev <vladimir@thecybershadow.net> 12 */ 13 14 module ae.sys.process; 15 16 version(Posix): 17 18 import ae.net.sync; 19 import ae.sys.signals; 20 21 import std.process; 22 23 /// Asynchronously wait for a process to terminate. 24 void asyncWait(Pid pid, void delegate(int status) dg) 25 { 26 auto anchor = new ThreadAnchor; 27 28 void handler() nothrow @nogc 29 { 30 anchor.runAsync( 31 { 32 // Linux may coalesce multiple SIGCHLD into one, so 33 // we need to explicitly check if our process exited. 34 auto result = tryWait(pid); 35 if (result.terminated) 36 { 37 removeSignalHandler(SIGCHLD, &handler); 38 dg(result.status); 39 } 40 }); 41 } 42 43 addSignalHandler(SIGCHLD, &handler); 44 } 45 46 version(unittest) import ae.sys.timing, ae.net.asockets; 47 48 unittest 49 { 50 string order; 51 52 auto pid = spawnProcess(["sleep", "1"]); 53 asyncWait(pid, (int status) { assert(status == 0); order ~= "b"; }); 54 setTimeout({ order ~= "a"; }, 500.msecs); 55 setTimeout({ order ~= "c"; }, 1500.msecs); 56 socketManager.loop(); 57 58 assert(order == "abc"); 59 }