diff options
| author | Diego Nehab <diego@tecgraf.puc-rio.br> | 2009-05-27 09:31:38 +0000 |
|---|---|---|
| committer | Diego Nehab <diego@tecgraf.puc-rio.br> | 2009-05-27 09:31:38 +0000 |
| commit | bce60be30fe8e9c1b0eb33128c23c93d7bca5303 (patch) | |
| tree | 3927343c777fcb7764a0f2f89754a0ceab141c21 /src/select.c | |
| parent | d1a72435d5bd3528f3c334cd4d1da16dcead47bf (diff) | |
| download | luasocket-bce60be30fe8e9c1b0eb33128c23c93d7bca5303.tar.gz luasocket-bce60be30fe8e9c1b0eb33128c23c93d7bca5303.tar.bz2 luasocket-bce60be30fe8e9c1b0eb33128c23c93d7bca5303.zip | |
Decent makefiles!
Diffstat (limited to 'src/select.c')
| -rw-r--r-- | src/select.c | 39 |
1 files changed, 25 insertions, 14 deletions
diff --git a/src/select.c b/src/select.c index 99b59f5..8e47d0e 100644 --- a/src/select.c +++ b/src/select.c | |||
| @@ -18,8 +18,8 @@ | |||
| 18 | \*=========================================================================*/ | 18 | \*=========================================================================*/ |
| 19 | static t_socket getfd(lua_State *L); | 19 | static t_socket getfd(lua_State *L); |
| 20 | static int dirty(lua_State *L); | 20 | static int dirty(lua_State *L); |
| 21 | static t_socket collect_fd(lua_State *L, int tab, t_socket max_fd, | 21 | static void collect_fd(lua_State *L, int tab, int itab, |
| 22 | int itab, fd_set *set); | 22 | fd_set *set, t_socket *max_fd); |
| 23 | static int check_dirty(lua_State *L, int tab, int dtab, fd_set *set); | 23 | static int check_dirty(lua_State *L, int tab, int dtab, fd_set *set); |
| 24 | static void return_fd(lua_State *L, fd_set *set, t_socket max_fd, | 24 | static void return_fd(lua_State *L, fd_set *set, t_socket max_fd, |
| 25 | int itab, int tab, int start); | 25 | int itab, int tab, int start); |
| @@ -39,6 +39,9 @@ static luaL_reg func[] = { | |||
| 39 | * Initializes module | 39 | * Initializes module |
| 40 | \*-------------------------------------------------------------------------*/ | 40 | \*-------------------------------------------------------------------------*/ |
| 41 | int select_open(lua_State *L) { | 41 | int select_open(lua_State *L) { |
| 42 | lua_pushstring(L, "_SETSIZE"); | ||
| 43 | lua_pushnumber(L, FD_SETSIZE); | ||
| 44 | lua_rawset(L, -3); | ||
| 42 | luaL_openlib(L, NULL, func, 0); | 45 | luaL_openlib(L, NULL, func, 0); |
| 43 | return 0; | 46 | return 0; |
| 44 | } | 47 | } |
| @@ -51,7 +54,7 @@ int select_open(lua_State *L) { | |||
| 51 | \*-------------------------------------------------------------------------*/ | 54 | \*-------------------------------------------------------------------------*/ |
| 52 | static int global_select(lua_State *L) { | 55 | static int global_select(lua_State *L) { |
| 53 | int rtab, wtab, itab, ret, ndirty; | 56 | int rtab, wtab, itab, ret, ndirty; |
| 54 | t_socket max_fd; | 57 | t_socket max_fd = SOCKET_INVALID; |
| 55 | fd_set rset, wset; | 58 | fd_set rset, wset; |
| 56 | t_timeout tm; | 59 | t_timeout tm; |
| 57 | double t = luaL_optnumber(L, 3, -1); | 60 | double t = luaL_optnumber(L, 3, -1); |
| @@ -60,12 +63,12 @@ static int global_select(lua_State *L) { | |||
| 60 | lua_newtable(L); itab = lua_gettop(L); | 63 | lua_newtable(L); itab = lua_gettop(L); |
| 61 | lua_newtable(L); rtab = lua_gettop(L); | 64 | lua_newtable(L); rtab = lua_gettop(L); |
| 62 | lua_newtable(L); wtab = lua_gettop(L); | 65 | lua_newtable(L); wtab = lua_gettop(L); |
| 63 | max_fd = collect_fd(L, 1, SOCKET_INVALID, itab, &rset); | 66 | collect_fd(L, 1, itab, &rset, &max_fd); |
| 67 | collect_fd(L, 2, itab, &wset, &max_fd); | ||
| 64 | ndirty = check_dirty(L, 1, rtab, &rset); | 68 | ndirty = check_dirty(L, 1, rtab, &rset); |
| 65 | t = ndirty > 0? 0.0: t; | 69 | t = ndirty > 0? 0.0: t; |
| 66 | timeout_init(&tm, t, -1); | 70 | timeout_init(&tm, t, -1); |
| 67 | timeout_markstart(&tm); | 71 | timeout_markstart(&tm); |
| 68 | max_fd = collect_fd(L, 2, max_fd, itab, &wset); | ||
| 69 | ret = socket_select(max_fd+1, &rset, &wset, NULL, &tm); | 72 | ret = socket_select(max_fd+1, &rset, &wset, NULL, &tm); |
| 70 | if (ret > 0 || ndirty > 0) { | 73 | if (ret > 0 || ndirty > 0) { |
| 71 | return_fd(L, &rset, max_fd+1, itab, rtab, ndirty); | 74 | return_fd(L, &rset, max_fd+1, itab, rtab, ndirty); |
| @@ -77,7 +80,7 @@ static int global_select(lua_State *L) { | |||
| 77 | lua_pushstring(L, "timeout"); | 80 | lua_pushstring(L, "timeout"); |
| 78 | return 3; | 81 | return 3; |
| 79 | } else { | 82 | } else { |
| 80 | lua_pushstring(L, "error"); | 83 | luaL_error(L, "select failed"); |
| 81 | return 3; | 84 | return 3; |
| 82 | } | 85 | } |
| 83 | } | 86 | } |
| @@ -112,11 +115,13 @@ static int dirty(lua_State *L) { | |||
| 112 | return is; | 115 | return is; |
| 113 | } | 116 | } |
| 114 | 117 | ||
| 115 | static t_socket collect_fd(lua_State *L, int tab, t_socket max_fd, | 118 | static void collect_fd(lua_State *L, int tab, int itab, |
| 116 | int itab, fd_set *set) { | 119 | fd_set *set, t_socket *max_fd) { |
| 117 | int i = 1; | 120 | int i = 1, n = 0; |
| 118 | if (lua_isnil(L, tab)) | 121 | /* nil is the same as an empty table */ |
| 119 | return max_fd; | 122 | if (lua_isnil(L, tab)) return; |
| 123 | /* otherwise we need it to be a table */ | ||
| 124 | luaL_checktype(L, tab, LUA_TTABLE); | ||
| 120 | while (1) { | 125 | while (1) { |
| 121 | t_socket fd; | 126 | t_socket fd; |
| 122 | lua_pushnumber(L, i); | 127 | lua_pushnumber(L, i); |
| @@ -125,11 +130,18 @@ static t_socket collect_fd(lua_State *L, int tab, t_socket max_fd, | |||
| 125 | lua_pop(L, 1); | 130 | lua_pop(L, 1); |
| 126 | break; | 131 | break; |
| 127 | } | 132 | } |
| 133 | /* getfd figures out if this is a socket */ | ||
| 128 | fd = getfd(L); | 134 | fd = getfd(L); |
| 129 | if (fd != SOCKET_INVALID) { | 135 | if (fd != SOCKET_INVALID) { |
| 136 | /* make sure we don't overflow the fd_set */ | ||
| 137 | if (n >= FD_SETSIZE) | ||
| 138 | luaL_argerror(L, tab, "too many sockets"); | ||
| 130 | FD_SET(fd, set); | 139 | FD_SET(fd, set); |
| 131 | if (max_fd == SOCKET_INVALID || max_fd < fd) | 140 | n++; |
| 132 | max_fd = fd; | 141 | /* keep track of the largest descriptor so far */ |
| 142 | if (*max_fd == SOCKET_INVALID || *max_fd < fd) | ||
| 143 | *max_fd = fd; | ||
| 144 | /* make sure we can map back from descriptor to the object */ | ||
| 133 | lua_pushnumber(L, fd); | 145 | lua_pushnumber(L, fd); |
| 134 | lua_pushvalue(L, -2); | 146 | lua_pushvalue(L, -2); |
| 135 | lua_settable(L, itab); | 147 | lua_settable(L, itab); |
| @@ -137,7 +149,6 @@ static t_socket collect_fd(lua_State *L, int tab, t_socket max_fd, | |||
| 137 | lua_pop(L, 1); | 149 | lua_pop(L, 1); |
| 138 | i = i + 1; | 150 | i = i + 1; |
| 139 | } | 151 | } |
| 140 | return max_fd; | ||
| 141 | } | 152 | } |
| 142 | 153 | ||
| 143 | static int check_dirty(lua_State *L, int tab, int dtab, fd_set *set) { | 154 | static int check_dirty(lua_State *L, int tab, int dtab, fd_set *set) { |
