1 /** 2 An implemention of a Queue. 3 4 This Queue is thread safe (and block-free) to have separate threads reading and writing asynchronously. The Queue is NOT safe to have multiple threads reading or writing at the same time. i.e. A single thread can read while another single thread is writing. 5 If you want to have mutiple threads reading or writing data from queue the threads will need to be sure to block themself. 6 7 To Create a queue 8 --- 9 Queue!string queue; // Replace string with data type that values should be. 10 --- 11 12 To add to queue 13 --- 14 queue.put("This is a value that is added to queue!"); // Argument should be of oppropriate type. 15 --- 16 17 To read data 18 --- 19 foreach (string value; queue) { 20 // Deal with value here! 21 } 22 --- 23 24 To read data safe to have multiple threads reading 25 --- 26 synchronized { 27 foreach (string value; queue) { 28 // Deal with value here! 29 } 30 } 31 --- 32 or 33 --- 34 while (true) { 35 string value; 36 synchronized { 37 if (queue.empty) { 38 break; 39 } 40 value = queue.front; 41 queue.popFront; 42 } 43 // Deal with value here! 44 } 45 --- 46 47 Examples: 48 --- 49 Queue!string queue; 50 51 queue.add("A!"); 52 queue.add("BBB!"); 53 queue.add("CC!"); 54 55 foreach (string value; queue) { 56 writeln(value); 57 } 58 59 queue.add("DDDDD!"); 60 queue.add("EEEE!"); 61 62 foreach (string value; queue) { 63 writeln(value); 64 } 65 --- 66 */ 67 68 module queue; 69 70 import core.atomic : atomicOp; 71 ////import core.sync.semaphore : Semaphore; 72 73 class Queue(T) { 74 75 //private struct HeadNode { 76 // Node* _first; 77 //} 78 private struct Node { 79 T payload; 80 Node* next; 81 } 82 83 private Node* _first; 84 private Node* _last = new Node; 85 shared private int count = 0; 86 87 this() { 88 this._first = this._last; 89 } 90 91 /** Add to the Queue (to the end). 92 */ 93 void put(T value) { 94 Node* newLast = new Node; 95 this._last.payload = value; 96 this._last.next = newLast; 97 this._last = newLast; 98 99 count.atomicOp!("+=")(1); 100 } 101 102 103 /** To be iterable with `foreach` loop. 104 */ 105 bool empty() { 106 return this.count == 0; 107 ////return _head._first == null; 108 } 109 110 /// ditto 111 void popFront() { 112 assert (!this.empty); 113 this._first = this._first.next; 114 count.atomicOp!("-=")(1); 115 } 116 117 ///ditto 118 T front() { 119 assert (!this.empty); 120 return this._first.payload; 121 ////} 122 ////else { 123 //// return null; 124 ////} 125 } 126 127 } 128 129 130 131 ////void main(){ 132 //// import core.thread; 133 //// import std.stdio; 134 //// class ThreadInput : Thread { 135 //// private Queue!string queue; 136 //// 137 //// this(Queue!string queue) { 138 //// super(&run); 139 //// this.queue = queue; 140 //// } 141 //// 142 //// private void run() { 143 //// while (true) { 144 //// queue.put(readln); 145 //// } 146 //// } 147 //// } 148 //// Queue!string inputQueue = new Queue!string; 149 //// ThreadInput threadInput = new ThreadInput(inputQueue); 150 //// threadInput.start; 151 //// 152 //// while (true) { 153 //// foreach (string value; inputQueue) { 154 //// writeln(value); 155 //// } 156 //// } 157 //// 158 //// 159 //// 160 ////}