moonbridge
diff moonbridge_io.c @ 88:fca51922b708
Extended I/O library; Integrated new I/O library into moonbridge.c and moonbridge_http.lua
author | jbe |
---|---|
date | Tue Apr 07 02:15:17 2015 +0200 (2015-04-07) |
parents | 1d91c6eedf18 |
children | 54e6104c70a6 |
line diff
1.1 --- a/moonbridge_io.c Tue Apr 07 01:17:55 2015 +0200 1.2 +++ b/moonbridge_io.c Tue Apr 07 02:15:17 2015 +0200 1.3 @@ -26,6 +26,8 @@ 1.4 typedef struct { 1.5 int fd; 1.6 int issocket; 1.7 + int canshutdown; 1.8 + int shutwr; 1.9 int nonblocking; 1.10 int readerr; 1.11 int readbufcnt; 1.12 @@ -167,6 +169,7 @@ 1.13 ssize_t result; 1.14 handle = luaL_checkudata(L, 1, MOONBR_IO_HANDLE_MT_REGKEY); 1.15 if (handle->fd < 0) luaL_error(L, "Attempt to write to a closed I/O handle"); 1.16 + if (handle->shutwr) luaL_error(L, "Attempt to write to a finished I/O handle"); 1.17 if (handle->writeerr) { 1.18 lua_pushnil(L); 1.19 lua_pushliteral(L, "Previous write error"); 1.20 @@ -277,6 +280,30 @@ 1.21 return moonbr_io_write_impl(L, 1, 1); 1.22 } 1.23 1.24 +static int moonbr_io_finish(lua_State *L) { 1.25 + moonbr_io_handle_t *handle; 1.26 + handle = luaL_checkudata(L, 1, MOONBR_IO_HANDLE_MT_REGKEY); 1.27 + if (handle->fd < 0) luaL_error(L, "Attempt to finish a closed I/O handle"); 1.28 + if (handle->shutwr) luaL_error(L, "Attempt to finish a finished I/O handle"); 1.29 + handle->shutwr = 1; 1.30 + if (handle->canshutdown) { 1.31 + if (handle->writeleft) { 1.32 + lua_pushcfunction(L, moonbr_io_flush); 1.33 + lua_pushvalue(L, 1); 1.34 + lua_call(L, 1, 2); 1.35 + if (!lua_toboolean(L, -2)) return 2; 1.36 + } 1.37 + if (shutdown(handle->fd, SHUT_WR)) { 1.38 + moonbr_io_errmsg(); 1.39 + lua_pushnil(L); 1.40 + lua_pushstring(L, errmsg); 1.41 + return 2; 1.42 + } 1.43 + } 1.44 + lua_pushboolean(L, 1); 1.45 + return 1; 1.46 +} 1.47 + 1.48 static int moonbr_io_close(lua_State *L) { 1.49 moonbr_io_handle_t *handle; 1.50 int timeout; 1.51 @@ -319,11 +346,36 @@ 1.52 return lua_gettop(L); 1.53 } 1.54 1.55 -void moonbr_io_pushhandle(lua_State *L, int fd, int issocket) { 1.56 +static int moonbr_io_gc(lua_State *L) { 1.57 + moonbr_io_handle_t *handle; 1.58 + handle = luaL_checkudata(L, 1, MOONBR_IO_HANDLE_MT_REGKEY); 1.59 + if (handle->fd >= 0) { 1.60 + lua_pushcfunction(L, moonbr_io_close); 1.61 + lua_pushvalue(L, 1); 1.62 + lua_pushinteger(L, 0); 1.63 + lua_call(L, 2, 0); 1.64 + } 1.65 + return 0; 1.66 +} 1.67 + 1.68 +void moonbr_io_closehandle(lua_State *L, int idx, int timeout) { 1.69 + moonbr_io_handle_t *handle; 1.70 + handle = luaL_checkudata(L, idx, MOONBR_IO_HANDLE_MT_REGKEY); 1.71 + if (handle->fd >= 0) { 1.72 + lua_pushcfunction(L, moonbr_io_close); 1.73 + lua_pushvalue(L, idx); 1.74 + lua_pushinteger(L, timeout); 1.75 + lua_call(L, 2, 0); 1.76 + } 1.77 +} 1.78 + 1.79 +void moonbr_io_pushhandle(lua_State *L, int fd, int issocket, int canshutdown) { 1.80 moonbr_io_handle_t *handle; 1.81 handle = lua_newuserdata(L, sizeof(moonbr_io_handle_t)); 1.82 handle->fd = fd; 1.83 handle->issocket = issocket; 1.84 + handle->canshutdown = canshutdown; 1.85 + handle->shutwr = 0; 1.86 handle->nonblocking = -1; 1.87 handle->readerr = 0; 1.88 handle->readbufcnt = 0; 1.89 @@ -374,6 +426,7 @@ 1.90 {"write_nb", moonbr_io_write_nb}, 1.91 {"flush", moonbr_io_flush}, 1.92 {"flush_nb", moonbr_io_flush_nb}, 1.93 + {"finish", moonbr_io_finish}, 1.94 {"close", moonbr_io_close}, 1.95 {"reset", moonbr_io_reset}, 1.96 {NULL, NULL} 1.97 @@ -382,7 +435,7 @@ 1.98 static const struct luaL_Reg moonbr_io_handle_metamethods[] = { 1.99 {"__index", moonbr_io_handleindex}, 1.100 {"__newindex", moonbr_io_handlenewindex}, 1.101 - {"__gc", moonbr_io_reset}, 1.102 + {"__gc", moonbr_io_gc}, 1.103 {NULL, NULL} 1.104 }; 1.105