How to implement Canceleable spawn() from parent

Stanislav Blinov stanislav.blinov at gmail.com
Sun Jun 28 14:23:01 UTC 2020


On Sunday, 28 June 2020 at 13:29:08 UTC, aberba wrote:

> Getting error:
>
> Error: template std.concurrency.spawn cannot deduce function 
> from argument types !()(void delegate(Tid id) @system, Tid), 
> candidates are:
> /usr/include/dmd/phobos/std/concurrency.d(460,5):        
> spawn(F, T...)(F fn, T args)
>   with F = void delegate(Tid) @system,
>        T = (Tid)
>   must satisfy the following constraint:
>        isSpawnable!(F, T)


The error you're getting is because you're passing a pointer to a 
delegate instead of a delegate.

>     Tid id = spawn(&worker, milliseconds, &callback);
                                             ^ here

But fixing that still won't compile, because when you want to 
pass a delegate to `spawn`, it needs to be a shared delegate.

If I understood your intent correctly, here's how you can do it:

import std.stdio : writeln;
import std.concurrency;
import core.thread.osthread : Thread;
import std.datetime.stopwatch;

auto setInterval(long milliseconds, void function() callback)
{
     static void worker(Duration d, void function() cb)
     {
         writeln("Starting ", thisTid, "...");

         bool done = false;

         StopWatch sw;
         sw.start;
         while (true)
         {
             // wait for messages for a timespan of at least `d`
             receiveTimeout(
                 d,
                 (string text) {
                    writeln("Received string: ", text);
                    if (text == "cancel")
                        done = true;
                });

             if (done)
                 break;

             // a non-cancelling message might've been received 
before timeout,
             // so test if it's really time for the callback
             if (sw.peek >= d)
             {
                 cb();
                 sw.reset;
             }
         }
     }

     Tid id = spawn(&worker, milliseconds.msecs, callback);

     return id;
}

void stopInterval(Tid tid) {
     send(tid, "cancel");
}

void main()
{
     auto tid = setInterval(1000, { writeln("tick"); });
     Thread.sleep(2.seconds);
     send(tid, "not cancel");
     Thread.sleep(5.seconds);
     stopInterval(tid);
}


More information about the Digitalmars-d-learn mailing list