I'm new to D and I'm writing a simple multithreaded server for practice. A common paradigm for starting client handler threads in C is to pass the file descriptor of the newly-accept()ed socket into pthread_create(), but D's std.concurrency.spawn() will not allow me to pass the Socket because it's mutable and accessible by two threads.
Of course, I don't actually want an immutable socket (which is why I don't really want to cast it in the main thread unless I have to) - I want to pass a mutable one in and have it go out of scope in the main thread. How would I go about this? Should(/can) I use tid.send(s)
to let the thread use the socket? For some reason that seems very clunky to me.
My code now:
void main() {
Socket listener = new TcpSocket;
...
for (;;) {
Socket s = listener.accept();
scope(exit) s.close();
auto tid = spawn(&clientHandler, s);
}
}
void clientHandler(Socket s) {
...
}
Which produces: Error: static assert "Aliases to mutable thread-local data not allowed." ... instantiated from here: spawn!(Socket)
you need to cast the socket to shared and back again in the clienthandler
auto tid = spawn(&clientHandler, cast(shared) s);
void clientHandler(shared Socket s) {
Socket sock = cast(Socket)s;
scope(exit)sock.close();
}
the reason for this is that all local variables are implicitly thread local unless specified shared
, and only references to shared or immutable can be passed as argument to spawn
(or send
) while stuff passed by value (structs without references and primitives) is fine
also you should put the close int the handler as with your current implementation the socket will likely be closed before the newly spawned thread has a chance to run
The problem here isn't the socket, which is a local variable. It's the clientHandler, whose declaration you haven't shown, but clearly it is thread-local as it says in the error message, when there should be a new one per accepted socket. The hint is the word 'alias', which refers to the & operator.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With