On 3/6/2012 2:01 PM, Mike Parker wrote:
On 3/6/2012 1:55 PM, Mike Parker wrote:
On 3/6/2012 1:34 PM, Tyler Jameson Little wrote:
I've been playing with libev in D lately, and I've run into a problem.
I've been able to hack around it, but it'd like to find a better, more
general solution. Here's a link to the code:

https://github.com/beatgammit/fun-with-d/blob/master/libev/tcp_server.d

The code is a basic TCP server that responds to connections in a
non-blocking fashion. It's not perfect, and the current problem I'm
trying to solve is how to get my Socket instance (from accept) to the
handler. Since everything is asynchronous, and the return value of
accept() will get lost (garbage collected, I think). When I try to get
the address of it, the compiler complains that it's not an lvalue.

Socket instance returned by accept won't be garbage collected (or lost)
as long as you have a reference to it active somewhere in your program.
It doesn't matter which thread. Just take the return value of accept and
pass it to your handler as is. As long as your handler holds on to the
reference, you're fine. No need to try and get the address, or hack
around it.

Ah, sorry. Never mind. I misunderstood the problem.

I suggest you keep an associative array of Sockets, using req.handle as
a key. Then, your code becomes this:

// The map
Socket[socket_t] sockets;

// in connection_cb
auto req = server.accept();
sockets[req.handle] = req;

// then in socket_watcher_cb
auto req = sockets[w.fd];


Alternatively:

struct Wrapper
{
 Socket s;
 this(Socket s)
 {
    this.s = s;
 }
}

// in connection_cb
auto req = server.accept();
auto wrapper = new Wrapper(req);

Then assign the wrapper instance to the data pointer you mentioned.


Reply via email to