<div dir="ltr"><div>So I'm porting so #golang code to #dlang and there is all these blasted "go" statements.So I thought I'd give implmenting it in D a shot. What do you guys think?<br>Fire away :).<br><br>
import std.stdio;<br>import core.thread : Thread;<br>import core.sync.mutex : Mutex;<br>import core.time;<br><br>void main() {<br> auto ch = chan!int(1);<br> go!({<br> foreach (i; 22..44) {<br> ch._ = i;<br>
} });<br><br> foreach (i; 0..10) {<br> writeln("pop: ", ch._);<br> }<br>}<br><br></div>// Implementation<br><br>void go(alias F)() {<br> auto t = new Thread(F);<br> t.isDaemon(true); // we don't care if this thread dies.<br>
t.start();<br>}<br><br>/**<br> * chan allows messaging between threads without having to deal with locks, similar to how chan works in golang<br> */<br>class chan_(T) {<br> shared Mutex lock;<br> struct Container(T) {<br>
T value;<br> Container!T* next;<br> }<br> shared Container!T* buf;<br> shared Container!T* last;<br> shared size_t length;<br> shared void insert(shared T v) {<br> shared Container!T* newItem = new shared Container!T();<br>
newItem.value = v;<br> if (buf is null) {<br> buf = newItem;<br> last = newItem;<br> } else {<br> last.next = newItem;<br> last = newItem;<br> }<br>
length++;<br> }<br> shared T popFront() {<br> T ret;<br> synchronized (lock) {<br> ret = buf.value;<br> buf = buf.next;<br> length--;<br> }<br> return ret;<br>
}<br> size_t maxItems;<br> bool blockOnFull = false;<br> this(int maxItems = 1024, bool blockOnFull = true) {<br> lock = cast(shared)new Mutex;<br> length = 0;<br><br> this.maxItems = maxItems;<br>
this.blockOnFull = blockOnFull;<br> }<br><br> @property<br> shared void _(T value) {<br> bool done;<br> while(true) {<br> synchronized(lock) {<br> if (!done && length < maxItems) {<br>
insert(value);<br> done = true;<br> } else if (!blockOnFull) {<br> throw new ChannelFull("Channel Full");<br> }<br> if (length <= maxItems-1) {<br>
break;<br> }<br> }<br> Thread.sleep(dur!"msecs"(5));<br> }<br> }<br> @property<br> shared T _() {<br> while(true) {<br> size_t len;<br>
synchronized(lock) {<br> len = length;<br> }<br> if (len > 0) {<br> break;<br> }<br> Thread.sleep(dur!"msecs"(5));<br> };<br>
auto r = popFront();<br> return r;<br> }<br>}<br>auto chan(T)(int n, bool blockOnFull = true) {<br> return cast(shared)new chan_!T(n, blockOnFull);<br>}<br><br>class ChannelFull : Exception {<br> this(string msg, string file = __FILE__, ulong line = cast(ulong)__LINE__, Throwable next = null) {<br>
super(msg,file,line,next);<br> }<br>}<br><br></div>