Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Aliases to mutable thread-local data not allowed

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)

like image 935
Dan Avatar asked Jan 18 '13 08:01

Dan


2 Answers

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

like image 65
ratchet freak Avatar answered Sep 28 '22 07:09

ratchet freak


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.

like image 41
user207421 Avatar answered Sep 28 '22 09:09

user207421