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.

As you can see, I've hacked around it by grabbing the handle and recreating
the Socket instance in the handler (line 14). The problem, however, is that
this can only assume a single type in AddressFamily. Honestly, I will
probably only need INET, INET6, or UNIX (which can be set in a global), but
this sounds a bit hacky to me.

I was able to hack around the problem for libev structs, because creating a
new instance returns a pointer, which can be assigned somewhere else to be
garbage collected later. This doesn't seem to be the case for classes,
however.

Initially, I solved this before by having a global Socket[] and adding
sockets to it as I received them, but this was an even worse hack to get
around the GC (see previous version in version control if interested). This
did, however, allow me to get a reference from the array to assign to the
data value (a void*), where it could be retrieved in the callback.

Are there any other options that I've missed that would make this cleaner
and more general?

Also, I'd be interested if someone notices some badness in my code that
could lead to nasty side-effects. I'm trying to make this example pretty
robust in terms of cleaning up after myself and doing things correctly.

Thanks so much!!

Reply via email to