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 version(Posix) { 84 enum nullFileName = "/dev/null"; 85 } else { 86 enum nullFileName = "NUL"; 87 } 88 89 stdout = File(nullFileName, "w"); 90 stderr = File(nullFileName, "w"); 91 } 92 93 while(!done) { 94 string output; 95 receive( 96 (string msg) { 97 output ~= msg; 98 }, 99 (Tid i) { 100 done = true; 101 tid = i; 102 }, 103 (OwnerTerminated trm) { 104 done = true; 105 } 106 ); 107 saveStdout.write(output); 108 } 109 saveStdout.flush(); 110 stdout = saveStdout; 111 stderr = saveStderr; 112 if(tid != Tid.init) tid.send(thisTid); 113 }