mirror of
https://github.com/php/php-src.git
synced 2024-11-28 20:34:29 +08:00
LiteSpeed SAPI 7.3, better process management, new API function litespeed_finish_request().
This commit is contained in:
parent
d07a6fdedf
commit
1e7f1b90e8
@ -466,7 +466,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 */
|
||||
@ -1394,6 +1394,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);
|
||||
|
||||
@ -1401,9 +1402,11 @@ 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}
|
||||
};
|
||||
|
||||
@ -1532,6 +1535,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
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
|
@ -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 );
|
||||
|
Loading…
Reference in New Issue
Block a user