diff --git a/examples/userver/userver.cpp b/examples/userver/userver.cpp index 837133bf..7df79253 100644 --- a/examples/userver/userver.cpp +++ b/examples/userver/userver.cpp @@ -95,7 +95,7 @@ public: // REQ_TIMEOUT timeout for request from client // TCP_KEEP_ALIVE Specifies to active the TCP keepalive implementation in the linux kernel. // MAX_KEEP_ALIVE Specifies the maximum number of requests that can be served through a Keep-Alive (Persistent) session. - // (Value <= 0 will disable Keep-Alive) (default 1020) + // (Value <= 0 will disable Keep-Alive) // // DH_FILE DH param // CERT_FILE certificate of server diff --git a/include/ulib/net/server/client_image.h b/include/ulib/net/server/client_image.h index 797f60b9..38d6864e 100644 --- a/include/ulib/net/server/client_image.h +++ b/include/ulib/net/server/client_image.h @@ -311,10 +311,10 @@ public: static struct iovec iov_vec[4]; static UClientImage_Base* pthis; static bPFpc callerIsValidRequest; - static bPFpcu callerIsValidRequestExt; static vPF callerHandlerEndRequest; + static bPFpcu callerIsValidRequestExt; static uint32_t rstart, size_request; - static iPF callerHandlerRead, callerHandlerRequest, callerHandlerReset; + static iPF callerHandlerRead, callerHandlerRequest, callerHandlerReset, callerHandlerDataPending; // NB: these are for ULib Servlet Page (USP) - USP_PRINTF... @@ -391,6 +391,8 @@ protected: #endif private: + static int handlerDataPending() U_NO_EXPORT; + static bool isValidRequest( const char* ptr) U_NO_EXPORT; static bool isValidRequestExt(const char* ptr, uint32_t sz) U_NO_EXPORT; diff --git a/include/ulib/utility/uhttp.h b/include/ulib/utility/uhttp.h index ec83cf82..f6ff2a9c 100644 --- a/include/ulib/utility/uhttp.h +++ b/include/ulib/utility/uhttp.h @@ -79,6 +79,7 @@ public: static void ctor(); static void dtor(); + static int handlerDataPending(); static bool isValidRequest(const char* ptr) __pure; static bool scanfHeader(const char* ptr, uint32_t size); static bool isValidRequestExt(const char* ptr, uint32_t size) __pure; diff --git a/src/ulib/lemon/expression.y b/src/ulib/lemon/expression.y index 5a5175b1..0dcd53b4 100644 --- a/src/ulib/lemon/expression.y +++ b/src/ulib/lemon/expression.y @@ -253,20 +253,24 @@ multiplicativeExpression(A) ::= multiplicativeExpression(B) multiplicativeCond(C U_INTERNAL_DUMP("B = %.*S C = %d D = %.*S", U_STRING_TO_TRACE(*B), C, U_STRING_TO_TRACE(*D)) -#ifndef U_COVERITY_FALSE_POSITIVE - long Blo = B->strtol(), - Dlo = D->strtol(), - lo = (C == U_TK_MULT ? Blo * Dlo : - C == U_TK_DIV ? Blo / Dlo : - Blo % Dlo); + long lo, + Blo = B->strtol(), + Dlo = D->strtol(); - A = U_NEW(UString(UStringExt::stringFromNumber(lo))); + if (Dlo == 0) A = U_NEW(UString(U_STRING_FROM_CONSTANT("0"))); + else + { + lo = (C == U_TK_MULT ? Blo * Dlo : + C == U_TK_DIV ? Blo / Dlo : + Blo % Dlo); + + A = U_NEW(UString(UStringExt::stringFromNumber(lo))); + } delete B; delete D; U_INTERNAL_DUMP("A = %.*S", U_STRING_TO_TRACE(*A)) -#endif } multiplicativeExpression(A) ::= unaryExpression(B). { diff --git a/src/ulib/net/server/client_image.cpp b/src/ulib/net/server/client_image.cpp index b366e06b..763336bc 100644 --- a/src/ulib/net/server/client_image.cpp +++ b/src/ulib/net/server/client_image.cpp @@ -29,6 +29,7 @@ iPF UClientImage_Base::callerHandlerRequest; iPF UClientImage_Base::callerHandlerReset; bPF UClientImage_Base::callerHandlerCache; vPF UClientImage_Base::callerHandlerEndRequest; +iPF UClientImage_Base::callerHandlerDataPending; bool UClientImage_Base::bIPv6; bool UClientImage_Base::log_request_partial; char UClientImage_Base::cbuffer[128]; @@ -257,6 +258,35 @@ void UClientImage_Base::saveRequestResponse() U_NO_EXPORT bool UClientImage_Base::isValidRequest( const char* ptr) { return true; } U_NO_EXPORT bool UClientImage_Base::isValidRequestExt(const char* ptr, uint32_t sz) { return sz; } +U_NO_EXPORT int UClientImage_Base::handlerDataPending() +{ + U_TRACE(0, "UClientImage_Base::handlerDataPending()") + + U_INTERNAL_ASSERT_POINTER(psocket) + + if (UServer_Base::startParallelization(UServer_Base::num_client_for_parallelization)) + { + // parent + + U_ClientImage_state = U_PLUGIN_HANDLER_ERROR; + + U_RETURN(-1); + } + + if (U_ClientImage_parallelization == 1) // 1 => child of parallelization + { + if (UNotifier::waitForRead(psocket->iSockDesc, U_TIMEOUT_MS) != 1 || + (resetReadBuffer(), USocketExt::read(psocket, *rbuffer, size_request == 0 ? U_SINGLE_READ : size_request - rbuffer->size(), 0)) == false) + { + U_RETURN(-1); + } + + U_RETURN(1); + } + + U_RETURN(0); +} + void UClientImage_Base::init() { U_TRACE(0, "UClientImage_Base::init()") @@ -286,8 +316,9 @@ void UClientImage_Base::init() chronometer->start(); - callerIsValidRequest = isValidRequest; - callerIsValidRequestExt = isValidRequestExt; + callerIsValidRequest = isValidRequest; + callerIsValidRequestExt = isValidRequestExt; + callerHandlerDataPending = handlerDataPending; #ifdef DEBUG UError::callerDataDump = saveRequestResponse; @@ -410,12 +441,6 @@ void UClientImage_Base::handlerDelete() { U_TRACE(0, "UClientImage_Base::handlerDelete()") - U_DUMP("UEventFd::fd = %d socket->iSockDesc = %d " - "UNotifier::num_connection = %d UNotifier::min_connection = %d " - "UServer_Base::isParallelizationChild() = %b sfd = %d UEventFd::op_mask = %B", - UEventFd::fd, socket->iSockDesc, UNotifier::num_connection, UNotifier::min_connection, - UServer_Base::isParallelizationChild(), sfd, UEventFd::op_mask); - #if !defined(USE_LIBEVENT) && defined(HAVE_EPOLL_WAIT) && defined(DEBUG) if (UNLIKELY(UNotifier::num_connection <= UNotifier::min_connection)) { @@ -532,11 +557,9 @@ void UClientImage_Base::handlerError() U_INTERNAL_ASSERT_POINTER(socket) - U_DUMP("UEventFd::fd = %d socket->iSockDesc = %d " - "UNotifier::num_connection = %d UNotifier::min_connection = %d " - "UServer_Base::isParallelizationChild() = %b sfd = %d UEventFd::op_mask = %B", - UEventFd::fd, socket->iSockDesc, UNotifier::num_connection, UNotifier::min_connection, - UServer_Base::isParallelizationChild(), sfd, UEventFd::op_mask); + pthis = this; + + UNotifier::handlerDelete(UEventFd::fd, UEventFd::op_mask); #if !defined(USE_LIBEVENT) && defined(HAVE_EPOLL_WAIT) && defined(DEBUG) if (UNLIKELY(socket->iSockDesc == -1)) @@ -554,11 +577,6 @@ void UClientImage_Base::handlerError() U_INTERNAL_ASSERT_EQUALS(socket->iSockDesc, UEventFd::fd) #endif - pthis = this; - (psocket = socket)->iState = USocket::EPOLLERROR; - - UNotifier::handlerDelete(UEventFd::fd, UEventFd::op_mask); - UClientImage_Base::handlerDelete(); } @@ -566,12 +584,6 @@ int UClientImage_Base::handlerTimeout() { U_TRACE(0, "UClientImage_Base::handlerTimeout()") - U_DUMP("UEventFd::fd = %d socket->iSockDesc = %d " - "UNotifier::num_connection = %d UNotifier::min_connection = %d " - "UServer_Base::isParallelizationChild() = %b sfd = %d UEventFd::op_mask = %B", - UEventFd::fd, socket->iSockDesc, UNotifier::num_connection, UNotifier::min_connection, - UServer_Base::isParallelizationChild(), sfd, UEventFd::op_mask); - #if !defined(USE_LIBEVENT) && defined(HAVE_EPOLL_WAIT) && defined(DEBUG) if (UNLIKELY(socket->iSockDesc == -1)) { @@ -596,7 +608,7 @@ int UClientImage_Base::handlerTimeout() pthis = this; // NB: U_SRV_LOG_WITH_ADDR macro depend on UClientImage_Base::pthis... - socket->iState = USocket::TIMEOUT | USocket::EPOLLERROR; + socket->iState = USocket::TIMEOUT; U_RETURN(U_NOTIFIER_DELETE); } @@ -950,6 +962,10 @@ int UClientImage_Base::handlerRead() // Connection-wide hooks { U_TRACE(0, "UClientImage_Base::handlerRead()") + int result; + uint32_t sz; + const char* ptr; + u_clientimage_flag.u = 0; #ifdef U_CLASSIC_SUPPORT @@ -989,7 +1005,7 @@ loop: if (LIKELY(U_ClientImage_pipeline == false)) *request = *rbuffer; else { - uint32_t sz = rbuffer->size(); + sz = rbuffer->size(); U_ASSERT_MINOR(rstart, sz) U_INTERNAL_ASSERT_MAJOR(rstart, 0) @@ -1017,42 +1033,26 @@ loop: if (U_ClientImage_data_missing) { dmiss: + result = callerHandlerDataPending(); + + if (result) + { + if (result == 1) goto loop; + if (result == -1) + { + if ((U_ClientImage_state & U_PLUGIN_HANDLER_ERROR) != 0) U_RETURN(U_NOTIFIER_DELETE); + + goto death; + } + } + U_ClientImage_data_missing = false; U_INTERNAL_ASSERT_EQUALS(data_pending, 0) - U_INTERNAL_DUMP("U_http_version = %C", U_http_version) + data_pending = U_NEW(UString((void*)U_STRING_TO_PARAM(*request))); - if (U_http_version == '2') - { - // TODO - } - else - { - if (UServer_Base::startParallelization(UServer_Base::num_client_for_parallelization)) - { - // parent - - U_ClientImage_state = U_PLUGIN_HANDLER_ERROR; - - U_RETURN(U_NOTIFIER_DELETE); - } - - if (U_ClientImage_parallelization == 1) // 1 => child of parallelization - { - if (UNotifier::waitForRead(socket->iSockDesc, U_TIMEOUT_MS) != 1 || - (resetReadBuffer(), USocketExt::read(socket, *rbuffer, size_request == 0 ? U_SINGLE_READ : size_request - rbuffer->size(), 0)) == false) - { - goto death; - } - - goto loop; - } - - data_pending = U_NEW(UString((void*)U_STRING_TO_PARAM(*request))); - - U_INTERNAL_DUMP("data_pending(%u) = %.*S", data_pending->size(), U_STRING_TO_TRACE(*data_pending)) - } + U_INTERNAL_DUMP("data_pending(%u) = %.*S", data_pending->size(), U_STRING_TO_TRACE(*data_pending)) U_INTERNAL_ASSERT(socket->isOpen()) U_INTERNAL_ASSERT_DIFFERS(U_ClientImage_parallelization, 1) // 1 => child of parallelization @@ -1065,8 +1065,8 @@ dmiss: if (U_ClientImage_request_is_cached) { - uint32_t sz = request->size(); - const char* ptr = request->data(); + sz = request->size(); + ptr = request->data(); U_INTERNAL_DUMP("cbuffer(%u) = %.*S", u_http_info.startHeader, u_http_info.startHeader, cbuffer) U_INTERNAL_DUMP("request(%u) = %.*S", sz, sz, ptr) @@ -1139,7 +1139,7 @@ dmiss: # ifndef U_CACHE_REQUEST_DISABLE next: # endif - uint32_t sz = rbuffer->size(); + sz = rbuffer->size(); if (LIKELY(U_ClientImage_pipeline == false)) { @@ -1165,7 +1165,7 @@ next: { U_INTERNAL_ASSERT_EQUALS(nrequest, 0) - const char* ptr = rbuffer->data(); + ptr = rbuffer->data(); const char* end = ptr + sz; while (true) @@ -1349,18 +1349,6 @@ end: if (U_ClientImage_parallelization == 1) goto death; // 1 => child of paral if (U_ClientImage_parallelization == 1) { -# ifdef DEBUG - if (count) // NB: we must not have pending write... - { - U_ERROR("handlerRead(): " - "UEventFd::fd = %d socket->iSockDesc = %d " - "UNotifier::num_connection = %d UNotifier::min_connection = %d " - "count = %u sfd = %d UEventFd::op_mask = %B", - UEventFd::fd, socket->iSockDesc, UNotifier::num_connection, UNotifier::min_connection, - count, sfd, UEventFd::op_mask); - } -# endif - U_INTERNAL_ASSERT_DIFFERS(socket->iSockDesc, -1) if (UNotifier::waitForRead(socket->iSockDesc, U_TIMEOUT_MS) == 1) goto start; diff --git a/src/ulib/net/server/plugin/mod_http.cpp b/src/ulib/net/server/plugin/mod_http.cpp index 170652af..46f489d7 100644 --- a/src/ulib/net/server/plugin/mod_http.cpp +++ b/src/ulib/net/server/plugin/mod_http.cpp @@ -552,11 +552,12 @@ int UHttpPlugIn::handlerRun() // NB: we use this method because now we have the // NB: we can shortcut the http request processing... - UClientImage_Base::callerHandlerRead = UHTTP::handlerREAD; - UClientImage_Base::callerHandlerCache = UHTTP::handlerCache; - UClientImage_Base::callerIsValidRequest = UHTTP::isValidRequest; - UClientImage_Base::callerIsValidRequestExt = UHTTP::isValidRequestExt; - UClientImage_Base::callerHandlerEndRequest = UHTTP::setEndRequestProcessing; + UClientImage_Base::callerHandlerRead = UHTTP::handlerREAD; + UClientImage_Base::callerHandlerCache = UHTTP::handlerCache; + UClientImage_Base::callerIsValidRequest = UHTTP::isValidRequest; + UClientImage_Base::callerIsValidRequestExt = UHTTP::isValidRequestExt; + UClientImage_Base::callerHandlerEndRequest = UHTTP::setEndRequestProcessing; + UClientImage_Base::callerHandlerDataPending = UHTTP::handlerDataPending; } U_ASSERT(UHTTP::cache_file_check_memory()) diff --git a/src/ulib/net/server/server.cpp b/src/ulib/net/server/server.cpp index 99c86343..9abf9e84 100644 --- a/src/ulib/net/server/server.cpp +++ b/src/ulib/net/server/server.cpp @@ -547,7 +547,7 @@ void UServer_Base::loadConfigParam() // REQ_TIMEOUT timeout for request from client // TCP_KEEP_ALIVE Specifies to active the TCP keepalive implementation in the linux kernel. // MAX_KEEP_ALIVE Specifies the maximum number of requests that can be served through a Keep-Alive (Persistent) session. - // (Value <= 0 will disable Keep-Alive) (default 1020) + // (Value <= 0 will disable Keep-Alive) // // DH_FILE DH param // CERT_FILE server certificate diff --git a/src/ulib/net/socket.cpp b/src/ulib/net/socket.cpp index 48cfcc22..20a4f0a6 100644 --- a/src/ulib/net/socket.cpp +++ b/src/ulib/net/socket.cpp @@ -202,7 +202,7 @@ bool USocket::checkErrno() U_RETURN(true); } - iState = (errno == ECONNRESET ? EPOLLERROR : BROKEN); + if (errno != ECONNRESET) iState = BROKEN; closesocket(); diff --git a/src/ulib/utility/socket_ext.cpp b/src/ulib/utility/socket_ext.cpp index 7537ff02..cbdab81b 100644 --- a/src/ulib/utility/socket_ext.cpp +++ b/src/ulib/utility/socket_ext.cpp @@ -129,7 +129,11 @@ error: U_INTERNAL_DUMP("errno = %d", errno) { if (U_ClientImage_parallelization != 1) // 1 => child of parallelization { - if (sk == UClientImage_Base::psocket) sk->iState = (errno == ECONNRESET ? USocket::EPOLLERROR : USocket::BROKEN); + if (errno != ECONNRESET && + sk == UClientImage_Base::psocket) + { + sk->iState = USocket::BROKEN; + } sk->close(); } @@ -157,16 +161,7 @@ error: U_INTERNAL_DUMP("errno = %d", errno) { U_INTERNAL_DUMP("byte_read = %d errno = %d", byte_read, errno) - if (U_ClientImage_parallelization != 1) // 1 => child of parallelization - { - if (errno == ENOTCONN && - sk == UClientImage_Base::psocket) - { - sk->iState = USocket::EPOLLERROR; - } - - sk->close(); - } + if (U_ClientImage_parallelization != 1) sk->close(); // 1 => child of parallelization U_RETURN(false); } diff --git a/src/ulib/utility/uhttp.cpp b/src/ulib/utility/uhttp.cpp index f8fb4436..fcd5661b 100644 --- a/src/ulib/utility/uhttp.cpp +++ b/src/ulib/utility/uhttp.cpp @@ -1600,6 +1600,22 @@ __pure bool UHTTP::isValidRequestExt(const char* ptr, uint32_t sz) U_RETURN(false); } +int UHTTP::handlerDataPending() +{ + U_TRACE(0, "UHTTP::handlerDataPending()") + + U_INTERNAL_DUMP("U_http_version = %C", U_http_version) + + if (U_http_version == '2') + { + // TODO + + U_RETURN(-1); + } + + return UClientImage_Base::handlerDataPending(); +} + bool UHTTP::scanfHeader(const char* ptr, uint32_t size) { U_TRACE(0, "UHTTP::scanfHeader(%.*S,%u)", size, ptr, size) diff --git a/tests/examples/FrameworkBenchmarks.sh b/tests/examples/FrameworkBenchmarks.sh index 5898d0ea..2d74463b 100755 --- a/tests/examples/FrameworkBenchmarks.sh +++ b/tests/examples/FrameworkBenchmarks.sh @@ -25,7 +25,7 @@ rm -f /tmp/*.memusage.* \ #ORM_DRIVER="pgsql" #ORM_OPTION="host=localhost user=benchmarkdbuser password=benchmarkdbpass dbname=hello_world" -UMEMPOOL="152,85,0,37,8315,105,-17,-22,40" +UMEMPOOL="152,85,0,37,8330,105,-17,-22,40" export ORM_DRIVER ORM_OPTION UMEMPOOL DIR_CMD="../../examples/userver" diff --git a/tests/examples/benchmark/FrameworkBenchmarks/ULib/install.sh b/tests/examples/benchmark/FrameworkBenchmarks/ULib/install.sh index 510a8f9a..764a3da1 100755 --- a/tests/examples/benchmark/FrameworkBenchmarks/ULib/install.sh +++ b/tests/examples/benchmark/FrameworkBenchmarks/ULib/install.sh @@ -42,6 +42,7 @@ if [ ! -f "benchmark.cfg" ]; then userver { PORT 8080 PREFORK_CHILD 8 + MAX_KEEP_ALIVE 1023 LISTEN_BACKLOG 16384 CLIENT_FOR_PARALLELIZATION 256 ORM_DRIVER "mysql pgsql sqlite" diff --git a/tests/examples/benchmark/FrameworkBenchmarks/ULib/setup_mysql.sh b/tests/examples/benchmark/FrameworkBenchmarks/ULib/setup_mysql.sh index 338fab8a..f1e9370d 100755 --- a/tests/examples/benchmark/FrameworkBenchmarks/ULib/setup_mysql.sh +++ b/tests/examples/benchmark/FrameworkBenchmarks/ULib/setup_mysql.sh @@ -1,6 +1,6 @@ #!/bin/bash -export UMEMPOOL="152,85,0,37,8315,105,-17,-22,40" +export UMEMPOOL="152,85,0,37,8330,105,-17,-22,40" export ORM_DRIVER="mysql" export ORM_OPTION="host=${DBHOST} user=benchmarkdbuser password=benchmarkdbpass character-set=utf8 dbname=hello_world" diff --git a/tests/examples/benchmark/FrameworkBenchmarks/ULib/setup_postgres.sh b/tests/examples/benchmark/FrameworkBenchmarks/ULib/setup_postgres.sh index 076c6caa..9c107a33 100755 --- a/tests/examples/benchmark/FrameworkBenchmarks/ULib/setup_postgres.sh +++ b/tests/examples/benchmark/FrameworkBenchmarks/ULib/setup_postgres.sh @@ -1,6 +1,6 @@ #!/bin/bash -export UMEMPOOL="152,85,0,37,8315,105,-17,-22,40" +export UMEMPOOL="152,85,0,37,8330,105,-17,-22,40" export ORM_DRIVER="pgsql" export ORM_OPTION="host=${DBHOST} user=benchmarkdbuser password=benchmarkdbpass dbname=hello_world client_encoding=UTF8" diff --git a/tests/examples/benchmark/FrameworkBenchmarks/ULib/setup_sqlite.sh b/tests/examples/benchmark/FrameworkBenchmarks/ULib/setup_sqlite.sh index 9fca1021..26de90f1 100755 --- a/tests/examples/benchmark/FrameworkBenchmarks/ULib/setup_sqlite.sh +++ b/tests/examples/benchmark/FrameworkBenchmarks/ULib/setup_sqlite.sh @@ -1,6 +1,6 @@ #!/bin/bash -export UMEMPOOL="152,85,0,37,8315,105,-17,-22,40" +export UMEMPOOL="152,85,0,37,8330,105,-17,-22,40" export ORM_DRIVER="sqlite" export ORM_OPTION="host=${DBHOST} user=benchmarkdbuser password=benchmarkdbpass character-set=utf8 dbname=${ULIB_ROOT}/db/%.*s" diff --git a/tests/examples/benchmark/FrameworkBenchmarks/fbenchmark.cfg b/tests/examples/benchmark/FrameworkBenchmarks/fbenchmark.cfg index e81b8449..dd74e0f4 100644 --- a/tests/examples/benchmark/FrameworkBenchmarks/fbenchmark.cfg +++ b/tests/examples/benchmark/FrameworkBenchmarks/fbenchmark.cfg @@ -2,6 +2,7 @@ userver { PORT 8080 PREFORK_CHILD 8 + MAX_KEEP_ALIVE 1023 LISTEN_BACKLOG 16384 CLIENT_FOR_PARALLELIZATION 256 DOCUMENT_ROOT benchmark/FrameworkBenchmarks/ULib/www