lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


> > So you could accept connections in a given Lua state and process it in a
> > different one. Be it by means of using Lanes, LuaProc, or whatever suits
> > you.
> 
> The above doesn't answer the OP's question of how
> 
> fd = ssock:acceptfd()
> 
> is different from
> 
> fd = ssock:accept():getfd()
> 
> It might be that the problem is that the accepted userdata will close
> the underlying fd in it's __gc().
> 
> If true, acceptfd() might be better replaced with a method of
> relinquishing ownership.

There is currently no way that I know of to make luasocket work
corrently for this behavior.
getfd and setfd are not good enough for that (as Diego says they
were made for debugging mainly).

When you do ssock:accept():getfd() you risk getting the fd closed
by the GC as you said, but that is not all.
Then you must use that fd somehow, so you try to do:
s = socket.tcp()
s:setfd(fd)
data = s:recieve()

But then receive complains that s is of type tcp{master} instead
of tcp{client}. Also, socket.tcp() does actually create a fd when
called, not when :connect() or :bind() are called.
This means when you do 
s = socket.tcp()
s:setfd(fd)
You actually get a "loose" fd, which is terrible if your application
must handled hundreds or thousands of connections per minutes,
you run VERY quickly into the OS fd limit.
So you could use a small C lib to implement the OS close(fd) call
then do socket.tcp(), getfd() on it to close it, then setfd(fd).
This is not exactly intuitive.

And anyway since socket.tcp() makes the object a tcp{master} it
does not work anyway.
To get it to work the only way is to do a "fake" connect() call to
a port you know will not respond to change the class to tcp{client}.
Like in this example:
s = socket.tcp()
s:connect("127.0.0.1", 12312)
myclose(s:getfd())
s:setfd(fd)
data = s:recieve()

This is extremely clunky and requires a C module that implements the OS 
close() call otherwise you get lost fds.

I believe making threaded socket servers is a quite basic and common
problem and thus this "solution" is not workable with it.
Lanes is a really nice threading module, I like it a lot, but the
inability to do network based stuff with it is annoying as hell,
so as long as we do not get native threading in a single lua state
we must find a workaround.

> Now, if what we are talking about functionality that allows
> you to obtain this OS-dependent socket handle/descriptor and
> create another LuaSocket object from it, we can discuss what
> is the best API for it. It is a valid scenario that I had
> not foreseen, and I'd be happy to add it to the library.

I do agree my patch is probably not the best or most beautiful,
I did it only to resolve my problem, and it seems it is not only
my problem :) But yes I do not code, nor care much I must confess,
for Windows and a solution for it would be desirable too.

However if windows does not use integer fds for its handles I am not
sure it would work anyway. Can Lanes Lindas transfer something like that
between states ? It only works for unix because fds are ints and so
are transported just fine with Lindas.

Maybe luasocket could keep an internal global list of all openned sockets
with the fd/handle/... they refer to in the OS and then the multiple lua 
states could all use some luasocket API to access it via a simple number.
But this would mean to make the global list threading resistant which is
probably out of the scope of luasocket (and also an extremely ugly solution..)

Well I guess I have written enough or too much already, good luck to
those that read all of my bad english :)