2

When sending a Message to a stopped vibe.d Task, the application gets an segmentation fault. I did not expect the message to be delivered, but to get notified about the failed sending attempt (or at least not to crash).

The following example illustrates this Problem.

import std.stdio;
import core.thread;
import vibe.core.core;
import vibe.core.concurrency;

static this() {
    Task t = runTask({
        writeln("Hi");
    });
    t.join;
    t.send(42);
    writeln("Bye");
}

When running the code above, the output is:

Hi
Program exited with code -11

... instead of:

Hi
Bye

The callstack looks like this.

#0  0x00007ffff6dbd346 in std.concurrency.MessageBox.put(ref std.concurrency.Message) ()
   from /usr/lib64/libphobos2.so.0.71
#1  0x000000000051b0b3 in std.concurrency._send!(int)._send(std.concurrency.MsgType, std.concurrency.Tid, int) (_param_2=42, tid=..., type=<incomplete type>)
    at /opt/dmd-2.071/import/std/concurrency.d:640
#2  0x000000000051b06d in std.concurrency._send!(int)._send(std.concurrency.Tid, int) (
    _param_1=42, tid=...) at /opt/dmd-2.071/import/std/concurrency.d:629
#3  0x000000000051b04b in std.concurrency.send!(int).send(std.concurrency.Tid, int) (
    _param_1=42, tid=...) at /opt/dmd-2.071/import/std/concurrency.d:605
#4  0x000000000051b027 in vibe.core.concurrency.send!(int).send(vibe.core.task.Task, int) (
    _param_1=42, task=...)
    at /home/user/.dub/packages/vibe-d-0.7.30/vibe-d/source/vibe/core/concurrency.d:1239
#5  0x0000000000517b6b in app._staticCtor1() () at /tmp/test/source/app.d:11
...
  • How could the segfault be prevented? Are there checking send functions? How could this be patched in vibe.d or phobos2?
  • Is it a bug of vibe.d or phobos2?
Skruppy
  • 63
  • 6

1 Answers1

0

Task has a running property that you could use. I believe it's intended behavior, as error-handling generally should be on application level, not library level.

import std.stdio;
import core.thread;
import vibe.core.core;
import vibe.core.concurrency;

static this() {
    Task t = runTask({
        writeln("Hi");
    });
    t.join;

    if (t.running) {
        t.send(42);
    }

    writeln("Bye");
}
Bauss
  • 2,767
  • 24
  • 28
  • do you also have an idea what to do when I only have the `Tid` of a `Task`? – Skruppy Nov 19 '16 at 15:21
  • Unfortunately I can't see any way to retrieve a task by a tid through the api documentation. It could be my lack of vibe.d knowledge though. Is there no way for you to save the task rather than the tid? And about thread-safety it really depends on how you use it and what safety we're talking. Are we talking synchronization-wise, race-condition wise or what? There's a lot of things that plays a role in thread-safety in general. It should work fine as long as you don't attempt to check if it's running elsewhere and just sends the state around. – Bauss Nov 21 '16 at 07:12