Search code examples
multithreadingconcurrencydnonblocking

Non-blocking concurrent message receive


Is there a standard function to receive messages concurrent, but non-blocking? It seems like all the functions available in std.concurrency are blocking and the closest I found to something that is non-blocking is receiveTimeout however it still waits until the timeout. I would like it to return immediately if there are no messages passed to the thread.

Here is what I came up with using receiveTimeout.

module main;

import std.concurrency;
import std.stdio : writefln, readln;
import core.time;
import core.thread;

void spawnedFunc() {
    while (true) {
        receiveTimeout(
            dur!("nsecs")(1),
            (int i) { writefln("Received %s", i); }
        );
        Thread.sleep(dur!("msecs")(100));
    }
}

void main() {
    auto tid = spawn(&spawnedFunc);
    while (true) {
        readln();
        send(tid, 42);
    }
}

Update:

Is my best bet a function like this?

void receiveNonBlocking(T...)(T ops) {
    receiveTimeout(
        dur!("nsecs")(1),
        ops
    );
}

...

receiveNonBlocking(
    (int i) { writefln("Received %s", i); }
);

Solution

  • Looking at implementation of receiveTimeout:

    if( period.isNegative || !m_putMsg.wait( period ) )
        return false;
    

    So, providing negative timeout, e.g. nsecs(-1), is the best choice here. And it wouldn't really impact performance, since implementation of non blocking function wouldn't be much different from current one with timeout. Just one more if check to execute before exit for function with negative timeout.