Large (>32 byte) concurrency messages
JR
zorael at gmail.com
Thu Aug 8 13:08:08 PDT 2013
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
More information about the Digitalmars-d-learn
mailing list