I'm working on an IRC bot as my pet project. I do know of Dirk[1]; I'm mostly doing this to learn the language.

For the sake of the argument, imagine three threads; one that reads from the socketstream of the socket connected to the IRC server, one Mediator that keeps track of what other threads and/or functions are interested in different IRC events (joins, parts, channel messages, ...), and one that simply wants to receive stuff to print to the screen.

The flow of events would go like this:
1. the 'reading' thread gets a raw string from the server
2. ...and passes it as a concurrency message to the Mediator
3. the Mediator receives it
4. ...and does serious regex voodoo to produce an IrcEvent struct, with various members detailing what type of event it was (again join, parts, ...), from and to whom, textual content if applicable, etc 5. the Mediator sends the struct as a concurrency message to our printing thread
6. ...which receives and prints it.
7. GOTO 1

The first concurrency message passed is a string, which works as expected. The second message is the translated struct of over 32 bytes in size (96 to be exact), and that's where things start breaking.

Passing by value, e.g. tid.send(eventStruct);
core.exception.AssertError@/usr/include/d/4.8/std/variant.d(280): target must be non-null

Passing by immutable, e.g. tid.send(cast(immutable) eventStruct);
/usr/include/d/4.8/std/variant.d:552: Error: cannot modify immutable expression *p /usr/include/d/4.8/std/concurrency.d:111: Error: template instance std.variant.VariantN!(32LU).VariantN.opAssign!(immutable(IrcEvent)) error instantiating

Passing an immutable pointer *initially* works, but then you get a race to finish using the struct before the scope it was declared in ends. (It's not on the heap.)
received *(immutable(IrcEvent*)): immutable(IrcEvent)(UNSET, x"F0 30 E2 DA FF 7F 00 00 80 96 98 00 00 00 00 00 80 DF 9F 64 D2 7F 00 00 F0 30 E2 DA FF 7F 00 00 [...] Segmentation fault

From gdb;
The value of '_param_1.sender' is a struct/class of type 'struct string' with the following fields:

 length = 4409885 .. (Value of type 'ulong')
    ptr = <Enter 1 to explore this field of type 'const char *'>

Enter the field number of choice: 1
'(_param_1.sender).ptr' is a pointer to a value of type 'const char'
Continue exploring it as a pointer to a single value [y/n]: y
'(_param_1.sender).ptr' a pointer pointing to an invalid memory location.


I put together http://dpaste.dzfl.pl/d7322971 earlier to demonstrate some of these errors, though I didn't mention the raciness of passing pointers there. To test that race I used http://dpaste.dzfl.pl/e6fd4569.


Are there any easy workarounds? Do people use std.concurrency, or is it largely avoided? Variant also seems to have some major issues... or maybe everything is caused by Variant and std.concurrency just exposes it.

I hit a wall here. :< Would love any tips or tricks you could spare!


[1]: https://github.com/JakobOvrum/Dirk

Reply via email to