diff options
author | George Wang <gwang@php.net> | 2019-04-12 17:44:32 -0400 |
---|---|---|
committer | George Wang <gwang@php.net> | 2019-04-12 17:44:32 -0400 |
commit | 7f551c728cf6ae27f1d6df3a8aaf48b8874cdce3 (patch) | |
tree | 24d2aba5624f1457cbc1983ee0a5a4c4db61ccfa /sapi | |
parent | 8ed3b74a0cc0a683a7db986e9a5657d34d41d94b (diff) | |
parent | 1e7f1b90e8118aeece2dc48c5252d6979d2e0a3a (diff) | |
download | php-git-7f551c728cf6ae27f1d6df3a8aaf48b8874cdce3.tar.gz |
Merge branch 'PHP-7.2' into PHP-7.3
Diffstat (limited to 'sapi')
-rw-r--r-- | sapi/litespeed/lsapi_main.c | 19 | ||||
-rw-r--r-- | sapi/litespeed/lsapilib.c | 153 | ||||
-rw-r--r-- | sapi/litespeed/lsapilib.h | 6 |
3 files changed, 152 insertions, 26 deletions
diff --git a/sapi/litespeed/lsapi_main.c b/sapi/litespeed/lsapi_main.c index f572816eef..2598141722 100644 --- a/sapi/litespeed/lsapi_main.c +++ b/sapi/litespeed/lsapi_main.c @@ -455,7 +455,7 @@ static int sapi_lsapi_activate() static sapi_module_struct lsapi_sapi_module = { "litespeed", - "LiteSpeed V7.2", + "LiteSpeed V7.3", php_lsapi_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ @@ -1378,6 +1378,7 @@ ZEND_END_ARG_INFO() PHP_FUNCTION(litespeed_request_headers); PHP_FUNCTION(litespeed_response_headers); PHP_FUNCTION(apache_get_modules); +PHP_FUNCTION(litespeed_finish_request); PHP_MINFO_FUNCTION(litespeed); @@ -1385,9 +1386,11 @@ static const zend_function_entry litespeed_functions[] = { PHP_FE(litespeed_request_headers, arginfo_litespeed__void) PHP_FE(litespeed_response_headers, arginfo_litespeed__void) PHP_FE(apache_get_modules, arginfo_litespeed__void) + PHP_FE(litespeed_finish_request, arginfo_litespeed__void) PHP_FALIAS(getallheaders, litespeed_request_headers, arginfo_litespeed__void) PHP_FALIAS(apache_request_headers, litespeed_request_headers, arginfo_litespeed__void) PHP_FALIAS(apache_response_headers, litespeed_response_headers, arginfo_litespeed__void) + PHP_FALIAS(fastcgi_finish_request, litespeed_finish_request, arginfo_litespeed__void) {NULL, NULL, NULL} }; @@ -1516,6 +1519,20 @@ PHP_FUNCTION(apache_get_modules) /* }}} */ +/* {{{ proto array litespeed_finish_request(void) + Flushes all response data to the client */ +PHP_FUNCTION(litespeed_finish_request) +{ + if (ZEND_NUM_ARGS() > 0) { + WRONG_PARAM_COUNT; + } + if (LSAPI_End_Response() != -1) { + RETURN_TRUE; + } + RETURN_FALSE; +} +/* }}} */ + /* * Local variables: * tab-width: 4 diff --git a/sapi/litespeed/lsapilib.c b/sapi/litespeed/lsapilib.c index 0e4410fbc7..371bc6b0e3 100644 --- a/sapi/litespeed/lsapilib.c +++ b/sapi/litespeed/lsapilib.c @@ -55,6 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <fcntl.h> #include <limits.h> #include <sys/stat.h> +#include <sched.h> #include <signal.h> #include <stdlib.h> #include <stdio.h> @@ -113,10 +114,18 @@ typedef struct lsapi_MD5Context lsapi_MD5_CTX; #define LSAPI_ST_REQ_BODY 2 #define LSAPI_ST_RESP_HEADER 4 #define LSAPI_ST_RESP_BODY 8 +#define LSAPI_ST_BACKGROUND 16 #define LSAPI_RESP_BUF_SIZE 8192 #define LSAPI_INIT_RESP_HEADER_LEN 4096 +enum +{ + LSAPI_STATE_IDLE, + LSAPI_STATE_CONNECTED, + LSAPI_STATE_ACCEPTING, +}; + typedef struct _lsapi_child_status { int m_pid; @@ -124,7 +133,7 @@ typedef struct _lsapi_child_status volatile short m_iKillSent; volatile char m_inProcess; - volatile char m_connected; + volatile char m_state; volatile int m_iReqCounter; volatile long m_tmWaitBegin; @@ -156,6 +165,9 @@ static int s_max_busy_workers = -1; static char *s_stderr_log_path = NULL; static int s_stderr_is_pipe = 0; static int s_ignore_pid = -1; +static size_t s_total_pages = 1; +static size_t s_min_avail_pages = 256 * 1024; +static size_t *s_avail_pages = &s_total_pages; LSAPI_Request g_req = { .m_fdListen = -1, .m_fd = -1 }; @@ -415,7 +427,7 @@ static void lsapi_close_connection(LSAPI_Request *pReq) if (s_busy_workers) __sync_fetch_and_sub(s_busy_workers, 1); if (s_worker_status) - s_worker_status->m_connected = 0; + __sync_lock_test_and_set(&s_worker_status->m_state, LSAPI_STATE_IDLE); } @@ -1558,7 +1570,8 @@ int LSAPI_Accept_r( LSAPI_Request * pReq ) else { if (s_worker_status) - s_worker_status->m_connected = 1; + __sync_lock_test_and_set(&s_worker_status->m_state, + LSAPI_STATE_CONNECTED); if (s_busy_workers) __sync_fetch_and_add(s_busy_workers, 1); lsapi_set_nblock( pReq->m_fd , 0 ); @@ -1621,6 +1634,37 @@ int LSAPI_Finish_r( LSAPI_Request * pReq ) } +int LSAPI_End_Response_r(LSAPI_Request * pReq) +{ + if (!pReq) + return -1; + if (pReq->m_reqState) + { + if ( pReq->m_fd != -1 ) + { + if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) + { + LSAPI_FinalizeRespHeaders_r( pReq ); + } + if ( pReq->m_pRespBufPos != pReq->m_pRespBuf ) + { + Flush_RespBuf_r( pReq ); + } + + pReq->m_pIovecCur->iov_base = (void *)&finish; + pReq->m_pIovecCur->iov_len = LSAPI_PACKET_HEADER_LEN; + pReq->m_totalLen += LSAPI_PACKET_HEADER_LEN; + ++pReq->m_pIovecCur; + LSAPI_Flush_r( pReq ); + } + send_conn_close_notification(pReq->m_fd); + lsapi_close_connection(pReq); + pReq->m_reqState |= LSAPI_ST_BACKGROUND; + } + return 0; +} + + void LSAPI_Reset_r( LSAPI_Request * pReq ) { pReq->m_pRespBufPos = pReq->m_pRespBuf; @@ -1806,7 +1850,11 @@ ssize_t LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, size_t len ) ssize_t packetLen; int skip = 0; - if ( !pReq || !pBuf || (pReq->m_fd == -1) ) + if (!pReq || !pBuf) + return -1; + if (pReq->m_reqState & LSAPI_ST_BACKGROUND) + return len; + if (pReq->m_fd == -1) return -1; if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) { @@ -2708,6 +2756,9 @@ int LSAPI_Init_Prefork_Server( int max_children, fn_select_t fp, int avoidFork ) s_ppid = getppid(); s_pid = getpid(); setpgid( s_pid, s_pid ); +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) + s_total_pages = sysconf(_SC_PHYS_PAGES); +#endif g_prefork_server->m_iAvoidFork = avoidFork; g_prefork_server->m_iMaxChildren = max_children; @@ -2842,11 +2893,19 @@ static void lsapi_sigchild( int signal ) child_status = find_child_status( pid ); if ( child_status ) { - if (child_status->m_connected) + if (__sync_bool_compare_and_swap(&child_status->m_state, + LSAPI_STATE_CONNECTED, + LSAPI_STATE_IDLE)) { if (s_busy_workers) __sync_fetch_and_sub(s_busy_workers, 1); - child_status->m_connected = 0; + } + else if (__sync_bool_compare_and_swap(&child_status->m_state, + LSAPI_STATE_ACCEPTING, + LSAPI_STATE_IDLE)) + { + if (s_accepting_workers) + __sync_fetch_and_sub(s_accepting_workers, 1); } child_status->m_pid = 0; --g_prefork_server->m_iCurChildren; @@ -2882,6 +2941,7 @@ static int lsapi_init_children_status(void) s_busy_workers = (int *)g_prefork_server->m_pChildrenStatusEnd; s_accepting_workers = s_busy_workers + 1; s_global_counter = s_accepting_workers + 1; + s_avail_pages = (size_t *)(s_global_counter + 1); return 0; } @@ -3021,6 +3081,17 @@ void set_skip_write() { s_skip_write = 1; } +int is_enough_free_mem() +{ +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) + //minimum 1GB or 10% available free memory + return (*s_avail_pages > s_min_avail_pages + || (*s_avail_pages * 10) / s_total_pages > 0); +#endif + return 1; +} + + static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Request * pReq ) { @@ -3090,6 +3161,12 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, } } +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) + *s_avail_pages = sysconf(_SC_AVPHYS_PAGES); + lsapi_log("Memory total: %zd, free: %zd, free %%%zd\n", + s_total_pages, *s_avail_pages, *s_avail_pages * 100 / s_total_pages); + +#endif FD_ZERO( &readfds ); FD_SET( pServer->m_fd, &readfds ); timeout.tv_sec = 1; @@ -3097,11 +3174,15 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, ret = (*g_fnSelect)(pServer->m_fd+1, &readfds, NULL, NULL, &timeout); if (ret == 1 ) { - if (pServer->m_iCurChildren >= pServer->m_iMaxChildren - && s_accepting_workers - && (ret = __sync_add_and_fetch(s_accepting_workers, 0)) > 0) + int accepting = 0; + if (s_accepting_workers) + accepting = __sync_add_and_fetch(s_accepting_workers, 0); + + if (pServer->m_iCurChildren > 0 && accepting > 0) { - usleep( 200 ); + usleep(400); + while(accepting-- > 0) + sched_yield(); continue; } } @@ -3162,14 +3243,17 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, if (pthread_atfork_func) (*pthread_atfork_func)(NULL, NULL, set_skip_write); - s_worker_status->m_connected = 1; + __sync_lock_test_and_set(&s_worker_status->m_state, + LSAPI_STATE_CONNECTED); if (s_busy_workers) __sync_add_and_fetch(s_busy_workers, 1); lsapi_set_nblock( pReq->m_fd, 0 ); //keep it open if busy_count is used. - if (s_busy_workers && s_uid != 0) + if (s_busy_workers + && *s_busy_workers > (pServer->m_iMaxChildren >> 1)) s_keepListener = 1; - else if ( pReq->m_fdListen != -1 ) + if ((s_uid == 0 || !s_keepListener || !is_enough_free_mem()) + && pReq->m_fdListen != -1 ) { close( pReq->m_fdListen ); pReq->m_fdListen = -1; @@ -3295,6 +3379,9 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq ) timeout.tv_usec = 0; if (fd == pReq->m_fdListen) { + if (s_worker_status) + __sync_lock_test_and_set(&s_worker_status->m_state, + LSAPI_STATE_ACCEPTING); if (s_accepting_workers) __sync_fetch_and_add(s_accepting_workers, 1); } @@ -3303,6 +3390,9 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq ) { if (s_accepting_workers) __sync_fetch_and_sub(s_accepting_workers, 1); + if (s_worker_status) + __sync_lock_test_and_set(&s_worker_status->m_state, + LSAPI_STATE_IDLE); } if ( ret == 0 ) @@ -3310,7 +3400,8 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq ) if ( s_worker_status ) { s_worker_status->m_inProcess = 0; - if (fd == pReq->m_fdListen) + if (fd == pReq->m_fdListen + && (s_keepListener != 2 || !is_enough_free_mem())) return -1; } ++wait_secs; @@ -3337,7 +3428,8 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq ) if ( pReq->m_fd != -1 ) { if (s_worker_status) - s_worker_status->m_connected = 1; + __sync_lock_test_and_set(&s_worker_status->m_state, + LSAPI_STATE_CONNECTED); if (s_busy_workers) __sync_fetch_and_add(s_busy_workers, 1); @@ -3345,7 +3437,7 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq ) lsapi_set_nblock( fd, 0 ); //init_conn_key( pReq->m_fd ); - if ( !s_keepListener ) + if (!s_keepListener) { close( pReq->m_fdListen ); pReq->m_fdListen = -1; @@ -3611,6 +3703,7 @@ static int lsapi_reopen_stderr(const char *p) int LSAPI_Init_Env_Parameters( fn_select_t fp ) { const char *p; + char ch; int n; int avoidFork = 0; @@ -3632,10 +3725,28 @@ int LSAPI_Init_Env_Parameters( fn_select_t fp ) LSAPI_Set_Max_Reqs( n ); } + p = getenv( "LSAPI_KEEP_LISTEN" ); + if ( p ) + { + n = atoi( p ); + s_keepListener = n; + } + p = getenv( "LSAPI_AVOID_FORK" ); if ( p ) { avoidFork = atoi( p ); + if (avoidFork) + { + s_keepListener = 2; + ch = *(p + strlen(p) - 1); + if ( ch == 'G' || ch == 'g' ) + avoidFork *= 1024 * 1024 * 1024; + else if ( ch == 'M' || ch == 'm' ) + avoidFork *= 1024 * 1024; + if (avoidFork >= 1024 * 10240) + s_min_avail_pages = avoidFork / 4096; + } } p = getenv( "LSAPI_ACCEPT_NOTIFY" ); @@ -3670,14 +3781,6 @@ int LSAPI_Init_Env_Parameters( fn_select_t fp ) LSAPI_Set_Max_Idle( n ); } - p = getenv( "LSAPI_KEEP_LISTEN" ); - if ( p ) - { - n = atoi( p ); - s_keepListener = n; - } - - if ( LSAPI_Is_Listen() ) { n = 0; @@ -3688,7 +3791,7 @@ int LSAPI_Init_Env_Parameters( fn_select_t fp ) n = atoi( p ); if ( n > 1 ) { - LSAPI_Init_Prefork_Server( n, fp, avoidFork ); + LSAPI_Init_Prefork_Server( n, fp, avoidFork != 0 ); LSAPI_Set_Server_fd( g_req.m_fdListen ); } diff --git a/sapi/litespeed/lsapilib.h b/sapi/litespeed/lsapilib.h index 8619632e0b..f6e1f93067 100644 --- a/sapi/litespeed/lsapilib.h +++ b/sapi/litespeed/lsapilib.h @@ -265,6 +265,9 @@ static inline off_t LSAPI_GetReqBodyRemain_r( LSAPI_Request * pReq ) } +int LSAPI_End_Response_r(LSAPI_Request * pReq); + + int LSAPI_Is_Listen(void); @@ -348,6 +351,9 @@ static inline int LSAPI_SetRespStatus( int code ) static inline int LSAPI_ErrResponse( int code, const char ** pRespHeaders, const char * pBody, int bodyLen ) { return LSAPI_ErrResponse_r( &g_req, code, pRespHeaders, pBody, bodyLen ); } +static inline int LSAPI_End_Response(void) +{ return LSAPI_End_Response_r( &g_req ); } + int LSAPI_IsRunning(void); int LSAPI_CreateListenSock( const char * pBind, int backlog ); |