Skip to content

Commit f0f1388

Browse files
author
George Wang
committed
Merge branch 'PHP-7.3' into PHP-7.4
2 parents a345908 + 7f551c7 commit f0f1388

File tree

3 files changed

+153
-26
lines changed

3 files changed

+153
-26
lines changed

sapi/litespeed/lsapi_main.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ static int sapi_lsapi_activate()
448448
static sapi_module_struct lsapi_sapi_module =
449449
{
450450
"litespeed",
451-
"LiteSpeed V7.2",
451+
"LiteSpeed V7.3",
452452

453453
php_lsapi_startup, /* startup */
454454
php_module_shutdown_wrapper, /* shutdown */
@@ -1368,16 +1368,19 @@ ZEND_END_ARG_INFO()
13681368
PHP_FUNCTION(litespeed_request_headers);
13691369
PHP_FUNCTION(litespeed_response_headers);
13701370
PHP_FUNCTION(apache_get_modules);
1371+
PHP_FUNCTION(litespeed_finish_request);
13711372

13721373
PHP_MINFO_FUNCTION(litespeed);
13731374

13741375
static const zend_function_entry litespeed_functions[] = {
13751376
PHP_FE(litespeed_request_headers, arginfo_litespeed__void)
13761377
PHP_FE(litespeed_response_headers, arginfo_litespeed__void)
13771378
PHP_FE(apache_get_modules, arginfo_litespeed__void)
1379+
PHP_FE(litespeed_finish_request, arginfo_litespeed__void)
13781380
PHP_FALIAS(getallheaders, litespeed_request_headers, arginfo_litespeed__void)
13791381
PHP_FALIAS(apache_request_headers, litespeed_request_headers, arginfo_litespeed__void)
13801382
PHP_FALIAS(apache_response_headers, litespeed_response_headers, arginfo_litespeed__void)
1383+
PHP_FALIAS(fastcgi_finish_request, litespeed_finish_request, arginfo_litespeed__void)
13811384
{NULL, NULL, NULL}
13821385
};
13831386

@@ -1504,3 +1507,18 @@ PHP_FUNCTION(apache_get_modules)
15041507
}
15051508
}
15061509
/* }}} */
1510+
1511+
1512+
/* {{{ proto array litespeed_finish_request(void)
1513+
Flushes all response data to the client */
1514+
PHP_FUNCTION(litespeed_finish_request)
1515+
{
1516+
if (ZEND_NUM_ARGS() > 0) {
1517+
WRONG_PARAM_COUNT;
1518+
}
1519+
if (LSAPI_End_Response() != -1) {
1520+
RETURN_TRUE;
1521+
}
1522+
RETURN_FALSE;
1523+
}
1524+
/* }}} */

sapi/litespeed/lsapilib.c

Lines changed: 128 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5555
#include <fcntl.h>
5656
#include <limits.h>
5757
#include <sys/stat.h>
58+
#include <sched.h>
5859
#include <signal.h>
5960
#include <stdlib.h>
6061
#include <stdio.h>
@@ -115,18 +116,26 @@ typedef struct lsapi_MD5Context lsapi_MD5_CTX;
115116
#define LSAPI_ST_REQ_BODY 2
116117
#define LSAPI_ST_RESP_HEADER 4
117118
#define LSAPI_ST_RESP_BODY 8
119+
#define LSAPI_ST_BACKGROUND 16
118120

119121
#define LSAPI_RESP_BUF_SIZE 8192
120122
#define LSAPI_INIT_RESP_HEADER_LEN 4096
121123

124+
enum
125+
{
126+
LSAPI_STATE_IDLE,
127+
LSAPI_STATE_CONNECTED,
128+
LSAPI_STATE_ACCEPTING,
129+
};
130+
122131
typedef struct _lsapi_child_status
123132
{
124133
int m_pid;
125134
long m_tmStart;
126135

127136
volatile short m_iKillSent;
128137
volatile char m_inProcess;
129-
volatile char m_connected;
138+
volatile char m_state;
130139
volatile int m_iReqCounter;
131140

132141
volatile long m_tmWaitBegin;
@@ -158,6 +167,9 @@ static int s_max_busy_workers = -1;
158167
static char *s_stderr_log_path = NULL;
159168
static int s_stderr_is_pipe = 0;
160169
static int s_ignore_pid = -1;
170+
static size_t s_total_pages = 1;
171+
static size_t s_min_avail_pages = 256 * 1024;
172+
static size_t *s_avail_pages = &s_total_pages;
161173

162174
LSAPI_Request g_req =
163175
{ .m_fdListen = -1, .m_fd = -1 };
@@ -417,7 +429,7 @@ static void lsapi_close_connection(LSAPI_Request *pReq)
417429
if (s_busy_workers)
418430
__sync_fetch_and_sub(s_busy_workers, 1);
419431
if (s_worker_status)
420-
s_worker_status->m_connected = 0;
432+
__sync_lock_test_and_set(&s_worker_status->m_state, LSAPI_STATE_IDLE);
421433
}
422434

423435

@@ -1560,7 +1572,8 @@ int LSAPI_Accept_r( LSAPI_Request * pReq )
15601572
else
15611573
{
15621574
if (s_worker_status)
1563-
s_worker_status->m_connected = 1;
1575+
__sync_lock_test_and_set(&s_worker_status->m_state,
1576+
LSAPI_STATE_CONNECTED);
15641577
if (s_busy_workers)
15651578
__sync_fetch_and_add(s_busy_workers, 1);
15661579
lsapi_set_nblock( pReq->m_fd , 0 );
@@ -1623,6 +1636,37 @@ int LSAPI_Finish_r( LSAPI_Request * pReq )
16231636
}
16241637

16251638

1639+
int LSAPI_End_Response_r(LSAPI_Request * pReq)
1640+
{
1641+
if (!pReq)
1642+
return -1;
1643+
if (pReq->m_reqState)
1644+
{
1645+
if ( pReq->m_fd != -1 )
1646+
{
1647+
if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER )
1648+
{
1649+
LSAPI_FinalizeRespHeaders_r( pReq );
1650+
}
1651+
if ( pReq->m_pRespBufPos != pReq->m_pRespBuf )
1652+
{
1653+
Flush_RespBuf_r( pReq );
1654+
}
1655+
1656+
pReq->m_pIovecCur->iov_base = (void *)&finish;
1657+
pReq->m_pIovecCur->iov_len = LSAPI_PACKET_HEADER_LEN;
1658+
pReq->m_totalLen += LSAPI_PACKET_HEADER_LEN;
1659+
++pReq->m_pIovecCur;
1660+
LSAPI_Flush_r( pReq );
1661+
}
1662+
send_conn_close_notification(pReq->m_fd);
1663+
lsapi_close_connection(pReq);
1664+
pReq->m_reqState |= LSAPI_ST_BACKGROUND;
1665+
}
1666+
return 0;
1667+
}
1668+
1669+
16261670
void LSAPI_Reset_r( LSAPI_Request * pReq )
16271671
{
16281672
pReq->m_pRespBufPos = pReq->m_pRespBuf;
@@ -1808,7 +1852,11 @@ ssize_t LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, size_t len )
18081852
ssize_t packetLen;
18091853
int skip = 0;
18101854

1811-
if ( !pReq || !pBuf || (pReq->m_fd == -1) )
1855+
if (!pReq || !pBuf)
1856+
return -1;
1857+
if (pReq->m_reqState & LSAPI_ST_BACKGROUND)
1858+
return len;
1859+
if (pReq->m_fd == -1)
18121860
return -1;
18131861
if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER )
18141862
{
@@ -2710,6 +2758,9 @@ int LSAPI_Init_Prefork_Server( int max_children, fn_select_t fp, int avoidFork )
27102758
s_ppid = getppid();
27112759
s_pid = getpid();
27122760
setpgid( s_pid, s_pid );
2761+
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__)
2762+
s_total_pages = sysconf(_SC_PHYS_PAGES);
2763+
#endif
27132764
g_prefork_server->m_iAvoidFork = avoidFork;
27142765
g_prefork_server->m_iMaxChildren = max_children;
27152766

@@ -2844,11 +2895,19 @@ static void lsapi_sigchild( int signal )
28442895
child_status = find_child_status( pid );
28452896
if ( child_status )
28462897
{
2847-
if (child_status->m_connected)
2898+
if (__sync_bool_compare_and_swap(&child_status->m_state,
2899+
LSAPI_STATE_CONNECTED,
2900+
LSAPI_STATE_IDLE))
28482901
{
28492902
if (s_busy_workers)
28502903
__sync_fetch_and_sub(s_busy_workers, 1);
2851-
child_status->m_connected = 0;
2904+
}
2905+
else if (__sync_bool_compare_and_swap(&child_status->m_state,
2906+
LSAPI_STATE_ACCEPTING,
2907+
LSAPI_STATE_IDLE))
2908+
{
2909+
if (s_accepting_workers)
2910+
__sync_fetch_and_sub(s_accepting_workers, 1);
28522911
}
28532912
child_status->m_pid = 0;
28542913
--g_prefork_server->m_iCurChildren;
@@ -2884,6 +2943,7 @@ static int lsapi_init_children_status(void)
28842943
s_busy_workers = (int *)g_prefork_server->m_pChildrenStatusEnd;
28852944
s_accepting_workers = s_busy_workers + 1;
28862945
s_global_counter = s_accepting_workers + 1;
2946+
s_avail_pages = (size_t *)(s_global_counter + 1);
28872947
return 0;
28882948
}
28892949

@@ -3023,6 +3083,17 @@ void set_skip_write()
30233083
{ s_skip_write = 1; }
30243084

30253085

3086+
int is_enough_free_mem()
3087+
{
3088+
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__)
3089+
//minimum 1GB or 10% available free memory
3090+
return (*s_avail_pages > s_min_avail_pages
3091+
|| (*s_avail_pages * 10) / s_total_pages > 0);
3092+
#endif
3093+
return 1;
3094+
}
3095+
3096+
30263097
static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer,
30273098
LSAPI_Request * pReq )
30283099
{
@@ -3092,18 +3163,28 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer,
30923163
}
30933164
}
30943165

3166+
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__)
3167+
*s_avail_pages = sysconf(_SC_AVPHYS_PAGES);
3168+
lsapi_log("Memory total: %zd, free: %zd, free %%%zd\n",
3169+
s_total_pages, *s_avail_pages, *s_avail_pages * 100 / s_total_pages);
3170+
3171+
#endif
30953172
FD_ZERO( &readfds );
30963173
FD_SET( pServer->m_fd, &readfds );
30973174
timeout.tv_sec = 1;
30983175
timeout.tv_usec = 0;
30993176
ret = (*g_fnSelect)(pServer->m_fd+1, &readfds, NULL, NULL, &timeout);
31003177
if (ret == 1 )
31013178
{
3102-
if (pServer->m_iCurChildren >= pServer->m_iMaxChildren
3103-
&& s_accepting_workers
3104-
&& (ret = __sync_add_and_fetch(s_accepting_workers, 0)) > 0)
3179+
int accepting = 0;
3180+
if (s_accepting_workers)
3181+
accepting = __sync_add_and_fetch(s_accepting_workers, 0);
3182+
3183+
if (pServer->m_iCurChildren > 0 && accepting > 0)
31053184
{
3106-
usleep( 200 );
3185+
usleep(400);
3186+
while(accepting-- > 0)
3187+
sched_yield();
31073188
continue;
31083189
}
31093190
}
@@ -3164,14 +3245,17 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer,
31643245
if (pthread_atfork_func)
31653246
(*pthread_atfork_func)(NULL, NULL, set_skip_write);
31663247

3167-
s_worker_status->m_connected = 1;
3248+
__sync_lock_test_and_set(&s_worker_status->m_state,
3249+
LSAPI_STATE_CONNECTED);
31683250
if (s_busy_workers)
31693251
__sync_add_and_fetch(s_busy_workers, 1);
31703252
lsapi_set_nblock( pReq->m_fd, 0 );
31713253
//keep it open if busy_count is used.
3172-
if (s_busy_workers && s_uid != 0)
3254+
if (s_busy_workers
3255+
&& *s_busy_workers > (pServer->m_iMaxChildren >> 1))
31733256
s_keepListener = 1;
3174-
else if ( pReq->m_fdListen != -1 )
3257+
if ((s_uid == 0 || !s_keepListener || !is_enough_free_mem())
3258+
&& pReq->m_fdListen != -1 )
31753259
{
31763260
close( pReq->m_fdListen );
31773261
pReq->m_fdListen = -1;
@@ -3297,6 +3381,9 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq )
32973381
timeout.tv_usec = 0;
32983382
if (fd == pReq->m_fdListen)
32993383
{
3384+
if (s_worker_status)
3385+
__sync_lock_test_and_set(&s_worker_status->m_state,
3386+
LSAPI_STATE_ACCEPTING);
33003387
if (s_accepting_workers)
33013388
__sync_fetch_and_add(s_accepting_workers, 1);
33023389
}
@@ -3305,14 +3392,18 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq )
33053392
{
33063393
if (s_accepting_workers)
33073394
__sync_fetch_and_sub(s_accepting_workers, 1);
3395+
if (s_worker_status)
3396+
__sync_lock_test_and_set(&s_worker_status->m_state,
3397+
LSAPI_STATE_IDLE);
33083398
}
33093399

33103400
if ( ret == 0 )
33113401
{
33123402
if ( s_worker_status )
33133403
{
33143404
s_worker_status->m_inProcess = 0;
3315-
if (fd == pReq->m_fdListen)
3405+
if (fd == pReq->m_fdListen
3406+
&& (s_keepListener != 2 || !is_enough_free_mem()))
33163407
return -1;
33173408
}
33183409
++wait_secs;
@@ -3339,15 +3430,16 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq )
33393430
if ( pReq->m_fd != -1 )
33403431
{
33413432
if (s_worker_status)
3342-
s_worker_status->m_connected = 1;
3433+
__sync_lock_test_and_set(&s_worker_status->m_state,
3434+
LSAPI_STATE_CONNECTED);
33433435
if (s_busy_workers)
33443436
__sync_fetch_and_add(s_busy_workers, 1);
33453437

33463438
fd = pReq->m_fd;
33473439

33483440
lsapi_set_nblock( fd, 0 );
33493441
//init_conn_key( pReq->m_fd );
3350-
if ( !s_keepListener )
3442+
if (!s_keepListener)
33513443
{
33523444
close( pReq->m_fdListen );
33533445
pReq->m_fdListen = -1;
@@ -3613,6 +3705,7 @@ static int lsapi_reopen_stderr(const char *p)
36133705
int LSAPI_Init_Env_Parameters( fn_select_t fp )
36143706
{
36153707
const char *p;
3708+
char ch;
36163709
int n;
36173710
int avoidFork = 0;
36183711

@@ -3634,10 +3727,28 @@ int LSAPI_Init_Env_Parameters( fn_select_t fp )
36343727
LSAPI_Set_Max_Reqs( n );
36353728
}
36363729

3730+
p = getenv( "LSAPI_KEEP_LISTEN" );
3731+
if ( p )
3732+
{
3733+
n = atoi( p );
3734+
s_keepListener = n;
3735+
}
3736+
36373737
p = getenv( "LSAPI_AVOID_FORK" );
36383738
if ( p )
36393739
{
36403740
avoidFork = atoi( p );
3741+
if (avoidFork)
3742+
{
3743+
s_keepListener = 2;
3744+
ch = *(p + strlen(p) - 1);
3745+
if ( ch == 'G' || ch == 'g' )
3746+
avoidFork *= 1024 * 1024 * 1024;
3747+
else if ( ch == 'M' || ch == 'm' )
3748+
avoidFork *= 1024 * 1024;
3749+
if (avoidFork >= 1024 * 10240)
3750+
s_min_avail_pages = avoidFork / 4096;
3751+
}
36413752
}
36423753

36433754
p = getenv( "LSAPI_ACCEPT_NOTIFY" );
@@ -3672,14 +3783,6 @@ int LSAPI_Init_Env_Parameters( fn_select_t fp )
36723783
LSAPI_Set_Max_Idle( n );
36733784
}
36743785

3675-
p = getenv( "LSAPI_KEEP_LISTEN" );
3676-
if ( p )
3677-
{
3678-
n = atoi( p );
3679-
s_keepListener = n;
3680-
}
3681-
3682-
36833786
if ( LSAPI_Is_Listen() )
36843787
{
36853788
n = 0;
@@ -3690,7 +3793,7 @@ int LSAPI_Init_Env_Parameters( fn_select_t fp )
36903793
n = atoi( p );
36913794
if ( n > 1 )
36923795
{
3693-
LSAPI_Init_Prefork_Server( n, fp, avoidFork );
3796+
LSAPI_Init_Prefork_Server( n, fp, avoidFork != 0 );
36943797
LSAPI_Set_Server_fd( g_req.m_fdListen );
36953798
}
36963799

0 commit comments

Comments
 (0)