1 module unit_threaded.writer_thread; 2 3 import unit_threaded.io; 4 import std.concurrency; 5 import std.stdio; 6 import std.conv; 7 8 9 package void utWrite(T...)(T args) { 10 WriterThread.get().write(args); 11 } 12 13 package void utWriteln(T...)(T args) { 14 WriterThread.get().writeln(args); 15 } 16 17 package void utWritelnGreen(T...)(T args) { 18 WriterThread.get().writelnGreen(args); 19 } 20 21 package void utWritelnRed(T...)(T args) { 22 WriterThread.get().writelnRed(args); 23 } 24 25 26 /** 27 * Thread to output to stdout 28 */ 29 class WriterThread { 30 static WriterThread get() { 31 if(!_instantiated) { 32 synchronized { 33 if (_instance is null) { 34 _instance = new WriterThread; 35 } 36 _instantiated = true; 37 } 38 } 39 return _instance; 40 } 41 42 void write(T...)(T args) { 43 _tid.send(text(args)); 44 } 45 46 void writeln(T...)(T args) { 47 write(args, "\n"); 48 } 49 50 void writelnGreen(T...)(T args) { 51 _tid.send(green(text(args) ~ "\n")); 52 } 53 54 void writelnRed(T...)(T args) { 55 _tid.send(red(text(args) ~ "\n")); 56 } 57 58 void join() { 59 _tid.send(thisTid); //tell it to join 60 receiveOnly!Tid(); //wait for it to join 61 } 62 63 private: 64 65 this() { 66 _tid = spawn(&threadWriter); 67 } 68 69 Tid _tid; 70 71 static bool _instantiated; // Thread local 72 __gshared WriterThread _instance; 73 } 74 75 private void threadWriter() { 76 auto done = false; 77 Tid tid; 78 79 auto saveStdout = stdout; 80 auto saveStderr = stderr; 81 82 if(!isDebugOutputEnabled()) { 83 stdout = File("/dev/null", "w"); 84 stderr = File("/dev/null", "w"); 85 } 86 87 while(!done) { 88 string output; 89 receive( 90 (string msg) { 91 output ~= msg; 92 }, 93 (Tid i) { 94 done = true; 95 tid = i; 96 }, 97 (OwnerTerminated trm) { 98 done = true; 99 } 100 ); 101 saveStdout.write(output); 102 } 103 saveStdout.flush(); 104 stdout = saveStdout; 105 stderr = saveStderr; 106 if(tid != Tid.init) tid.send(thisTid); 107 }