# HG changeset patch # User jbe # Date 1428448940 -7200 # Node ID fdc1bb7105446d6fccd53b4d66545fc128d2253a # Parent 719f83c7fea412b405b84ab81750f308b851bb2c Allow full write buffer without forcing TCP PSH diff -r 719f83c7fea4 -r fdc1bb710544 moonbridge_io.c --- a/moonbridge_io.c Wed Apr 08 01:12:03 2015 +0200 +++ b/moonbridge_io.c Wed Apr 08 01:22:20 2015 +0200 @@ -55,14 +55,18 @@ flags = fcntl(handle->fd, F_GETFL, 0); if (flags == -1) { moonbr_io_errmsg(); - handle->nonblocking = -1; + close(handle->fd); + handle->fd = -1; + handle->closed = 1; luaL_error(L, "Unexpected error in fcntl call: %s", errmsg); } if (nonblocking) flags |= O_NONBLOCK; else flags &= ~O_NONBLOCK; if (fcntl(handle->fd, F_SETFL, flags) == -1) { moonbr_io_errmsg(); - handle->nonblocking = -1; + close(handle->fd); + handle->fd = -1; + handle->closed = 1; luaL_error(L, "Unexpected error in fcntl call: %s", errmsg); } handle->nonblocking = nonblocking; @@ -77,26 +81,37 @@ } if (setsockopt(handle->fd, SOL_SOCKET, SO_LINGER, &lingerval, sizeof(lingerval))) { moonbr_io_errmsg(); + close(handle->fd); + handle->fd = -1; + handle->closed = 1; luaL_error(L, "Unexpected error while setting SO_LINGER with setsockopt: %s", errmsg); } } static void moonbr_io_handle_set_nopush(lua_State *L, moonbr_io_handle_t *handle, int nopush) { +#if defined(TCP_NOPUSH) || defined(TCP_CORK) if (!handle->isnetwork || handle->nopush == nopush) return; -#if defined(TCP_CORK) && !defined(TCP_NOPUSH) +#if defined(TCP_NOPUSH) + if (setsockopt(handle->fd, IPPROTO_TCP, TCP_NOPUSH, &nopush, sizeof(nopush))) { + moonbr_io_errmsg(); + close(handle->fd); + handle->fd = -1; + handle->closed = 1; + luaL_error(L, "Unexpected error while setting TCP_NOPUSH with setsockopt: %s", errmsg); + } +#elif defined(TCP_CORK) if (setsockopt(handle->fd, IPPROTO_TCP, TCP_CORK, &nopush, sizeof(nopush))) { moonbr_io_errmsg(); - handle->nopush = -1; + close(handle->fd); + handle->fd = -1; + handle->closed = 1; luaL_error(L, "Unexpected error while setting TCP_CORK with setsockopt: %s", errmsg); } -#else - if (setsockopt(handle->fd, IPPROTO_TCP, TCP_NOPUSH, &nopush, sizeof(nopush))) { - moonbr_io_errmsg(); - handle->nopush = -1; - luaL_error(L, "Unexpected error while setting TCP_NOPUSH with setsockopt: %s", errmsg); - } #endif handle->nopush = nopush; +#else +#warning Neither TCP_NOPUSH nor TCP_CORK is available +#endif } static int moonbr_io_read_impl(lua_State *L, int nonblocking, int drain) { @@ -228,15 +243,12 @@ lua_rawgeti(L, -1, handle->writeqout); str = lua_tolstring(L, -1, &strlen); while (handle->writeqoff < strlen) { - if (strlen - handle->writeqoff < MOONBR_IO_WRITEBUFLEN - handle->writebufcnt) { + if (strlen - handle->writeqoff <= MOONBR_IO_WRITEBUFLEN - handle->writebufcnt) { memcpy(handle->writebuf + handle->writebufcnt, str + handle->writeqoff, strlen - handle->writeqoff); handle->writebufcnt += strlen - handle->writeqoff; break; } else { - moonbr_io_handle_set_nopush(L, handle, - (flush || handle->writeleft == MOONBR_IO_WRITEBUFLEN) ? - 0 : 1 - ); + moonbr_io_handle_set_nopush(L, handle, flush ? 0 : 1); written = 0; memcpy(handle->writebuf + handle->writebufcnt, str + handle->writeqoff, MOONBR_IO_WRITEBUFLEN - handle->writebufcnt); handle->writeqoff += MOONBR_IO_WRITEBUFLEN - handle->writebufcnt;