Change. socket:setfd() set fd to invalid value.

Change. socket:setfd return previews `fd` value.
Change. socket.tcp and socket.udp can create object based on `fd`.

Add. test setfd
```lua
  ---- server
  cli = assert(srv:accept())
  -- test if worker thread take ownership and clear `fd`
  if run_worker_thread(cli:getfd()) then cli:setfd() end
  cli:close()

  ---- worker
  -- wrap raw `fd` to socket object
  local sock = socket.tcp(..., "client")
  -- do work with sock object
```
This commit is contained in:
moteus 2013-06-10 12:05:34 +04:00
parent c0a73370eb
commit 3520727490
3 changed files with 60 additions and 7 deletions

View File

@ -171,8 +171,11 @@ static int meth_getfd(lua_State *L)
static int meth_setfd(lua_State *L) static int meth_setfd(lua_State *L)
{ {
p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
tcp->sock = (t_socket) luaL_checknumber(L, 2); t_socket fd = tcp->sock;
return 0; if(lua_gettop(L) == 1) tcp->sock = SOCKET_INVALID;
else tcp->sock = (t_socket) luaL_checknumber(L, 2);
lua_pushnumber(L, (int) fd);
return 1;
} }
static int meth_dirty(lua_State *L) static int meth_dirty(lua_State *L)
@ -356,14 +359,24 @@ static int meth_settimeout(lua_State *L)
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/
static int tcp_create(lua_State *L, int family) { static int tcp_create(lua_State *L, int family) {
t_socket sock; t_socket sock;
const char *err = inet_trycreate(&sock, family, SOCK_STREAM); const char *err;
const int is_inherite = lua_isnumber(L,1);
const char *obj_type = "tcp{master}";
if (is_inherite){
err = NULL;
sock = (t_socket)lua_tonumber(L, 1);
if(strstr(luaL_optstring(L,2,""),"client"))
obj_type = "tcp{client}";
}
else
err = inet_trycreate(&sock, family, SOCK_STREAM);
/* try to allocate a system socket */ /* try to allocate a system socket */
if (!err) { if (!err) {
/* allocate tcp object */ /* allocate tcp object */
p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp));
memset(tcp, 0, sizeof(t_tcp)); memset(tcp, 0, sizeof(t_tcp));
/* set its type as master object */ /* set its type as master object */
auxiliar_setclass(L, "tcp{master}", -1); auxiliar_setclass(L, obj_type, -1);
/* initialize remaining structure fields */ /* initialize remaining structure fields */
socket_setnonblocking(&sock); socket_setnonblocking(&sock);
if (family == PF_INET6) { if (family == PF_INET6) {

View File

@ -284,8 +284,11 @@ static int meth_getfd(lua_State *L) {
/* this is very dangerous, but can be handy for those that are brave enough */ /* this is very dangerous, but can be handy for those that are brave enough */
static int meth_setfd(lua_State *L) { static int meth_setfd(lua_State *L) {
p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
udp->sock = (t_socket) luaL_checknumber(L, 2); t_socket fd = udp->sock;
return 0; if(lua_gettop(L) == 1) udp->sock = SOCKET_INVALID;
else udp->sock = (t_socket) luaL_checknumber(L, 2);
lua_pushnumber(L, (int) fd);
return 1;
} }
static int meth_dirty(lua_State *L) { static int meth_dirty(lua_State *L) {
@ -408,7 +411,14 @@ static int meth_setsockname(lua_State *L) {
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/
static int udp_create(lua_State *L, int family) { static int udp_create(lua_State *L, int family) {
t_socket sock; t_socket sock;
const char *err = inet_trycreate(&sock, family, SOCK_DGRAM); const char *err;
const int is_inherite = lua_isnumber(L,1);
if (is_inherite){
err = NULL;
sock = (t_socket)lua_tonumber(L, 1);
}
else
err = inet_trycreate(&sock, family, SOCK_DGRAM);
/* try to allocate a system socket */ /* try to allocate a system socket */
if (!err) { if (!err) {
/* allocate udp object */ /* allocate udp object */

30
test/test_setfd.lua Normal file
View File

@ -0,0 +1,30 @@
local socket = require "socket"
local host, port = "127.0.0.1", "5462"
local srv = assert(socket.bind(host, port))
local sock_cli = socket.tcp()
assert(sock_cli:connect(host, port))
local fd do
local sock_srv = assert(srv:accept())
fd = assert(sock_srv:getfd())
assert(not pcall(function() sock_srv:setfd(nil) end))
sock_srv:setfd()
assert(sock_srv:close())
end
local sock_srv = assert(socket.tcp(fd, "client"))
collectgarbage"collect"
collectgarbage"collect"
assert(5 == assert(sock_srv:send("hello")))
assert("hello" == assert(sock_cli:receive(5)))
sock_cli:close()
sock_srv:close()
srv:close()
print("done!")