ruby-lsapi 4.4 → 5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: fb7c17d4bad59b5058a4683b2c07d8abfadc9e36
4
- data.tar.gz: 0836a55ff1392b8dc1052b2f83732e9b8f992c94
2
+ SHA256:
3
+ metadata.gz: d4a6919e0d321057af7cf14393996e0363f79078d81f7246bc763c6111f9b4fa
4
+ data.tar.gz: fb8fbce714f668d4b974bccce18f48b384a491011d4e2172f3c8635e00f10cbf
5
5
  SHA512:
6
- metadata.gz: 417955426a67c9a0a9802a4d18a6ac6d075d8b81a7b01adcf2f4e217b0e15a6b7a0b4cec3bcf40e595e39a89809328840880c860c3907aeab8b08ac83b799436
7
- data.tar.gz: a0499088de40de67681b2aa0c94ef2fb2248568e7aa9d5c00f668daef3a020e9513c22cf9e2f746ed9eed6d1c2ec1fbb72166930c2b1b0a447fa549753206481
6
+ metadata.gz: 673a3a93b519d8d54171ff6430970669c8ad23fa023ff8f1a3f774b446b54f171a8027a89c2f6c4acd5d0a7c00f394d225d8d58736accb5b528f731a50b285be
7
+ data.tar.gz: bc5907c83c66ed42af04b60ef5977dc01603e2c210fb5d36b8904303193a6ae537213ae9a1c92ada2a9f89efb873bf470525ae2357edf215d8f2db308b1d80cb
@@ -1,21 +1,21 @@
1
1
  /*
2
- Copyright (c) 2002-2015, Lite Speed Technologies Inc.
2
+ Copyright (c) 2002-2018, Lite Speed Technologies Inc.
3
3
  All rights reserved.
4
4
 
5
5
  Redistribution and use in source and binary forms, with or without
6
6
  modification, are permitted provided that the following conditions are
7
- met:
7
+ met:
8
8
 
9
9
  * Redistributions of source code must retain the above copyright
10
- notice, this list of conditions and the following disclaimer.
10
+ notice, this list of conditions and the following disclaimer.
11
11
  * Redistributions in binary form must reproduce the above
12
12
  copyright notice, this list of conditions and the following
13
13
  disclaimer in the documentation and/or other materials provided
14
- with the distribution.
14
+ with the distribution.
15
15
  * Neither the name of the Lite Speed Technologies Inc nor the
16
16
  names of its contributors may be used to endorse or promote
17
17
  products derived from this software without specific prior
18
- written permission.
18
+ written permission.
19
19
 
20
20
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
21
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -27,7 +27,7 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
27
  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
28
  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
29
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
31
  */
32
32
 
33
33
 
@@ -76,7 +76,7 @@ enum
76
76
 
77
77
  /* Values for m_flag in lsapi_packet_header */
78
78
  #define LSAPI_ENDIAN_LITTLE 0
79
- #define LSAPI_ENDIAN_BIG 1
79
+ #define LSAPI_ENDIAN_BIG 1
80
80
  #define LSAPI_ENDIAN_BIT 1
81
81
 
82
82
  #if defined(__i386__)||defined( __x86_64 )||defined( __x86_64__ )
@@ -119,7 +119,7 @@ struct lsapi_packet_header
119
119
 
120
120
  /*
121
121
  LSAPI request header packet
122
-
122
+
123
123
  1. struct lsapi_req_header
124
124
  2. struct lsapi_http_header_index
125
125
  3. lsapi_header_offset * unknownHeaders
@@ -130,7 +130,7 @@ struct lsapi_packet_header
130
130
  struct lsapi_req_header
131
131
  {
132
132
  struct lsapi_packet_header m_pktHeader;
133
-
133
+
134
134
  int32_t m_httpHeaderLen;
135
135
  int32_t m_reqBodyLen;
136
136
  int32_t m_scriptFileOff; /* path to the script file. */
@@ -144,11 +144,11 @@ struct lsapi_req_header
144
144
 
145
145
 
146
146
  struct lsapi_http_header_index
147
- {
148
- int16_t m_headerLen[H_TRANSFER_ENCODING+1];
147
+ {
148
+ uint16_t m_headerLen[H_TRANSFER_ENCODING+1];
149
149
  int32_t m_headerOff[H_TRANSFER_ENCODING+1];
150
- } ;
151
-
150
+ } ;
151
+
152
152
  struct lsapi_header_offset
153
153
  {
154
154
  int32_t nameOff;
@@ -1,5 +1,6 @@
1
+ //#define LSAPI_DEBUG
1
2
  /*
2
- Copyright (c) 2002-2015, Lite Speed Technologies Inc.
3
+ Copyright (c) 2002-2018, Lite Speed Technologies Inc.
3
4
  All rights reserved.
4
5
 
5
6
  Redistribution and use in source and binary forms, with or without
@@ -37,9 +38,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37
38
  #include <fcntl.h>
38
39
  #include <limits.h>
39
40
  #include <sys/stat.h>
41
+ #include <sched.h>
40
42
  #include <signal.h>
41
43
  #include <stdlib.h>
42
44
  #include <stdio.h>
45
+ #include <stdarg.h>
43
46
  #include <string.h>
44
47
  #include <sys/mman.h>
45
48
  #include <sys/resource.h>
@@ -94,18 +97,26 @@ typedef struct lsapi_MD5Context lsapi_MD5_CTX;
94
97
  #define LSAPI_ST_REQ_BODY 2
95
98
  #define LSAPI_ST_RESP_HEADER 4
96
99
  #define LSAPI_ST_RESP_BODY 8
100
+ #define LSAPI_ST_BACKGROUND 16
97
101
 
98
102
  #define LSAPI_RESP_BUF_SIZE 8192
99
103
  #define LSAPI_INIT_RESP_HEADER_LEN 4096
100
104
 
101
- typedef struct _lsapi_child_status
105
+ enum
106
+ {
107
+ LSAPI_STATE_IDLE,
108
+ LSAPI_STATE_CONNECTED,
109
+ LSAPI_STATE_ACCEPTING,
110
+ };
111
+
112
+ typedef struct lsapi_child_status
102
113
  {
103
114
  int m_pid;
104
115
  long m_tmStart;
105
116
 
106
117
  volatile short m_iKillSent;
107
118
  volatile char m_inProcess;
108
- volatile char m_connected;
119
+ volatile char m_state;
109
120
  volatile int m_iReqCounter;
110
121
 
111
122
  volatile long m_tmWaitBegin;
@@ -114,28 +125,43 @@ typedef struct _lsapi_child_status
114
125
  }
115
126
  lsapi_child_status;
116
127
 
117
- static lsapi_child_status * s_pChildStatus = NULL;
128
+ static lsapi_child_status * s_worker_status = NULL;
118
129
 
119
130
  static int g_inited = 0;
120
131
  static int g_running = 1;
121
132
  static int s_ppid;
133
+ static int s_restored_ppid = 0;
134
+ static int s_pid = 0;
122
135
  static int s_slow_req_msecs = 0;
123
136
  static int s_keepListener = 0;
124
137
  static int s_dump_debug_info = 0;
125
138
  static int s_pid_dump_debug_info = 0;
139
+ static int s_req_processed = 0;
140
+ static int s_skip_write = 0;
141
+ static int (*pthread_atfork_func)(void (*prepare)(void), void (*parent)(void),
142
+ void (*child)(void)) = NULL;
126
143
 
127
144
  static int *s_busy_workers = NULL;
128
- static int s_max_busy_children = -1;
129
-
130
- LSAPI_Request g_req = { -1, -1 };
145
+ static int *s_accepting_workers = NULL;
146
+ static int *s_global_counter = &s_req_processed;
147
+ static int s_max_busy_workers = -1;
148
+ static char *s_stderr_log_path = NULL;
149
+ static int s_stderr_is_pipe = 0;
150
+ static int s_ignore_pid = -1;
151
+ static size_t s_total_pages = 1;
152
+ static size_t s_min_avail_pages = 256 * 1024;
153
+ static size_t *s_avail_pages = &s_total_pages;
154
+
155
+ LSAPI_Request g_req =
156
+ { .m_fdListen = -1, .m_fd = -1 };
131
157
 
132
158
  static char s_secret[24];
133
- static char *s_pStderrLog = NULL;
159
+
160
+ static LSAPI_On_Timer_pf s_proc_group_timer_cb = NULL;
134
161
 
135
162
  void Flush_RespBuf_r( LSAPI_Request * pReq );
136
163
  static int lsapi_reopen_stderr(const char *p);
137
164
 
138
-
139
165
  static const char *CGI_HEADERS[H_TRANSFER_ENCODING+1] =
140
166
  {
141
167
  "HTTP_ACCEPT", "HTTP_ACCEPT_CHARSET",
@@ -188,9 +214,95 @@ static int HTTP_HEADER_LEN[H_TRANSFER_ENCODING+1] =
188
214
  13,17, 8, 13, 8, 19, 10, 5, 15, 3, 17
189
215
  };
190
216
 
217
+
218
+ static const char *s_log_level_names[8] =
219
+ {
220
+ "", "DEBUG","INFO", "NOTICE", "WARN", "ERROR", "CRIT", "FATAL"
221
+ };
222
+
223
+
224
+ void LSAPI_Log(int flag, const char * fmt, ...)
225
+ {
226
+ char buf[1024];
227
+ char *p = buf;
228
+ if ((flag & LSAPI_LOG_TIMESTAMP_BITS) &&
229
+ !((flag & LSAPI_LOG_TIMESTAMP_STDERR) && s_stderr_is_pipe))
230
+ {
231
+ struct timeval tv;
232
+ struct tm tm;
233
+ gettimeofday(&tv, NULL);
234
+ localtime_r(&tv.tv_sec, &tm);
235
+ if (flag & LSAPI_LOG_TIMESTAMP_FULL)
236
+ {
237
+ p += snprintf(p, 1024, "%04d-%02d-%02d %02d:%02d:%02d.%06d ",
238
+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
239
+ tm.tm_hour, tm.tm_min, tm.tm_sec, (int)tv.tv_usec);
240
+ }
241
+ else if (flag & LSAPI_LOG_TIMESTAMP_HMS)
242
+ {
243
+ p += snprintf(p, 1024, "%02d:%02d:%02d ",
244
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
245
+ }
246
+ }
247
+
248
+ int level = flag & LSAPI_LOG_LEVEL_BITS;
249
+ if (level && level <= LSAPI_LOG_FLAG_FATAL)
250
+ {
251
+ p += snprintf(p, 100, "[%s] ", s_log_level_names[level]);
252
+ }
253
+
254
+ if (flag & LSAPI_LOG_PID)
255
+ {
256
+ p += snprintf(p, 100, "[%d] ", s_pid);
257
+ }
258
+
259
+ if (p > buf)
260
+ fprintf(stderr, "%.*s", (int)(p - buf), buf);
261
+ va_list ap;
262
+ va_start(ap, fmt);
263
+ vfprintf(stderr, fmt, ap);
264
+ va_end(ap);
265
+ }
266
+
267
+ #ifdef LSAPI_DEBUG
268
+
269
+ #define DBGLOG_FLAG (LSAPI_LOG_TIMESTAMP_FULL|LSAPI_LOG_FLAG_DEBUG|LSAPI_LOG_PID)
270
+ #define lsapi_dbg(...) LSAPI_Log(DBGLOG_FLAG, __VA_ARGS__)
271
+
272
+ #else
273
+
274
+ #define lsapi_dbg(...)
275
+
276
+ #endif
277
+
278
+ #define lsapi_log(...) LSAPI_Log(LSAPI_LOG_TIMESTAMP_FULL|LSAPI_LOG_TIMESTAMP_STDERR|LSAPI_LOG_PID, __VA_ARGS__)
279
+
280
+
281
+ static int lsapi_parent_dead()
282
+ {
283
+ // Return non-zero if the parent is dead. 0 if still alive.
284
+ if (!s_ppid) {
285
+ // not checking, so not dead
286
+ return(0);
287
+ }
288
+ if (s_restored_ppid) {
289
+ if (kill(s_restored_ppid,0) == -1) {
290
+ if (errno == EPERM) {
291
+ return(0); // no permission, but it's still there.
292
+ }
293
+ return(1); // Dead
294
+ }
295
+ return(0); // it worked, so it's not dead
296
+ }
297
+ return(s_ppid != getppid());
298
+ }
299
+
300
+
191
301
  static void lsapi_sigpipe( int sig )
192
302
  {
193
303
  }
304
+
305
+
194
306
  static void lsapi_siguser1( int sig )
195
307
  {
196
308
  g_running = 0;
@@ -254,6 +366,7 @@ static inline void lsapi_buildPacketHeader( struct lsapi_packet_header * pHeader
254
366
  pHeader->m_packetLen.m_iLen = len;
255
367
  }
256
368
 
369
+
257
370
  static int lsapi_set_nblock( int fd, int nonblock )
258
371
  {
259
372
  int val = fcntl( fd, F_GETFL, 0 );
@@ -274,6 +387,7 @@ static int lsapi_set_nblock( int fd, int nonblock )
274
387
  return 0;
275
388
  }
276
389
 
390
+
277
391
  static int lsapi_close( int fd )
278
392
  {
279
393
  int ret;
@@ -295,9 +409,9 @@ static void lsapi_close_connection(LSAPI_Request *pReq)
295
409
  pReq->m_fd = -1;
296
410
  if (s_busy_workers)
297
411
  __sync_fetch_and_sub(s_busy_workers, 1);
298
- if (s_pChildStatus)
299
- s_pChildStatus->m_connected = 0;
300
- }
412
+ if (s_worker_status)
413
+ __sync_lock_test_and_set(&s_worker_status->m_state, LSAPI_STATE_IDLE);
414
+ }
301
415
 
302
416
 
303
417
  static inline ssize_t lsapi_read( int fd, void * pBuf, size_t len )
@@ -312,6 +426,7 @@ static inline ssize_t lsapi_read( int fd, void * pBuf, size_t len )
312
426
  }
313
427
  }
314
428
 
429
+
315
430
  /*
316
431
  static int lsapi_write( int fd, const void * pBuf, int len )
317
432
  {
@@ -334,11 +449,16 @@ static int lsapi_write( int fd, const void * pBuf, int len )
334
449
  }
335
450
  */
336
451
 
452
+
337
453
  static int lsapi_writev( int fd, struct iovec ** pVec, int count, int totalLen )
338
454
  {
339
455
  int ret;
340
456
  int left = totalLen;
341
457
  int n = count;
458
+
459
+ if (s_skip_write)
460
+ return totalLen;
461
+
342
462
  while(( left > 0 )&&g_running )
343
463
  {
344
464
  ret = writev( fd, *pVec, n );
@@ -378,6 +498,7 @@ static int lsapi_writev( int fd, struct iovec ** pVec, int count, int totalLen )
378
498
  return totalLen - left;
379
499
  }
380
500
 
501
+
381
502
  /*
382
503
  static int getTotalLen( struct iovec * pVec, int count )
383
504
  {
@@ -392,6 +513,7 @@ static int getTotalLen( struct iovec * pVec, int count )
392
513
  }
393
514
  */
394
515
 
516
+
395
517
  static inline int allocateBuf( LSAPI_Request * pReq, int size )
396
518
  {
397
519
  char * pBuf = (char *)realloc( pReq->m_pReqBuf, size );
@@ -419,6 +541,7 @@ static int allocateIovec( LSAPI_Request * pReq, int n )
419
541
  return 0;
420
542
  }
421
543
 
544
+
422
545
  static int allocateRespHeaderBuf( LSAPI_Request * pReq, int size )
423
546
  {
424
547
  char * p = (char *)realloc( pReq->m_pRespHeaderBuf, size );
@@ -450,6 +573,7 @@ static inline int verifyHeader( struct lsapi_packet_header * pHeader, char pktTy
450
573
  return pHeader->m_packetLen.m_iLen;
451
574
  }
452
575
 
576
+
453
577
  static int allocateEnvList( struct LSAPI_key_value_pair ** pEnvList,
454
578
  int *curSize, int newSize )
455
579
  {
@@ -471,6 +595,7 @@ static int allocateEnvList( struct LSAPI_key_value_pair ** pEnvList,
471
595
 
472
596
  }
473
597
 
598
+
474
599
  static inline int isPipe( int fd )
475
600
  {
476
601
  char achPeer[128];
@@ -482,6 +607,7 @@ static inline int isPipe( int fd )
482
607
  return 1;
483
608
  }
484
609
 
610
+
485
611
  static int parseEnv( struct LSAPI_key_value_pair * pEnvList, int count,
486
612
  char **pBegin, char * pEnd )
487
613
  {
@@ -518,6 +644,7 @@ static int parseEnv( struct LSAPI_key_value_pair * pEnvList, int count,
518
644
  return 0;
519
645
  }
520
646
 
647
+
521
648
  static inline void swapIntEndian( int * pInteger )
522
649
  {
523
650
  char * p = (char *)pInteger;
@@ -531,6 +658,7 @@ static inline void swapIntEndian( int * pInteger )
531
658
 
532
659
  }
533
660
 
661
+
534
662
  static inline void fixEndian( LSAPI_Request * pReq )
535
663
  {
536
664
  struct lsapi_req_header *p= pReq->m_pHeader;
@@ -545,6 +673,7 @@ static inline void fixEndian( LSAPI_Request * pReq )
545
673
  swapIntEndian( &p->m_cntSpecialEnv );
546
674
  }
547
675
 
676
+
548
677
  static void fixHeaderIndexEndian( LSAPI_Request * pReq )
549
678
  {
550
679
  int i;
@@ -633,7 +762,7 @@ static int (*fp_lve_leave)(struct liblve *, uint32_t *) = NULL;
633
762
  static int (*fp_lve_jail)( struct passwd *, char *) = NULL;
634
763
  static int lsapi_load_lve_lib(void)
635
764
  {
636
- s_liblve = dlopen("liblve.so.0", RTLD_LAZY);
765
+ s_liblve = dlopen("liblve.so.0", RTLD_NOW | RTLD_GLOBAL);
637
766
  if (s_liblve)
638
767
  {
639
768
  fp_lve_is_available = dlsym(s_liblve, "lve_is_available");
@@ -644,10 +773,10 @@ static int lsapi_load_lve_lib(void)
644
773
  int uid = getuid();
645
774
  if ( uid )
646
775
  {
647
- setreuid( s_uid, uid );
776
+ if (setreuid( s_uid, uid )) {};
648
777
  if ( !(*fp_lve_is_available)() )
649
778
  s_enable_lve = 0;
650
- setreuid( uid, s_uid );
779
+ if (setreuid( uid, s_uid )) {};
651
780
  }
652
781
  }
653
782
  }
@@ -659,6 +788,7 @@ static int lsapi_load_lve_lib(void)
659
788
  return (s_liblve)? 0 : -1;
660
789
  }
661
790
 
791
+
662
792
  static int init_lve_ex(void)
663
793
  {
664
794
  int rc;
@@ -698,32 +828,32 @@ static int readSecret( const char * pSecretFile )
698
828
  int fd = open( pSecretFile, O_RDONLY , 0600 );
699
829
  if ( fd == -1 )
700
830
  {
701
- fprintf( stderr, "LSAPI: failed to open secret file: %s!\n", pSecretFile );
831
+ lsapi_log("LSAPI: failed to open secret file: %s!\n", pSecretFile );
702
832
  return -1;
703
833
  }
704
834
  if ( fstat( fd, &st ) == -1 )
705
835
  {
706
- fprintf( stderr, "LSAPI: failed to check state of file: %s!\n", pSecretFile );
836
+ lsapi_log("LSAPI: failed to check state of file: %s!\n", pSecretFile );
707
837
  close( fd );
708
838
  return -1;
709
839
  }
710
840
  /*
711
841
  if ( st.st_uid != s_uid )
712
842
  {
713
- fprintf( stderr, "LSAPI: file owner check failure: %s!\n", pSecretFile );
843
+ lsapi_log("LSAPI: file owner check failure: %s!\n", pSecretFile );
714
844
  close( fd );
715
845
  return -1;
716
846
  }
717
847
  */
718
848
  if ( st.st_mode & 0077 )
719
849
  {
720
- fprintf( stderr, "LSAPI: file permission check failure: %s\n", pSecretFile );
850
+ lsapi_log("LSAPI: file permission check failure: %s\n", pSecretFile );
721
851
  close( fd );
722
852
  return -1;
723
853
  }
724
854
  if ( read( fd, s_secret, 16 ) < 16 )
725
855
  {
726
- fprintf( stderr, "LSAPI: failed to read secret from secret file: %s\n", pSecretFile );
856
+ lsapi_log("LSAPI: failed to read secret from secret file: %s\n", pSecretFile );
727
857
  close( fd );
728
858
  return -1;
729
859
  }
@@ -731,6 +861,7 @@ static int readSecret( const char * pSecretFile )
731
861
  return 0;
732
862
  }
733
863
 
864
+
734
865
  int LSAPI_is_suEXEC_Daemon(void)
735
866
  {
736
867
  if (( !s_uid )&&( s_secret[0] ))
@@ -739,20 +870,22 @@ int LSAPI_is_suEXEC_Daemon(void)
739
870
  return 0;
740
871
  }
741
872
 
873
+
742
874
  static int LSAPI_perror_r( LSAPI_Request * pReq, const char * pErr1, const char *pErr2 )
743
875
  {
744
876
  char achError[4096];
745
877
  int n = snprintf(achError, sizeof(achError), "[%d] %s:%s: %s\n", getpid(),
746
878
  pErr1, (pErr2)?pErr2:"", strerror(errno));
747
- if (n > sizeof(achError))
879
+ if (n > (int)sizeof(achError))
748
880
  n = sizeof(achError);
749
881
  if ( pReq )
750
882
  LSAPI_Write_Stderr_r( pReq, achError, n );
751
883
  else
752
- write( STDERR_FILENO, achError, n );
884
+ if (write( STDERR_FILENO, achError, n )) {};
753
885
  return 0;
754
886
  }
755
887
 
888
+
756
889
  static int lsapi_lve_error( LSAPI_Request * pReq )
757
890
  {
758
891
  static const char * headers[] =
@@ -776,6 +909,7 @@ static int lsapi_lve_error( LSAPI_Request * pReq )
776
909
  return 0;
777
910
  }
778
911
 
912
+
779
913
  static int lsapi_enterLVE( LSAPI_Request * pReq, uid_t uid )
780
914
  {
781
915
  #if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__)
@@ -786,7 +920,7 @@ static int lsapi_enterLVE( LSAPI_Request * pReq, uid_t uid )
786
920
  ret = (*fp_lve_enter)(s_lve, uid, -1, -1, &cookie);
787
921
  if ( ret < 0 )
788
922
  {
789
- fprintf( stderr, "Pid (%d): enter LVE (%d) : ressult: %d !\n", getpid(), uid, ret );
923
+ //lsapi_log("enter LVE (%d) : ressult: %d !\n", uid, ret );
790
924
  LSAPI_perror_r(pReq, "LSAPI: lve_enter() failure, reached resource limit.", NULL );
791
925
  lsapi_lve_error( pReq );
792
926
  return -1;
@@ -797,6 +931,7 @@ static int lsapi_enterLVE( LSAPI_Request * pReq, uid_t uid )
797
931
  return 0;
798
932
  }
799
933
 
934
+
800
935
  static int lsapi_jailLVE( LSAPI_Request * pReq, uid_t uid, struct passwd * pw )
801
936
  {
802
937
  int ret = 0;
@@ -805,8 +940,8 @@ static int lsapi_jailLVE( LSAPI_Request * pReq, uid_t uid, struct passwd * pw )
805
940
  ret = (*fp_lve_jail)( pw, error_msg );
806
941
  if ( ret < 0 )
807
942
  {
808
- fprintf( stderr, "LSAPI (%d): LVE jail(%d) ressult: %d, error: %s !\n",
809
- getpid(), uid, ret, error_msg );
943
+ lsapi_log("LSAPI: LVE jail(%d) ressult: %d, error: %s !\n",
944
+ uid, ret, error_msg );
810
945
  LSAPI_perror_r( pReq, "LSAPI: jail() failure.", NULL );
811
946
  return -1;
812
947
  }
@@ -973,11 +1108,11 @@ static int lsapi_changeUGid( LSAPI_Request * pReq )
973
1108
  --pReq->m_pHeader->m_cntSpecialEnv;
974
1109
  uid = *(uint32_t *)pEnv->pValue;
975
1110
  gid = *(((uint32_t *)pEnv->pValue) + 1 );
976
- //fprintf( stderr, "LSAPI: SUEXEC_UGID set UID: %d, GID: %d\n", uid, gid );
1111
+ //lsapi_log("LSAPI: SUEXEC_UGID set UID: %d, GID: %d\n", uid, gid );
977
1112
  }
978
1113
  else
979
1114
  {
980
- fprintf( stderr, "LSAPI: missing SUEXEC_UGID env, use default user!\n" );
1115
+ lsapi_log("LSAPI: missing SUEXEC_UGID env, use default user!\n" );
981
1116
  pEnv = NULL;
982
1117
  }
983
1118
  if ( pEnv&& lsapi_suexec_auth( pReq, pAuth->pValue, pAuth->valLen, pEnv->pValue, pEnv->valLen ) == 0 )
@@ -988,13 +1123,13 @@ static int lsapi_changeUGid( LSAPI_Request * pReq )
988
1123
  else
989
1124
  {
990
1125
  //authentication error
991
- fprintf( stderr, "LSAPI: SUEXEC_AUTH authentication failed, use default user!\n" );
1126
+ lsapi_log("LSAPI: SUEXEC_AUTH authentication failed, use default user!\n" );
992
1127
  uid = 0;
993
1128
  }
994
1129
  }
995
1130
  else
996
1131
  {
997
- //fprintf( stderr, "LSAPI: no SUEXEC_AUTH env, use default user!\n" );
1132
+ //lsapi_log("LSAPI: no SUEXEC_AUTH env, use default user!\n" );
998
1133
  }
999
1134
  }
1000
1135
 
@@ -1012,7 +1147,13 @@ static int lsapi_changeUGid( LSAPI_Request * pReq )
1012
1147
  }
1013
1148
 
1014
1149
  s_uid = uid;
1015
-
1150
+
1151
+ if ( pReq->m_fdListen != -1 )
1152
+ {
1153
+ close( pReq->m_fdListen );
1154
+ pReq->m_fdListen = -1;
1155
+ }
1156
+
1016
1157
  pStderrLog = LSAPI_GetEnv_r( pReq, "LSAPI_STDERR_LOG");
1017
1158
  if (pStderrLog)
1018
1159
  lsapi_reopen_stderr(pStderrLog);
@@ -1021,6 +1162,7 @@ static int lsapi_changeUGid( LSAPI_Request * pReq )
1021
1162
 
1022
1163
  }
1023
1164
 
1165
+
1024
1166
  static int parseContentLenFromHeader(LSAPI_Request * pReq)
1025
1167
  {
1026
1168
  const char * pContentLen = LSAPI_GetHeader_r( pReq, H_CONTENT_LENGTH );
@@ -1067,7 +1209,7 @@ static int parseRequest( LSAPI_Request * pReq, int totalLen )
1067
1209
  || pReq->m_pHeader->m_requestMethodOff < 0
1068
1210
  || pReq->m_pHeader->m_requestMethodOff >= totalLen)
1069
1211
  {
1070
- fprintf(stderr, "%d: bad request header - ERROR#1\n", getpid());
1212
+ lsapi_log("Bad request header - ERROR#1\n");
1071
1213
  return -1;
1072
1214
  }
1073
1215
  pReq->m_pScriptFile = pReq->m_pReqBuf + pReq->m_pHeader->m_scriptFileOff;
@@ -1087,8 +1229,8 @@ static int parseRequest( LSAPI_Request * pReq, int totalLen )
1087
1229
  pBegin += pReq->m_pHeader->m_httpHeaderLen;
1088
1230
  if ( pBegin != pEnd )
1089
1231
  {
1090
- fprintf( stderr, "%d: request header does match total size, total: %d, real: %ld\n", getpid(), totalLen,
1091
- pBegin - pReq->m_pReqBuf );
1232
+ lsapi_log("Request header does match total size, total: %d, "
1233
+ "real: %ld\n", totalLen, pBegin - pReq->m_pReqBuf );
1092
1234
  return -1;
1093
1235
  }
1094
1236
  if ( shouldFixEndian )
@@ -1098,7 +1240,7 @@ static int parseRequest( LSAPI_Request * pReq, int totalLen )
1098
1240
 
1099
1241
  if (validateHeaders(pReq) == -1)
1100
1242
  {
1101
- fprintf(stderr, "%d: bad request header - ERROR#2\n", getpid());
1243
+ lsapi_log("Bad request header - ERROR#2\n");
1102
1244
  return -1;
1103
1245
  }
1104
1246
 
@@ -1111,6 +1253,7 @@ static int parseRequest( LSAPI_Request * pReq, int totalLen )
1111
1253
  return 0;
1112
1254
  }
1113
1255
 
1256
+
1114
1257
  //OPTIMIZATION
1115
1258
  static char s_accept_notify = 0;
1116
1259
  static char s_schedule_notify = 0;
@@ -1119,26 +1262,41 @@ static char s_notified_pid = 0;
1119
1262
 
1120
1263
  static struct lsapi_packet_header s_ack = {'L', 'S',
1121
1264
  LSAPI_REQ_RECEIVED, LSAPI_ENDIAN, {LSAPI_PACKET_HEADER_LEN} };
1265
+ static struct lsapi_packet_header s_conn_close_pkt = {'L', 'S',
1266
+ LSAPI_CONN_CLOSE, LSAPI_ENDIAN, {LSAPI_PACKET_HEADER_LEN} };
1267
+
1122
1268
 
1123
-
1124
- static inline int write_req_received_notification( int fd )
1269
+ static inline int send_notification_pkt( int fd, struct lsapi_packet_header *pkt )
1125
1270
  {
1126
- if ( write( fd, &s_ack, LSAPI_PACKET_HEADER_LEN )
1127
- < LSAPI_PACKET_HEADER_LEN )
1271
+ if ( write( fd, pkt, LSAPI_PACKET_HEADER_LEN ) < LSAPI_PACKET_HEADER_LEN )
1128
1272
  return -1;
1129
1273
  return 0;
1130
1274
  }
1131
1275
 
1132
- static void lsapi_sigalarm( int sig )
1276
+
1277
+ static inline int send_req_received_notification( int fd )
1133
1278
  {
1134
- if ( s_notify_scheduled )
1135
- {
1136
- s_notify_scheduled = 0;
1137
- if ( g_req.m_fd != -1 )
1138
- write_req_received_notification( g_req.m_fd );
1139
- }
1279
+ return send_notification_pkt(fd, &s_ack);
1140
1280
  }
1141
1281
 
1282
+
1283
+ static inline int send_conn_close_notification( int fd )
1284
+ {
1285
+ return send_notification_pkt(fd, &s_conn_close_pkt);
1286
+ }
1287
+
1288
+
1289
+ //static void lsapi_sigalarm( int sig )
1290
+ //{
1291
+ // if ( s_notify_scheduled )
1292
+ // {
1293
+ // s_notify_scheduled = 0;
1294
+ // if ( g_req.m_fd != -1 )
1295
+ // write_req_received_notification( g_req.m_fd );
1296
+ // }
1297
+ //}
1298
+
1299
+
1142
1300
  static inline int lsapi_schedule_notify(void)
1143
1301
  {
1144
1302
  if ( !s_notify_scheduled )
@@ -1149,11 +1307,12 @@ static inline int lsapi_schedule_notify(void)
1149
1307
  return 0;
1150
1308
  }
1151
1309
 
1310
+
1152
1311
  static inline int notify_req_received( int fd )
1153
1312
  {
1154
1313
  if ( s_schedule_notify )
1155
1314
  return lsapi_schedule_notify();
1156
- return write_req_received_notification( fd );
1315
+ return send_req_received_notification( fd );
1157
1316
 
1158
1317
  }
1159
1318
 
@@ -1171,6 +1330,7 @@ static inline int lsapi_notify_pid( int fd )
1171
1330
  return 0;
1172
1331
  }
1173
1332
 
1333
+
1174
1334
  static char s_conn_key_packet[16];
1175
1335
  static inline int init_conn_key( int fd )
1176
1336
  {
@@ -1193,6 +1353,7 @@ static inline int init_conn_key( int fd )
1193
1353
 
1194
1354
  }
1195
1355
 
1356
+
1196
1357
  static int readReq( LSAPI_Request * pReq )
1197
1358
  {
1198
1359
  int len;
@@ -1217,12 +1378,12 @@ static int readReq( LSAPI_Request * pReq )
1217
1378
  packetLen = verifyHeader( &pReq->m_pHeader->m_pktHeader, LSAPI_BEGIN_REQUEST );
1218
1379
  if ( packetLen < 0 )
1219
1380
  {
1220
- fprintf( stderr, "%d: packetLen < 0\n", getpid() );
1381
+ lsapi_log("packetLen < 0\n");
1221
1382
  return -1;
1222
1383
  }
1223
1384
  if ( packetLen > LSAPI_MAX_HEADER_LEN )
1224
1385
  {
1225
- fprintf( stderr, "%d: packetLen > %d\n", getpid(), LSAPI_MAX_HEADER_LEN );
1386
+ lsapi_log("packetLen > %d\n", LSAPI_MAX_HEADER_LEN );
1226
1387
  return -1;
1227
1388
  }
1228
1389
 
@@ -1240,7 +1401,7 @@ static int readReq( LSAPI_Request * pReq )
1240
1401
  }
1241
1402
  if ( parseRequest( pReq, packetLen ) < 0 )
1242
1403
  {
1243
- fprintf( stderr, "%d: parseRequest error\n", getpid() );
1404
+ lsapi_log("ParseRequest error\n");
1244
1405
  return -1;
1245
1406
  }
1246
1407
 
@@ -1265,7 +1426,6 @@ static int readReq( LSAPI_Request * pReq )
1265
1426
  }
1266
1427
 
1267
1428
 
1268
-
1269
1429
  int LSAPI_Init(void)
1270
1430
  {
1271
1431
  if ( !g_inited )
@@ -1285,20 +1445,33 @@ int LSAPI_Init(void)
1285
1445
  return -1;
1286
1446
  g_inited = 1;
1287
1447
  s_ppid = getppid();
1448
+ void *pthread_lib = dlopen("libpthread.so", RTLD_LAZY);
1449
+ if (pthread_lib)
1450
+ pthread_atfork_func = dlsym(pthread_lib, "pthread_atfork");
1451
+
1288
1452
  }
1289
1453
  return 0;
1290
1454
  }
1291
1455
 
1456
+
1292
1457
  void LSAPI_Stop(void)
1293
1458
  {
1294
1459
  g_running = 0;
1295
1460
  }
1296
1461
 
1462
+
1297
1463
  int LSAPI_IsRunning(void)
1298
1464
  {
1299
1465
  return g_running;
1300
1466
  }
1301
1467
 
1468
+
1469
+ void LSAPI_Register_Pgrp_Timer_Callback(LSAPI_On_Timer_pf cb)
1470
+ {
1471
+ s_proc_group_timer_cb = cb;
1472
+ }
1473
+
1474
+
1302
1475
  int LSAPI_InitRequest( LSAPI_Request * pReq, int fd )
1303
1476
  {
1304
1477
  int newfd;
@@ -1337,18 +1510,19 @@ int LSAPI_InitRequest( LSAPI_Request * pReq, int fd )
1337
1510
  return 0;
1338
1511
  }
1339
1512
 
1513
+
1340
1514
  int LSAPI_Is_Listen( void )
1341
1515
  {
1342
1516
  return LSAPI_Is_Listen_r( &g_req );
1343
1517
  }
1344
1518
 
1519
+
1345
1520
  int LSAPI_Is_Listen_r( LSAPI_Request * pReq)
1346
1521
  {
1347
1522
  return pReq->m_fdListen != -1;
1348
1523
  }
1349
1524
 
1350
1525
 
1351
-
1352
1526
  int LSAPI_Accept_r( LSAPI_Request * pReq )
1353
1527
  {
1354
1528
  char achPeer[128];
@@ -1378,8 +1552,9 @@ int LSAPI_Accept_r( LSAPI_Request * pReq )
1378
1552
  }
1379
1553
  else
1380
1554
  {
1381
- if (s_pChildStatus)
1382
- s_pChildStatus->m_connected = 1;
1555
+ if (s_worker_status)
1556
+ __sync_lock_test_and_set(&s_worker_status->m_state,
1557
+ LSAPI_STATE_CONNECTED);
1383
1558
  if (s_busy_workers)
1384
1559
  __sync_fetch_and_add(s_busy_workers, 1);
1385
1560
  lsapi_set_nblock( pReq->m_fd , 0 );
@@ -1407,8 +1582,13 @@ int LSAPI_Accept_r( LSAPI_Request * pReq )
1407
1582
  return 0;
1408
1583
  }
1409
1584
 
1410
- static struct lsapi_packet_header finish = {'L', 'S',
1411
- LSAPI_RESP_END, LSAPI_ENDIAN, {LSAPI_PACKET_HEADER_LEN} };
1585
+
1586
+ static struct lsapi_packet_header finish_close[2] =
1587
+ {
1588
+ {'L', 'S', LSAPI_RESP_END, LSAPI_ENDIAN, {LSAPI_PACKET_HEADER_LEN} },
1589
+ {'L', 'S', LSAPI_CONN_CLOSE, LSAPI_ENDIAN, {LSAPI_PACKET_HEADER_LEN} }
1590
+ };
1591
+
1412
1592
 
1413
1593
  int LSAPI_Finish_r( LSAPI_Request * pReq )
1414
1594
  {
@@ -1428,7 +1608,7 @@ int LSAPI_Finish_r( LSAPI_Request * pReq )
1428
1608
  Flush_RespBuf_r( pReq );
1429
1609
  }
1430
1610
 
1431
- pReq->m_pIovecCur->iov_base = (void *)&finish;
1611
+ pReq->m_pIovecCur->iov_base = (void *)finish_close;
1432
1612
  pReq->m_pIovecCur->iov_len = LSAPI_PACKET_HEADER_LEN;
1433
1613
  pReq->m_totalLen += LSAPI_PACKET_HEADER_LEN;
1434
1614
  ++pReq->m_pIovecCur;
@@ -1440,6 +1620,41 @@ int LSAPI_Finish_r( LSAPI_Request * pReq )
1440
1620
  }
1441
1621
 
1442
1622
 
1623
+ int LSAPI_End_Response_r(LSAPI_Request * pReq)
1624
+ {
1625
+ if (!pReq)
1626
+ return -1;
1627
+ if (pReq->m_reqState & LSAPI_ST_BACKGROUND)
1628
+ return 0;
1629
+ if (pReq->m_reqState)
1630
+ {
1631
+ if ( pReq->m_fd != -1 )
1632
+ {
1633
+ if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER )
1634
+ {
1635
+ if ( pReq->m_pRespHeaderBufPos <= pReq->m_pRespHeaderBuf )
1636
+ return 0;
1637
+
1638
+ LSAPI_FinalizeRespHeaders_r( pReq );
1639
+ }
1640
+ if ( pReq->m_pRespBufPos != pReq->m_pRespBuf )
1641
+ {
1642
+ Flush_RespBuf_r( pReq );
1643
+ }
1644
+
1645
+ pReq->m_pIovecCur->iov_base = (void *)finish_close;
1646
+ pReq->m_pIovecCur->iov_len = LSAPI_PACKET_HEADER_LEN << 1;
1647
+ pReq->m_totalLen += LSAPI_PACKET_HEADER_LEN << 1;
1648
+ ++pReq->m_pIovecCur;
1649
+ LSAPI_Flush_r( pReq );
1650
+ lsapi_close_connection(pReq);
1651
+ }
1652
+ pReq->m_reqState |= LSAPI_ST_BACKGROUND;
1653
+ }
1654
+ return 0;
1655
+ }
1656
+
1657
+
1443
1658
  void LSAPI_Reset_r( LSAPI_Request * pReq )
1444
1659
  {
1445
1660
  pReq->m_pRespBufPos = pReq->m_pRespBuf;
@@ -1482,6 +1697,7 @@ char * LSAPI_GetHeader_r( LSAPI_Request * pReq, int headerIndex )
1482
1697
  return pReq->m_pHttpHeader + off;
1483
1698
  }
1484
1699
 
1700
+
1485
1701
  static int readBodyToReqBuf( LSAPI_Request * pReq )
1486
1702
  {
1487
1703
  off_t bodyLeft;
@@ -1518,7 +1734,6 @@ int LSAPI_ReqBodyGetChar_r( LSAPI_Request * pReq )
1518
1734
  }
1519
1735
 
1520
1736
 
1521
-
1522
1737
  int LSAPI_ReqBodyGetLine_r( LSAPI_Request * pReq, char * pBuf, size_t bufLen, int *getLF )
1523
1738
  {
1524
1739
  ssize_t len;
@@ -1527,7 +1742,7 @@ int LSAPI_ReqBodyGetLine_r( LSAPI_Request * pReq, char * pBuf, size_t bufLen, in
1527
1742
  char * pBufCur = pBuf;
1528
1743
  char * pCur;
1529
1744
  char * p;
1530
- if (!pReq || (pReq->m_fd ==-1) ||( !pBuf )||(bufLen < 0 )|| !getLF )
1745
+ if (!pReq || pReq->m_fd == -1 || !pBuf || !getLF)
1531
1746
  return -1;
1532
1747
  *getLF = 0;
1533
1748
  while( (left = pBufEnd - pBufCur ) > 0 )
@@ -1571,7 +1786,7 @@ ssize_t LSAPI_ReadReqBody_r( LSAPI_Request * pReq, char * pBuf, size_t bufLen )
1571
1786
  ssize_t len;
1572
1787
  off_t total;
1573
1788
  /* char *pOldBuf = pBuf; */
1574
- if (!pReq || (pReq->m_fd ==-1) || ( !pBuf )||((ssize_t)bufLen < 0 ))
1789
+ if (!pReq || pReq->m_fd == -1 || !pBuf || (ssize_t)bufLen < 0)
1575
1790
  return -1;
1576
1791
 
1577
1792
  total = pReq->m_reqBodyLen - pReq->m_reqBodyRead;
@@ -1625,7 +1840,11 @@ ssize_t LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, size_t len )
1625
1840
  ssize_t packetLen;
1626
1841
  int skip = 0;
1627
1842
 
1628
- if ( !pReq || !pBuf || (pReq->m_fd == -1) )
1843
+ if (!pReq || !pBuf)
1844
+ return -1;
1845
+ if (pReq->m_reqState & LSAPI_ST_BACKGROUND)
1846
+ return len;
1847
+ if (pReq->m_fd == -1)
1629
1848
  return -1;
1630
1849
  if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER )
1631
1850
  {
@@ -1700,6 +1919,7 @@ ssize_t LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, size_t len )
1700
1919
  return p - pBuf;
1701
1920
  }
1702
1921
 
1922
+
1703
1923
  #if defined(__FreeBSD__ ) || defined(__NetBSD__) || defined(__OpenBSD__)
1704
1924
  ssize_t gsendfile( int fdOut, int fdIn, off_t* off, size_t size )
1705
1925
  {
@@ -1715,6 +1935,7 @@ ssize_t gsendfile( int fdOut, int fdIn, off_t* off, size_t size )
1715
1935
  }
1716
1936
  #endif
1717
1937
 
1938
+
1718
1939
  #if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
1719
1940
  ssize_t gsendfile( int fdOut, int fdIn, off_t* off, size_t size )
1720
1941
  {
@@ -1730,6 +1951,7 @@ ssize_t gsendfile( int fdOut, int fdIn, off_t* off, size_t size )
1730
1951
  }
1731
1952
  #endif
1732
1953
 
1954
+
1733
1955
  #if defined(sun) || defined(__sun)
1734
1956
  #include <sys/sendfile.h>
1735
1957
  ssize_t gsendfile( int fdOut, int fdIn, off_t *off, size_t size )
@@ -1753,11 +1975,14 @@ ssize_t gsendfile( int fdOut, int fdIn, off_t *off, size_t size )
1753
1975
  }
1754
1976
  #endif
1755
1977
 
1978
+
1756
1979
  #if defined(linux) || defined(__linux) || defined(__linux__) || \
1757
1980
  defined(__gnu_linux__)
1758
1981
  #include <sys/sendfile.h>
1759
1982
  #define gsendfile sendfile
1760
1983
  #endif
1984
+
1985
+
1761
1986
  #if defined(HPUX)
1762
1987
  ssize_t gsendfile( int fdOut, int fdIn, off_t * off, size_t size )
1763
1988
  {
@@ -1765,6 +1990,7 @@ ssize_t gsendfile( int fdOut, int fdIn, off_t * off, size_t size )
1765
1990
  }
1766
1991
  #endif
1767
1992
 
1993
+
1768
1994
  ssize_t LSAPI_sendfile_r( LSAPI_Request * pReq, int fdIn, off_t* off, size_t size )
1769
1995
  {
1770
1996
  struct lsapi_packet_header * pHeader = pReq->m_respPktHeader;
@@ -1813,8 +2039,6 @@ void Flush_RespBuf_r( LSAPI_Request * pReq )
1813
2039
  }
1814
2040
 
1815
2041
 
1816
-
1817
-
1818
2042
  int LSAPI_Flush_r( LSAPI_Request * pReq )
1819
2043
  {
1820
2044
  int ret = 0;
@@ -1871,7 +2095,7 @@ ssize_t LSAPI_Write_Stderr_r( LSAPI_Request * pReq, const char * pBuf, size_t le
1871
2095
 
1872
2096
  if ( !pReq )
1873
2097
  return -1;
1874
- if (s_pStderrLog||( pReq->m_fd == -1 )||(pReq->m_fd == pReq->m_fdListen ))
2098
+ if (s_stderr_log_path || pReq->m_fd == -1 || pReq->m_fd == pReq->m_fdListen)
1875
2099
  return write( 2, pBuf, len );
1876
2100
  if ( pReq->m_pRespBufPos != pReq->m_pRespBuf )
1877
2101
  {
@@ -1910,6 +2134,7 @@ ssize_t LSAPI_Write_Stderr_r( LSAPI_Request * pReq, const char * pBuf, size_t le
1910
2134
  return p - pBuf;
1911
2135
  }
1912
2136
 
2137
+
1913
2138
  static char * GetHeaderVar( LSAPI_Request * pReq, const char * name )
1914
2139
  {
1915
2140
  int i;
@@ -1989,6 +2214,7 @@ char * LSAPI_GetEnv_r( LSAPI_Request * pReq, const char * name )
1989
2214
  return NULL;
1990
2215
  }
1991
2216
 
2217
+
1992
2218
  struct _headerInfo
1993
2219
  {
1994
2220
  const char * _name;
@@ -1997,12 +2223,14 @@ struct _headerInfo
1997
2223
  int _valueLen;
1998
2224
  };
1999
2225
 
2226
+
2000
2227
  int compareValueLocation(const void * v1, const void *v2 )
2001
2228
  {
2002
2229
  return ((const struct _headerInfo *)v1)->_value -
2003
2230
  ((const struct _headerInfo *)v2)->_value;
2004
2231
  }
2005
2232
 
2233
+
2006
2234
  int LSAPI_ForeachOrgHeader_r( LSAPI_Request * pReq,
2007
2235
  LSAPI_CB_EnvHandler fn, void * arg )
2008
2236
  {
@@ -2076,7 +2304,6 @@ int LSAPI_ForeachOrgHeader_r( LSAPI_Request * pReq,
2076
2304
  return ret;
2077
2305
  }
2078
2306
  return count;
2079
-
2080
2307
  }
2081
2308
 
2082
2309
 
@@ -2145,9 +2372,9 @@ int LSAPI_ForeachHeader_r( LSAPI_Request * pReq,
2145
2372
  }
2146
2373
  }
2147
2374
  return count + pReq->m_pHeader->m_cntUnknownHeaders;
2148
-
2149
2375
  }
2150
2376
 
2377
+
2151
2378
  static int EnvForeach( struct LSAPI_key_value_pair * pEnv,
2152
2379
  int n, LSAPI_CB_EnvHandler fn, void * arg )
2153
2380
  {
@@ -2167,7 +2394,6 @@ static int EnvForeach( struct LSAPI_key_value_pair * pEnv,
2167
2394
  }
2168
2395
 
2169
2396
 
2170
-
2171
2397
  int LSAPI_ForeachEnv_r( LSAPI_Request * pReq,
2172
2398
  LSAPI_CB_EnvHandler fn, void * arg )
2173
2399
  {
@@ -2182,7 +2408,6 @@ int LSAPI_ForeachEnv_r( LSAPI_Request * pReq,
2182
2408
  }
2183
2409
 
2184
2410
 
2185
-
2186
2411
  int LSAPI_ForeachSpecialEnv_r( LSAPI_Request * pReq,
2187
2412
  LSAPI_CB_EnvHandler fn, void * arg )
2188
2413
  {
@@ -2199,7 +2424,6 @@ int LSAPI_ForeachSpecialEnv_r( LSAPI_Request * pReq,
2199
2424
  }
2200
2425
 
2201
2426
 
2202
-
2203
2427
  int LSAPI_FinalizeRespHeaders_r( LSAPI_Request * pReq )
2204
2428
  {
2205
2429
  if ( !pReq || !pReq->m_pIovec )
@@ -2283,7 +2507,6 @@ int LSAPI_AppendRespHeader2_r( LSAPI_Request * pReq, const char * pHeaderName,
2283
2507
  }
2284
2508
 
2285
2509
 
2286
-
2287
2510
  int LSAPI_AppendRespHeader_r( LSAPI_Request * pReq, const char * pBuf, int len )
2288
2511
  {
2289
2512
  if ( !pReq || !pBuf || len <= 0 || len > LSAPI_RESP_HTTP_HEADER_MAX )
@@ -2364,9 +2587,9 @@ int LSAPI_CreateListenSock2( const struct sockaddr * pServerAddr, int backlog )
2364
2587
  close(fd);
2365
2588
  errno = ret;
2366
2589
  return -1;
2367
-
2368
2590
  }
2369
2591
 
2592
+
2370
2593
  int LSAPI_ParseSockAddr( const char * pBind, struct sockaddr * pAddr )
2371
2594
  {
2372
2595
  char achAddr[256];
@@ -2464,6 +2687,7 @@ int LSAPI_ParseSockAddr( const char * pBind, struct sockaddr * pAddr )
2464
2687
 
2465
2688
  }
2466
2689
 
2690
+
2467
2691
  int LSAPI_CreateListenSock( const char * pBind, int backlog )
2468
2692
  {
2469
2693
  char serverAddr[128];
@@ -2477,8 +2701,8 @@ int LSAPI_CreateListenSock( const char * pBind, int backlog )
2477
2701
  return fd;
2478
2702
  }
2479
2703
 
2480
- static fn_select_t g_fnSelect = select;
2481
2704
 
2705
+ static fn_select_t g_fnSelect = select;
2482
2706
  typedef struct _lsapi_prefork_server
2483
2707
  {
2484
2708
  int m_fd;
@@ -2496,12 +2720,11 @@ typedef struct _lsapi_prefork_server
2496
2720
  lsapi_child_status * m_pChildrenStatusEnd;
2497
2721
 
2498
2722
  }lsapi_prefork_server;
2499
-
2500
2723
  static lsapi_prefork_server * g_prefork_server = NULL;
2501
2724
 
2725
+
2502
2726
  int LSAPI_Init_Prefork_Server( int max_children, fn_select_t fp, int avoidFork )
2503
2727
  {
2504
- int pid;
2505
2728
  if ( g_prefork_server )
2506
2729
  return 0;
2507
2730
  if ( max_children <= 1 )
@@ -2509,7 +2732,8 @@ int LSAPI_Init_Prefork_Server( int max_children, fn_select_t fp, int avoidFork )
2509
2732
  if ( max_children >= 10000)
2510
2733
  max_children = 10000;
2511
2734
 
2512
- s_max_busy_children = max_children / 2 + 1;
2735
+ if (s_max_busy_workers == 0)
2736
+ s_max_busy_workers = max_children / 2 + 1;
2513
2737
 
2514
2738
  g_prefork_server = (lsapi_prefork_server *)malloc( sizeof( lsapi_prefork_server ) );
2515
2739
  if ( !g_prefork_server )
@@ -2520,8 +2744,11 @@ int LSAPI_Init_Prefork_Server( int max_children, fn_select_t fp, int avoidFork )
2520
2744
  g_fnSelect = fp;
2521
2745
 
2522
2746
  s_ppid = getppid();
2523
- pid = getpid();
2524
- setpgid( pid, pid );
2747
+ s_pid = getpid();
2748
+ setpgid( s_pid, s_pid );
2749
+ #if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__)
2750
+ s_total_pages = sysconf(_SC_PHYS_PAGES);
2751
+ #endif
2525
2752
  g_prefork_server->m_iAvoidFork = avoidFork;
2526
2753
  g_prefork_server->m_iMaxChildren = max_children;
2527
2754
 
@@ -2531,9 +2758,13 @@ int LSAPI_Init_Prefork_Server( int max_children, fn_select_t fp, int avoidFork )
2531
2758
  g_prefork_server->m_iMaxIdleChildren = 1;
2532
2759
  g_prefork_server->m_iChildrenMaxIdleTime = 300;
2533
2760
  g_prefork_server->m_iMaxReqProcessTime = 3600;
2761
+
2762
+ setsid();
2763
+
2534
2764
  return 0;
2535
2765
  }
2536
2766
 
2767
+
2537
2768
  void LSAPI_Set_Server_fd( int fd )
2538
2769
  {
2539
2770
  if( g_prefork_server )
@@ -2567,12 +2798,8 @@ static int lsapi_accept( int fdListen )
2567
2798
  }
2568
2799
 
2569
2800
 
2570
-
2571
-
2572
- static int s_req_processed = 0;
2573
- static int s_max_reqs = 10000;
2801
+ static unsigned int s_max_reqs = UINT_MAX;
2574
2802
  static int s_max_idle_secs = 300;
2575
-
2576
2803
  static int s_stop;
2577
2804
 
2578
2805
  static void lsapi_cleanup(int signal)
@@ -2580,6 +2807,7 @@ static void lsapi_cleanup(int signal)
2580
2807
  s_stop = signal;
2581
2808
  }
2582
2809
 
2810
+
2583
2811
  static lsapi_child_status * find_child_status( int pid )
2584
2812
  {
2585
2813
  lsapi_child_status * pStatus = g_prefork_server->m_pChildrenStatus;
@@ -2588,6 +2816,11 @@ static lsapi_child_status * find_child_status( int pid )
2588
2816
  {
2589
2817
  if ( pStatus->m_pid == pid )
2590
2818
  {
2819
+ if (pid == 0)
2820
+ {
2821
+ memset(pStatus, 0, sizeof( *pStatus ) );
2822
+ pStatus->m_pid = -1;
2823
+ }
2591
2824
  if ( pStatus + 1 > g_prefork_server->m_pChildrenStatusCur )
2592
2825
  g_prefork_server->m_pChildrenStatusCur = pStatus + 1;
2593
2826
  return pStatus;
@@ -2598,11 +2831,33 @@ static lsapi_child_status * find_child_status( int pid )
2598
2831
  }
2599
2832
 
2600
2833
 
2834
+ void LSAPI_reset_server_state( void )
2835
+ {
2836
+ /*
2837
+ Reset child status
2838
+ */
2839
+ g_prefork_server->m_iCurChildren = 0;
2840
+ lsapi_child_status * pStatus = g_prefork_server->m_pChildrenStatus;
2841
+ lsapi_child_status * pEnd = g_prefork_server->m_pChildrenStatusEnd;
2842
+ while( pStatus < pEnd )
2843
+ {
2844
+ pStatus->m_pid = 0;
2845
+ ++pStatus;
2846
+ }
2847
+ if (s_busy_workers)
2848
+ __sync_lock_release(s_busy_workers);
2849
+ if (s_accepting_workers)
2850
+ __sync_lock_release(s_accepting_workers);
2851
+
2852
+ }
2853
+
2601
2854
 
2602
2855
  static void lsapi_sigchild( int signal )
2603
2856
  {
2604
2857
  int status, pid;
2605
2858
  lsapi_child_status * child_status;
2859
+ if (g_prefork_server == NULL)
2860
+ return;
2606
2861
  while( 1 )
2607
2862
  {
2608
2863
  pid = waitpid( -1, &status, WNOHANG|WUNTRACED );
@@ -2614,21 +2869,36 @@ static void lsapi_sigchild( int signal )
2614
2869
  {
2615
2870
  int sig_num = WTERMSIG( status );
2616
2871
  int dump = WCOREDUMP( status );
2617
- fprintf( stderr, "Child process with pid: %d was killed by signal: %d, core dump: %d\n", pid, sig_num, dump );
2872
+ lsapi_log("Child process with pid: %d was killed by signal: "
2873
+ "%d, core dump: %d\n", pid, sig_num, dump );
2618
2874
  }
2619
2875
  if ( pid == s_pid_dump_debug_info )
2620
2876
  {
2621
2877
  pid = 0;
2622
2878
  continue;
2623
2879
  }
2880
+ if ( pid == s_ignore_pid )
2881
+ {
2882
+ pid = 0;
2883
+ s_ignore_pid = -1;
2884
+ continue;
2885
+ }
2624
2886
  child_status = find_child_status( pid );
2625
2887
  if ( child_status )
2626
2888
  {
2627
- if (child_status->m_connected)
2889
+ if (__sync_bool_compare_and_swap(&child_status->m_state,
2890
+ LSAPI_STATE_CONNECTED,
2891
+ LSAPI_STATE_IDLE))
2628
2892
  {
2629
2893
  if (s_busy_workers)
2630
2894
  __sync_fetch_and_sub(s_busy_workers, 1);
2631
- child_status->m_connected = 0;
2895
+ }
2896
+ else if (__sync_bool_compare_and_swap(&child_status->m_state,
2897
+ LSAPI_STATE_ACCEPTING,
2898
+ LSAPI_STATE_IDLE))
2899
+ {
2900
+ if (s_accepting_workers)
2901
+ __sync_fetch_and_sub(s_accepting_workers, 1);
2632
2902
  }
2633
2903
  child_status->m_pid = 0;
2634
2904
  --g_prefork_server->m_iCurChildren;
@@ -2640,13 +2910,19 @@ static void lsapi_sigchild( int signal )
2640
2910
 
2641
2911
  }
2642
2912
 
2913
+
2643
2914
  static int lsapi_init_children_status(void)
2644
2915
  {
2645
- int size = 4096;
2646
-
2647
2916
  char * pBuf;
2648
- size = (g_prefork_server->m_iMaxChildren + g_prefork_server->m_iExtraChildren ) * sizeof( lsapi_child_status ) * 2;
2649
- size = (size + 4095 ) / 4096 * 4096;
2917
+ int size = 4096;
2918
+ int max_children;
2919
+ if (g_prefork_server->m_pChildrenStatus)
2920
+ return 0;
2921
+ max_children = g_prefork_server->m_iMaxChildren
2922
+ + g_prefork_server->m_iExtraChildren;
2923
+
2924
+ size = max_children * sizeof( lsapi_child_status ) * 2 + 3 * sizeof(int);
2925
+ size = (size + 4095) / 4096 * 4096;
2650
2926
  pBuf =( char*) mmap( NULL, size, PROT_READ | PROT_WRITE,
2651
2927
  MAP_ANON | MAP_SHARED, -1, 0 );
2652
2928
  if ( pBuf == MAP_FAILED )
@@ -2657,10 +2933,17 @@ static int lsapi_init_children_status(void)
2657
2933
  memset( pBuf, 0, size );
2658
2934
  g_prefork_server->m_pChildrenStatus = (lsapi_child_status *)pBuf;
2659
2935
  g_prefork_server->m_pChildrenStatusCur = (lsapi_child_status *)pBuf;
2660
- g_prefork_server->m_pChildrenStatusEnd = (lsapi_child_status *)pBuf + size / sizeof( lsapi_child_status );
2936
+ g_prefork_server->m_pChildrenStatusEnd = (lsapi_child_status *)pBuf + max_children;
2937
+ s_busy_workers = (int *)g_prefork_server->m_pChildrenStatusEnd;
2938
+ s_accepting_workers = s_busy_workers + 1;
2939
+ s_global_counter = s_accepting_workers + 1;
2940
+ s_avail_pages = (size_t *)(s_global_counter + 1);
2941
+
2942
+ setsid();
2661
2943
  return 0;
2662
2944
  }
2663
2945
 
2946
+
2664
2947
  static void dump_debug_info( lsapi_child_status * pStatus, long tmCur )
2665
2948
  {
2666
2949
  char achCmd[1024];
@@ -2669,17 +2952,26 @@ static void dump_debug_info( lsapi_child_status * pStatus, long tmCur )
2669
2952
  if ( kill( s_pid_dump_debug_info, 0 ) == 0 )
2670
2953
  return;
2671
2954
  }
2672
- s_pid_dump_debug_info = fork();
2673
2955
 
2674
- fprintf( stderr, "[%s] Possible runaway process, PPID: %d, PID: %d, reqCount: %d, process time: %ld, checkpoint time: %ld, start time: %ld\n",
2675
- ctime(&tmCur), getpid(), pStatus->m_pid, pStatus->m_iReqCounter,
2676
- tmCur - pStatus->m_tmReqBegin, tmCur - pStatus->m_tmLastCheckPoint, tmCur - pStatus->m_tmStart );
2677
- snprintf( achCmd, 1024, "gdb --batch -ex \"attach %d\" -ex \"set height 0\" -ex \"bt\" >&2;PATH=$PATH:/usr/sbin lsof -p %d >&2", pStatus->m_pid, pStatus->m_pid );
2678
- if ( system( achCmd ) == -1 )
2679
- perror( "system()" );
2680
- exit( 0 );
2956
+ lsapi_log("Possible runaway process, PPID: %d, PID: %d, "
2957
+ "reqCount: %d, process time: %ld, checkpoint time: %ld, start "
2958
+ "time: %ld\n", getpid(), pStatus->m_pid,
2959
+ pStatus->m_iReqCounter, tmCur - pStatus->m_tmReqBegin,
2960
+ tmCur - pStatus->m_tmLastCheckPoint, tmCur - pStatus->m_tmStart );
2961
+
2962
+ s_pid_dump_debug_info = fork();
2963
+ if (s_pid_dump_debug_info == 0)
2964
+ {
2965
+ snprintf( achCmd, 1024, "gdb --batch -ex \"attach %d\" -ex \"set height 0\" "
2966
+ "-ex \"bt\" >&2;PATH=$PATH:/usr/sbin lsof -p %d >&2",
2967
+ pStatus->m_pid, pStatus->m_pid );
2968
+ if ( system( achCmd ) == -1 )
2969
+ perror( "system()" );
2970
+ exit( 0 );
2971
+ }
2681
2972
  }
2682
2973
 
2974
+
2683
2975
  static void lsapi_check_child_status( long tmCur )
2684
2976
  {
2685
2977
  int idle = 0;
@@ -2697,15 +2989,17 @@ static void lsapi_check_child_status( long tmCur )
2697
2989
  if ( !pStatus->m_inProcess )
2698
2990
  {
2699
2991
 
2700
- if (( g_prefork_server->m_iCurChildren - dying > g_prefork_server->m_iMaxChildren)||
2701
- ( idle > g_prefork_server->m_iMaxIdleChildren ))
2992
+ if (g_prefork_server->m_iCurChildren - dying
2993
+ > g_prefork_server->m_iMaxChildren
2994
+ || idle > g_prefork_server->m_iMaxIdleChildren)
2702
2995
  {
2703
2996
  ++pStatus->m_iKillSent;
2704
2997
  //tobekilled = SIGUSR1;
2705
2998
  }
2706
2999
  else
2707
3000
  {
2708
- if (( s_max_idle_secs> 0)&&(tmCur - pStatus->m_tmWaitBegin > s_max_idle_secs + 5 ))
3001
+ if (s_max_idle_secs> 0
3002
+ && tmCur - pStatus->m_tmWaitBegin > s_max_idle_secs + 5)
2709
3003
  {
2710
3004
  ++pStatus->m_iKillSent;
2711
3005
  //tobekilled = SIGUSR1;
@@ -2716,26 +3010,29 @@ static void lsapi_check_child_status( long tmCur )
2716
3010
  }
2717
3011
  else
2718
3012
  {
2719
- if ( tmCur - pStatus->m_tmReqBegin >
2720
- g_prefork_server->m_iMaxReqProcessTime )
3013
+ if (tmCur - pStatus->m_tmReqBegin >
3014
+ g_prefork_server->m_iMaxReqProcessTime)
2721
3015
  {
2722
- if (( ( pStatus->m_iKillSent % 5 ) == 0 )&&( s_dump_debug_info ))
3016
+ if ((pStatus->m_iKillSent % 5) == 0 && s_dump_debug_info)
2723
3017
  dump_debug_info( pStatus, tmCur );
2724
3018
  if ( pStatus->m_iKillSent > 5 )
2725
3019
  {
2726
3020
  tobekilled = SIGKILL;
2727
- fprintf( stderr, "Force killing runaway process PID: %d with SIGKILL\n", pStatus->m_pid );
3021
+ lsapi_log("Force killing runaway process PID: %d"
3022
+ " with SIGKILL\n", pStatus->m_pid );
2728
3023
  }
2729
3024
  else
2730
3025
  {
2731
3026
  tobekilled = SIGTERM;
2732
- fprintf( stderr, "Killing runaway process PID: %d with SIGTERM\n", pStatus->m_pid );
3027
+ lsapi_log("Killing runaway process PID: %d with "
3028
+ "SIGTERM\n", pStatus->m_pid );
2733
3029
  }
2734
3030
  }
2735
3031
  }
2736
3032
  if ( tobekilled )
2737
3033
  {
2738
- if (( kill( pStatus->m_pid, tobekilled ) == -1 )&&( errno == ESRCH ))
3034
+ if (( kill( pStatus->m_pid, tobekilled ) == -1 ) &&
3035
+ ( errno == ESRCH ))
2739
3036
  {
2740
3037
  pStatus->m_pid = 0;
2741
3038
  --count;
@@ -2751,34 +3048,50 @@ static void lsapi_check_child_status( long tmCur )
2751
3048
  }
2752
3049
  if ( abs( g_prefork_server->m_iCurChildren - count ) > 1 )
2753
3050
  {
2754
- fprintf( stderr, "Children tracking is wrong: PID: %d, Cur Children: %d, count: %d, idle: %d, dying: %d\n", getpid(),
2755
- g_prefork_server->m_iCurChildren, count, idle, dying );
2756
-
3051
+ lsapi_log("Children tracking is wrong: Cur Children: %d,"
3052
+ " count: %d, idle: %d, dying: %d\n",
3053
+ g_prefork_server->m_iCurChildren, count, idle, dying );
2757
3054
  }
2758
3055
  }
2759
3056
 
2760
- static int lsapi_all_children_must_die(void)
2761
- {
2762
- int maxWait;
2763
- int sec =0;
2764
- g_prefork_server->m_iMaxReqProcessTime = 10;
2765
- g_prefork_server->m_iMaxIdleChildren = -1;
2766
- maxWait = 15;
2767
3057
 
2768
- while( g_prefork_server->m_iCurChildren && (sec < maxWait) )
2769
- {
2770
- lsapi_check_child_status(time(NULL));
2771
- sleep( 1 );
2772
- sec++;
2773
- }
2774
- if ( g_prefork_server->m_iCurChildren != 0 )
2775
- kill( -getpgrp(), SIGKILL );
2776
- return 0;
2777
- }
3058
+ //static int lsapi_all_children_must_die(void)
3059
+ //{
3060
+ // int maxWait;
3061
+ // int sec =0;
3062
+ // g_prefork_server->m_iMaxReqProcessTime = 10;
3063
+ // g_prefork_server->m_iMaxIdleChildren = -1;
3064
+ // maxWait = 15;
3065
+ //
3066
+ // while( g_prefork_server->m_iCurChildren && (sec < maxWait) )
3067
+ // {
3068
+ // lsapi_check_child_status(time(NULL));
3069
+ // sleep( 1 );
3070
+ // sec++;
3071
+ // }
3072
+ // if ( g_prefork_server->m_iCurChildren != 0 )
3073
+ // kill( -getpgrp(), SIGKILL );
3074
+ // return 0;
3075
+ //}
3076
+
3077
+
3078
+ void set_skip_write()
3079
+ { s_skip_write = 1; }
3080
+
2778
3081
 
3082
+ int is_enough_free_mem()
3083
+ {
3084
+ #if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__)
3085
+ //minimum 1GB or 10% available free memory
3086
+ return (*s_avail_pages > s_min_avail_pages
3087
+ || (*s_avail_pages * 10) / s_total_pages > 0);
3088
+ #endif
3089
+ return 1;
3090
+ }
2779
3091
 
2780
3092
 
2781
- static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Request * pReq )
3093
+ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer,
3094
+ LSAPI_Request * pReq )
2782
3095
  {
2783
3096
  struct sigaction act, old_term, old_quit, old_int,
2784
3097
  old_usr1, old_child;
@@ -2796,10 +3109,9 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re
2796
3109
 
2797
3110
  lsapi_init_children_status();
2798
3111
 
2799
- setsid();
2800
-
2801
3112
  act.sa_flags = 0;
2802
3113
  act.sa_handler = lsapi_sigchild;
3114
+ sigemptyset(&(act.sa_mask));
2803
3115
  if( sigaction( SIGCHLD, &act, &old_child ) )
2804
3116
  {
2805
3117
  perror( "Can't set signal handler for SIGCHILD" );
@@ -2809,6 +3121,7 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re
2809
3121
  /* Set up handler to kill children upon exit */
2810
3122
  act.sa_flags = 0;
2811
3123
  act.sa_handler = lsapi_cleanup;
3124
+ sigemptyset(&(act.sa_mask));
2812
3125
  if( sigaction( SIGTERM, &act, &old_term ) ||
2813
3126
  sigaction( SIGINT, &act, &old_int ) ||
2814
3127
  sigaction( SIGUSR1, &act, &old_usr1 ) ||
@@ -2817,14 +3130,18 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re
2817
3130
  perror( "Can't set signals" );
2818
3131
  return -1;
2819
3132
  }
2820
- s_stop = 0;
3133
+
2821
3134
  while( !s_stop )
2822
3135
  {
3136
+ if (s_proc_group_timer_cb != NULL) {
3137
+ s_proc_group_timer_cb(&s_ignore_pid);
3138
+ }
3139
+
2823
3140
  curTime = time( NULL );
2824
3141
  if (curTime != lastTime )
2825
3142
  {
2826
3143
  lastTime = curTime;
2827
- if (s_ppid && (getppid() != s_ppid ))
3144
+ if (lsapi_parent_dead())
2828
3145
  break;
2829
3146
  lsapi_check_child_status(curTime );
2830
3147
  if (pServer->m_iServerMaxIdle)
@@ -2840,29 +3157,33 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re
2840
3157
  }
2841
3158
  }
2842
3159
 
2843
- if ( pServer->m_iCurChildren >= (pServer->m_iMaxChildren + pServer->m_iExtraChildren ) )
2844
- {
2845
- fprintf( stderr, "Reached max children process limit: %d, extra: %d, current: %d, please increase LSAPI_CHILDREN.\n",
2846
- pServer->m_iMaxChildren, pServer->m_iExtraChildren, pServer->m_iCurChildren );
2847
- usleep( 100000 );
2848
- continue;
2849
- }
3160
+ #if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__)
3161
+ *s_avail_pages = sysconf(_SC_AVPHYS_PAGES);
3162
+ // lsapi_log("Memory total: %zd, free: %zd, free %%%zd\n",
3163
+ // s_total_pages, *s_avail_pages, *s_avail_pages * 100 / s_total_pages);
2850
3164
 
3165
+ #endif
2851
3166
  FD_ZERO( &readfds );
2852
3167
  FD_SET( pServer->m_fd, &readfds );
2853
- timeout.tv_sec = 1; timeout.tv_usec = 0;
2854
- if ((ret = (*g_fnSelect)(pServer->m_fd+1, &readfds, NULL, NULL, &timeout)) == 1 )
3168
+ timeout.tv_sec = 1;
3169
+ timeout.tv_usec = 0;
3170
+ ret = (*g_fnSelect)(pServer->m_fd+1, &readfds, NULL, NULL, &timeout);
3171
+ if (ret == 1 )
2855
3172
  {
2856
- /*
2857
- if ( pServer->m_iCurChildren >= 0 )
3173
+ int accepting = 0;
3174
+ if (s_accepting_workers)
3175
+ accepting = __sync_add_and_fetch(s_accepting_workers, 0);
3176
+
3177
+ if (pServer->m_iCurChildren > 0
3178
+ && accepting > 0)
2858
3179
  {
2859
- usleep( 10 );
2860
- FD_ZERO( &readfds );
2861
- FD_SET( pServer->m_fd, &readfds );
2862
- timeout.tv_sec = 0; timeout.tv_usec = 0;
2863
- if ( (*g_fnSelect)(pServer->m_fd+1, &readfds, NULL, NULL, &timeout) == 0 )
2864
- continue;
2865
- }*/
3180
+ lsapi_log("children: %d, accepting: %d\n",
3181
+ pServer->m_iCurChildren, accepting);
3182
+ usleep( 400);
3183
+ while(accepting-- > 0)
3184
+ sched_yield();
3185
+ continue;
3186
+ }
2866
3187
  }
2867
3188
  else if ( ret == -1 )
2868
3189
  {
@@ -2876,12 +3197,23 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re
2876
3197
  continue;
2877
3198
  }
2878
3199
 
3200
+ if (pServer->m_iCurChildren >=
3201
+ pServer->m_iMaxChildren + pServer->m_iExtraChildren)
3202
+ {
3203
+ lsapi_log("Reached max children process limit: %d, extra: %d,"
3204
+ " current: %d, busy: %d, please increase LSAPI_CHILDREN.\n",
3205
+ pServer->m_iMaxChildren, pServer->m_iExtraChildren,
3206
+ pServer->m_iCurChildren,
3207
+ s_busy_workers ? *s_busy_workers : -1 );
3208
+ usleep( 100000 );
3209
+ continue;
3210
+ }
3211
+
2879
3212
  pReq->m_fd = lsapi_accept( pServer->m_fd );
2880
3213
  if ( pReq->m_fd != -1 )
2881
3214
  {
3215
+ wait_secs = 0;
2882
3216
  child_status = find_child_status( 0 );
2883
- if ( child_status )
2884
- memset( child_status, 0, sizeof( *child_status ) );
2885
3217
 
2886
3218
  sigemptyset( &mask );
2887
3219
  sigaddset( &mask, SIGCHLD );
@@ -2895,19 +3227,30 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re
2895
3227
 
2896
3228
  if ( !pid )
2897
3229
  {
3230
+ setsid();
2898
3231
  if (sigprocmask(SIG_SETMASK, &orig_mask, NULL) < 0)
2899
3232
  perror( "sigprocmask( SIG_SETMASK ) to restore SIGMASK in child" );
2900
3233
  g_prefork_server = NULL;
2901
3234
  s_ppid = getppid();
3235
+ s_pid = getpid();
2902
3236
  s_req_processed = 0;
2903
- s_pChildStatus = child_status;
3237
+ s_proc_group_timer_cb = NULL;
3238
+ s_worker_status = child_status;
3239
+
3240
+ if (pthread_atfork_func)
3241
+ (*pthread_atfork_func)(NULL, NULL, set_skip_write);
2904
3242
 
2905
- s_pChildStatus->m_connected = 1;
3243
+ __sync_lock_test_and_set(&s_worker_status->m_state,
3244
+ LSAPI_STATE_CONNECTED);
2906
3245
  if (s_busy_workers)
2907
- __sync_fetch_and_add(s_busy_workers, 1);
2908
-
3246
+ __sync_add_and_fetch(s_busy_workers, 1);
2909
3247
  lsapi_set_nblock( pReq->m_fd, 0 );
2910
- if ( pReq->m_fdListen != -1 )
3248
+ //keep it open if busy_count is used.
3249
+ if (s_busy_workers
3250
+ && *s_busy_workers > (pServer->m_iMaxChildren >> 1))
3251
+ s_keepListener = 1;
3252
+ if ((s_uid == 0 || !s_keepListener || !is_enough_free_mem())
3253
+ && pReq->m_fdListen != -1 )
2911
3254
  {
2912
3255
  close( pReq->m_fdListen );
2913
3256
  pReq->m_fdListen = -1;
@@ -2961,11 +3304,220 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re
2961
3304
 
2962
3305
  }
2963
3306
 
2964
- void lsapi_error( const char * pMessage, int err_no )
3307
+
3308
+ static struct sigaction old_term, old_quit, old_int,
3309
+ old_usr1, old_child;
3310
+
3311
+
3312
+ int LSAPI_Postfork_Child(LSAPI_Request * pReq)
3313
+ {
3314
+ int max_children = g_prefork_server->m_iMaxChildren;
3315
+ s_pid = getpid();
3316
+ __sync_lock_test_and_set(&pReq->child_status->m_pid, s_pid);
3317
+ s_worker_status = pReq->child_status;
3318
+
3319
+ setsid();
3320
+ g_prefork_server = NULL;
3321
+ s_ppid = getppid();
3322
+ s_req_processed = 0;
3323
+ s_proc_group_timer_cb = NULL;
3324
+
3325
+ if (pthread_atfork_func)
3326
+ (*pthread_atfork_func)(NULL, NULL, set_skip_write);
3327
+
3328
+ __sync_lock_test_and_set(&s_worker_status->m_state,
3329
+ LSAPI_STATE_CONNECTED);
3330
+ if (s_busy_workers)
3331
+ __sync_add_and_fetch(s_busy_workers, 1);
3332
+ lsapi_set_nblock( pReq->m_fd, 0 );
3333
+ //keep it open if busy_count is used.
3334
+ if (s_busy_workers
3335
+ && *s_busy_workers > (max_children >> 1))
3336
+ s_keepListener = 1;
3337
+ if ((s_uid == 0 || !s_keepListener || !is_enough_free_mem())
3338
+ && pReq->m_fdListen != -1 )
3339
+ {
3340
+ close(pReq->m_fdListen);
3341
+ pReq->m_fdListen = -1;
3342
+ }
3343
+
3344
+ //init_conn_key( pReq->m_fd );
3345
+ lsapi_notify_pid(pReq->m_fd);
3346
+ s_notified_pid = 1;
3347
+ //if ( s_accept_notify )
3348
+ // return notify_req_received( pReq->m_fd );
3349
+ return 0;
3350
+ }
3351
+
3352
+
3353
+ int LSAPI_Postfork_Parent(LSAPI_Request * pReq)
3354
+ {
3355
+ ++g_prefork_server->m_iCurChildren;
3356
+ if (pReq->child_status)
3357
+ {
3358
+ time_t curTime = time( NULL );
3359
+ pReq->child_status->m_tmWaitBegin = curTime;
3360
+ pReq->child_status->m_tmStart = curTime;
3361
+ }
3362
+ close(pReq->m_fd);
3363
+ pReq->m_fd = -1;
3364
+ return 0;
3365
+ }
3366
+
3367
+
3368
+ int LSAPI_Accept_Before_Fork(LSAPI_Request * pReq)
3369
+ {
3370
+ time_t lastTime = 0;
3371
+ time_t curTime = 0;
3372
+ fd_set readfds;
3373
+ struct timeval timeout;
3374
+ int wait_secs = 0;
3375
+ int ret = 0;
3376
+
3377
+ lsapi_prefork_server * pServer = g_prefork_server;
3378
+
3379
+ struct sigaction act;
3380
+
3381
+ lsapi_init_children_status();
3382
+
3383
+ act.sa_flags = 0;
3384
+ act.sa_handler = lsapi_sigchild;
3385
+ sigemptyset(&(act.sa_mask));
3386
+ if (sigaction(SIGCHLD, &act, &old_child))
3387
+ {
3388
+ perror( "Can't set signal handler for SIGCHILD" );
3389
+ return -1;
3390
+ }
3391
+
3392
+ /* Set up handler to kill children upon exit */
3393
+ act.sa_flags = 0;
3394
+ act.sa_handler = lsapi_cleanup;
3395
+ sigemptyset(&(act.sa_mask));
3396
+ if (sigaction(SIGTERM, &act, &old_term) ||
3397
+ sigaction(SIGINT, &act, &old_int ) ||
3398
+ sigaction(SIGUSR1, &act, &old_usr1) ||
3399
+ sigaction(SIGQUIT, &act, &old_quit))
3400
+ {
3401
+ perror( "Can't set signals" );
3402
+ return -1;
3403
+ }
3404
+ s_stop = 0;
3405
+ pReq->m_reqState = 0;
3406
+
3407
+ while(!s_stop)
3408
+ {
3409
+ if (s_proc_group_timer_cb != NULL) {
3410
+ s_proc_group_timer_cb(&s_ignore_pid);
3411
+ }
3412
+
3413
+ curTime = time(NULL);
3414
+ if (curTime != lastTime)
3415
+ {
3416
+ lastTime = curTime;
3417
+ if (lsapi_parent_dead())
3418
+ break;
3419
+ lsapi_check_child_status(curTime);
3420
+ if (pServer->m_iServerMaxIdle)
3421
+ {
3422
+ if (pServer->m_iCurChildren <= 0)
3423
+ {
3424
+ ++wait_secs;
3425
+ if ( wait_secs > pServer->m_iServerMaxIdle )
3426
+ return -1;
3427
+ }
3428
+ else
3429
+ wait_secs = 0;
3430
+ }
3431
+ }
3432
+
3433
+ #if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__)
3434
+ *s_avail_pages = sysconf(_SC_AVPHYS_PAGES);
3435
+ // lsapi_log("Memory total: %zd, free: %zd, free %%%zd\n",
3436
+ // s_total_pages, *s_avail_pages, *s_avail_pages * 100 / s_total_pages);
3437
+
3438
+ #endif
3439
+ FD_ZERO(&readfds);
3440
+ FD_SET(pServer->m_fd, &readfds);
3441
+ timeout.tv_sec = 1;
3442
+ timeout.tv_usec = 0;
3443
+ ret = (*g_fnSelect)(pServer->m_fd+1, &readfds, NULL, NULL, &timeout);
3444
+ if (ret == 1 )
3445
+ {
3446
+ int accepting = 0;
3447
+ if (s_accepting_workers)
3448
+ accepting = __sync_add_and_fetch(s_accepting_workers, 0);
3449
+
3450
+ if (pServer->m_iCurChildren > 0
3451
+ && accepting > 0)
3452
+ {
3453
+ lsapi_log("children: %d, accepting: %d\n",
3454
+ pServer->m_iCurChildren, accepting);
3455
+ usleep( 400);
3456
+ while(accepting-- > 0)
3457
+ sched_yield();
3458
+ continue;
3459
+ }
3460
+ }
3461
+ else if (ret == -1)
3462
+ {
3463
+ if (errno == EINTR)
3464
+ continue;
3465
+ /* perror( "select()" ); */
3466
+ break;
3467
+ }
3468
+ else
3469
+ {
3470
+ continue;
3471
+ }
3472
+
3473
+ if (pServer->m_iCurChildren >=
3474
+ pServer->m_iMaxChildren + pServer->m_iExtraChildren)
3475
+ {
3476
+ lsapi_log("Reached max children process limit: %d, extra: %d,"
3477
+ " current: %d, busy: %d, please increase LSAPI_CHILDREN.\n",
3478
+ pServer->m_iMaxChildren, pServer->m_iExtraChildren,
3479
+ pServer->m_iCurChildren,
3480
+ s_busy_workers ? *s_busy_workers : -1);
3481
+ usleep(100000);
3482
+ continue;
3483
+ }
3484
+
3485
+ pReq->m_fd = lsapi_accept(pServer->m_fd);
3486
+ if (pReq->m_fd != -1)
3487
+ {
3488
+ wait_secs = 0;
3489
+ pReq->child_status = find_child_status(0);
3490
+
3491
+ ret = 0;
3492
+ break;
3493
+ }
3494
+ else
3495
+ {
3496
+ if ((errno == EINTR) || (errno == EAGAIN))
3497
+ continue;
3498
+ perror( "accept() failed" );
3499
+ ret = -1;
3500
+ break;
3501
+ }
3502
+ }
3503
+
3504
+ sigaction(SIGCHLD, &old_child, 0);
3505
+ sigaction(SIGTERM, &old_term, 0);
3506
+ sigaction(SIGQUIT, &old_quit, 0);
3507
+ sigaction(SIGINT, &old_int, 0);
3508
+ sigaction(SIGUSR1, &old_usr1, 0);
3509
+
3510
+ return ret;
3511
+ }
3512
+
3513
+
3514
+ void lsapi_perror( const char * pMessage, int err_no )
2965
3515
  {
2966
- fprintf( stderr, "%d: %s, errno: %d (%s)\n", getpid(), pMessage, err_no, strerror( err_no ) );
3516
+ lsapi_log("%s, errno: %d (%s)\n", pMessage, err_no,
3517
+ strerror( err_no ) );
2967
3518
  }
2968
3519
 
3520
+
2969
3521
  int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq )
2970
3522
  {
2971
3523
  int fd;
@@ -2974,11 +3526,10 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq )
2974
3526
  fd_set readfds;
2975
3527
  struct timeval timeout;
2976
3528
 
2977
- LSAPI_Finish_r( pReq );
3529
+ if (s_skip_write)
3530
+ return -1;
2978
3531
 
2979
- if (s_max_busy_children > 0 && s_busy_workers
2980
- && *s_busy_workers >= s_max_busy_children)
2981
- lsapi_close_connection(pReq);
3532
+ LSAPI_Finish_r( pReq );
2982
3533
 
2983
3534
  if ( g_prefork_server )
2984
3535
  {
@@ -2986,12 +3537,22 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq )
2986
3537
  if ( lsapi_prefork_server_accept( g_prefork_server, pReq ) == -1 )
2987
3538
  return -1;
2988
3539
  }
2989
- if ( s_req_processed >= s_max_reqs )
3540
+ else if (s_req_processed > 0 && s_max_busy_workers > 0 && s_busy_workers)
3541
+ {
3542
+ ret = __sync_fetch_and_add(s_busy_workers, 0);
3543
+ if (ret >= s_max_busy_workers)
3544
+ {
3545
+ send_conn_close_notification(pReq->m_fd);
3546
+ lsapi_close_connection(pReq);
3547
+ }
3548
+ }
3549
+
3550
+ if ( (unsigned int)s_req_processed > s_max_reqs )
2990
3551
  return -1;
2991
3552
 
2992
- if ( s_pChildStatus )
3553
+ if ( s_worker_status )
2993
3554
  {
2994
- s_pChildStatus->m_tmWaitBegin = time( NULL );
3555
+ s_worker_status->m_tmWaitBegin = time( NULL );
2995
3556
  }
2996
3557
 
2997
3558
 
@@ -3012,23 +3573,44 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq )
3012
3573
  {
3013
3574
  if ( !g_running )
3014
3575
  return -1;
3015
- if ((s_req_processed)&&( s_pChildStatus )&&( s_pChildStatus->m_iKillSent ))
3576
+ if (s_req_processed && s_worker_status
3577
+ && s_worker_status->m_iKillSent)
3016
3578
  return -1;
3017
3579
  FD_ZERO( &readfds );
3018
3580
  FD_SET( fd, &readfds );
3019
3581
  timeout.tv_sec = 1;
3020
3582
  timeout.tv_usec = 0;
3583
+ if (fd == pReq->m_fdListen)
3584
+ {
3585
+ if (s_worker_status)
3586
+ __sync_lock_test_and_set(&s_worker_status->m_state,
3587
+ LSAPI_STATE_ACCEPTING);
3588
+ if (s_accepting_workers)
3589
+ __sync_fetch_and_add(s_accepting_workers, 1);
3590
+ }
3021
3591
  ret = (*g_fnSelect)(fd+1, &readfds, NULL, NULL, &timeout);
3592
+ if (fd == pReq->m_fdListen)
3593
+ {
3594
+ if (s_accepting_workers)
3595
+ __sync_fetch_and_sub(s_accepting_workers, 1);
3596
+ if (s_worker_status)
3597
+ __sync_lock_test_and_set(&s_worker_status->m_state,
3598
+ LSAPI_STATE_IDLE);
3599
+ }
3600
+
3022
3601
  if ( ret == 0 )
3023
3602
  {
3024
- if ( s_pChildStatus )
3603
+ if ( s_worker_status )
3025
3604
  {
3026
- s_pChildStatus->m_inProcess = 0;
3605
+ s_worker_status->m_inProcess = 0;
3606
+ if (fd == pReq->m_fdListen
3607
+ && (s_keepListener != 2 || !is_enough_free_mem()))
3608
+ return -1;
3027
3609
  }
3028
3610
  ++wait_secs;
3029
3611
  if (( s_max_idle_secs > 0 )&&(wait_secs >= s_max_idle_secs ))
3030
3612
  return -1;
3031
- if ( s_ppid &&( getppid() != s_ppid))
3613
+ if ( lsapi_parent_dead() )
3032
3614
  return -1;
3033
3615
  }
3034
3616
  else if ( ret == -1 )
@@ -3040,15 +3622,17 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq )
3040
3622
  }
3041
3623
  else if ( ret >= 1 )
3042
3624
  {
3043
- if (s_req_processed && ( s_pChildStatus )&&( s_pChildStatus->m_iKillSent ))
3625
+ if (s_req_processed && s_worker_status
3626
+ && s_worker_status->m_iKillSent)
3044
3627
  return -1;
3045
3628
  if ( fd == pReq->m_fdListen )
3046
3629
  {
3047
3630
  pReq->m_fd = lsapi_accept( pReq->m_fdListen );
3048
3631
  if ( pReq->m_fd != -1 )
3049
3632
  {
3050
- if (s_pChildStatus)
3051
- s_pChildStatus->m_connected = 1;
3633
+ if (s_worker_status)
3634
+ __sync_lock_test_and_set(&s_worker_status->m_state,
3635
+ LSAPI_STATE_CONNECTED);
3052
3636
  if (s_busy_workers)
3053
3637
  __sync_fetch_and_add(s_busy_workers, 1);
3054
3638
 
@@ -3056,7 +3640,7 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq )
3056
3640
 
3057
3641
  lsapi_set_nblock( fd, 0 );
3058
3642
  //init_conn_key( pReq->m_fd );
3059
- if ( !s_keepListener )
3643
+ if (!s_keepListener)
3060
3644
  {
3061
3645
  close( pReq->m_fdListen );
3062
3646
  pReq->m_fdListen = -1;
@@ -3069,7 +3653,7 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq )
3069
3653
  {
3070
3654
  if (( errno == EINTR )||( errno == EAGAIN))
3071
3655
  continue;
3072
- lsapi_error( "lsapi_accept() error", errno );
3656
+ lsapi_perror( "lsapi_accept() error", errno );
3073
3657
  return -1;
3074
3658
  }
3075
3659
  }
@@ -3080,12 +3664,13 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq )
3080
3664
 
3081
3665
  if ( !readReq( pReq ) )
3082
3666
  {
3083
- if ( s_pChildStatus )
3667
+ if ( s_worker_status )
3084
3668
  {
3085
- s_pChildStatus->m_iKillSent = 0;
3086
- s_pChildStatus->m_inProcess = 1;
3087
- ++s_pChildStatus->m_iReqCounter;
3088
- s_pChildStatus->m_tmReqBegin = s_pChildStatus->m_tmLastCheckPoint = time(NULL);
3669
+ s_worker_status->m_iKillSent = 0;
3670
+ s_worker_status->m_inProcess = 1;
3671
+ ++s_worker_status->m_iReqCounter;
3672
+ s_worker_status->m_tmReqBegin =
3673
+ s_worker_status->m_tmLastCheckPoint = time(NULL);
3089
3674
  }
3090
3675
  ++s_req_processed;
3091
3676
  return 0;
@@ -3097,24 +3682,28 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq )
3097
3682
 
3098
3683
  }
3099
3684
 
3685
+
3100
3686
  void LSAPI_Set_Max_Reqs( int reqs )
3101
- { s_max_reqs = reqs; }
3687
+ { s_max_reqs = reqs - 1; }
3102
3688
 
3103
3689
  void LSAPI_Set_Max_Idle( int secs )
3104
3690
  { s_max_idle_secs = secs; }
3105
3691
 
3692
+
3106
3693
  void LSAPI_Set_Max_Children( int maxChildren )
3107
3694
  {
3108
3695
  if ( g_prefork_server )
3109
3696
  g_prefork_server->m_iMaxChildren = maxChildren;
3110
3697
  }
3111
3698
 
3699
+
3112
3700
  void LSAPI_Set_Extra_Children( int extraChildren )
3113
3701
  {
3114
3702
  if (( g_prefork_server )&&( extraChildren >= 0 ))
3115
3703
  g_prefork_server->m_iExtraChildren = extraChildren;
3116
3704
  }
3117
3705
 
3706
+
3118
3707
  void LSAPI_Set_Max_Process_Time( int secs )
3119
3708
  {
3120
3709
  if (( g_prefork_server )&&( secs > 0 ))
@@ -3128,17 +3717,20 @@ void LSAPI_Set_Max_Idle_Children( int maxIdleChld )
3128
3717
  g_prefork_server->m_iMaxIdleChildren = maxIdleChld;
3129
3718
  }
3130
3719
 
3720
+
3131
3721
  void LSAPI_Set_Server_Max_Idle_Secs( int serverMaxIdle )
3132
3722
  {
3133
3723
  if ( g_prefork_server )
3134
3724
  g_prefork_server->m_iServerMaxIdle = serverMaxIdle;
3135
3725
  }
3136
3726
 
3727
+
3137
3728
  void LSAPI_Set_Slow_Req_Msecs( int msecs )
3138
3729
  {
3139
3730
  s_slow_req_msecs = msecs;
3140
3731
  }
3141
3732
 
3733
+
3142
3734
  int LSAPI_Get_Slow_Req_Msecs(void)
3143
3735
  {
3144
3736
  return s_slow_req_msecs;
@@ -3150,6 +3742,13 @@ void LSAPI_No_Check_ppid(void)
3150
3742
  s_ppid = 0;
3151
3743
  }
3152
3744
 
3745
+
3746
+ int LSAPI_Get_ppid()
3747
+ {
3748
+ return(s_ppid);
3749
+ }
3750
+
3751
+
3153
3752
  #if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
3154
3753
  #include <crt_externs.h>
3155
3754
  #else
@@ -3178,6 +3777,7 @@ static void unset_lsapi_envs(void)
3178
3777
  }
3179
3778
  }
3180
3779
 
3780
+
3181
3781
  static int lsapi_initSuEXEC(void)
3182
3782
  {
3183
3783
  int i;
@@ -3237,7 +3837,7 @@ static int lsapi_check_path(const char *p, char *final, int max_len)
3237
3837
  {
3238
3838
  char resolved_path[PATH_MAX+1];
3239
3839
  int len = 0;
3240
- char *end, *temp;
3840
+ char *end;
3241
3841
  if (*p != '/')
3242
3842
  {
3243
3843
  if (getcwd(final, max_len) == NULL)
@@ -3270,7 +3870,7 @@ static int lsapi_reopen_stderr2(const char *full_path)
3270
3870
  int newfd = open(full_path, O_WRONLY | O_CREAT | O_APPEND, 0644);
3271
3871
  if (newfd == -1)
3272
3872
  {
3273
- LSAPI_perror_r(NULL, "failed to open custom stderr log", full_path);
3873
+ LSAPI_perror_r(NULL, "Failed to open custom stderr log", full_path);
3274
3874
  return -1;
3275
3875
  }
3276
3876
  if (newfd != 2)
@@ -3279,12 +3879,12 @@ static int lsapi_reopen_stderr2(const char *full_path)
3279
3879
  close(newfd);
3280
3880
  dup2(2, 1);
3281
3881
  }
3282
- if (s_pStderrLog && full_path != s_pStderrLog)
3882
+ if (s_stderr_log_path && full_path != s_stderr_log_path)
3283
3883
  {
3284
- free(s_pStderrLog);
3285
- s_pStderrLog = NULL;
3884
+ free(s_stderr_log_path);
3885
+ s_stderr_log_path = NULL;
3286
3886
  }
3287
- s_pStderrLog = strdup(full_path);
3887
+ s_stderr_log_path = strdup(full_path);
3288
3888
  return 0;
3289
3889
  }
3290
3890
 
@@ -3296,7 +3896,7 @@ static int lsapi_reopen_stderr(const char *p)
3296
3896
  return -1;
3297
3897
  if (lsapi_check_path(p, full_path, PATH_MAX) == -1)
3298
3898
  {
3299
- LSAPI_perror_r(NULL, "invalid custom stderr log path", p);
3899
+ LSAPI_perror_r(NULL, "Invalid custom stderr log path", p);
3300
3900
  return -1;
3301
3901
  }
3302
3902
  return lsapi_reopen_stderr2(full_path);
@@ -3306,6 +3906,7 @@ static int lsapi_reopen_stderr(const char *p)
3306
3906
  int LSAPI_Init_Env_Parameters( fn_select_t fp )
3307
3907
  {
3308
3908
  const char *p;
3909
+ char ch;
3309
3910
  int n;
3310
3911
  int avoidFork = 0;
3311
3912
 
@@ -3314,7 +3915,9 @@ int LSAPI_Init_Env_Parameters( fn_select_t fp )
3314
3915
  {
3315
3916
  lsapi_reopen_stderr(p);
3316
3917
  }
3317
-
3918
+ if (!s_stderr_log_path)
3919
+ s_stderr_is_pipe = isPipe(STDERR_FILENO);
3920
+
3318
3921
  p = getenv( "PHP_LSAPI_MAX_REQUESTS" );
3319
3922
  if ( !p )
3320
3923
  p = getenv( "LSAPI_MAX_REQS" );
@@ -3325,10 +3928,28 @@ int LSAPI_Init_Env_Parameters( fn_select_t fp )
3325
3928
  LSAPI_Set_Max_Reqs( n );
3326
3929
  }
3327
3930
 
3931
+ p = getenv( "LSAPI_KEEP_LISTEN" );
3932
+ if ( p )
3933
+ {
3934
+ n = atoi( p );
3935
+ s_keepListener = n;
3936
+ }
3937
+
3328
3938
  p = getenv( "LSAPI_AVOID_FORK" );
3329
3939
  if ( p )
3330
3940
  {
3331
3941
  avoidFork = atoi( p );
3942
+ if (avoidFork)
3943
+ {
3944
+ s_keepListener = 2;
3945
+ ch = *(p + strlen(p) - 1);
3946
+ if ( ch == 'G' || ch == 'g' )
3947
+ avoidFork *= 1024 * 1024 * 1024;
3948
+ else if ( ch == 'M' || ch == 'm' )
3949
+ avoidFork *= 1024 * 1024;
3950
+ if (avoidFork >= 1024 * 10240)
3951
+ s_min_avail_pages = avoidFork / 4096;
3952
+ }
3332
3953
  }
3333
3954
 
3334
3955
  p = getenv( "LSAPI_ACCEPT_NOTIFY" );
@@ -3363,14 +3984,6 @@ int LSAPI_Init_Env_Parameters( fn_select_t fp )
3363
3984
  LSAPI_Set_Max_Idle( n );
3364
3985
  }
3365
3986
 
3366
- p = getenv( "LSAPI_KEEP_LISTEN" );
3367
- if ( p )
3368
- {
3369
- n = atoi( p );
3370
- s_keepListener = n;
3371
- }
3372
-
3373
-
3374
3987
  if ( LSAPI_Is_Listen() )
3375
3988
  {
3376
3989
  n = 0;
@@ -3381,7 +3994,7 @@ int LSAPI_Init_Env_Parameters( fn_select_t fp )
3381
3994
  n = atoi( p );
3382
3995
  if ( n > 1 )
3383
3996
  {
3384
- LSAPI_Init_Prefork_Server( n, fp, avoidFork );
3997
+ LSAPI_Init_Prefork_Server( n, fp, avoidFork != 0 );
3385
3998
  LSAPI_Set_Server_fd( g_req.m_fdListen );
3386
3999
  }
3387
4000
 
@@ -3407,6 +4020,16 @@ int LSAPI_Init_Env_Parameters( fn_select_t fp )
3407
4020
  {
3408
4021
  LSAPI_No_Check_ppid();
3409
4022
  }
4023
+
4024
+ p = getenv("LSAPI_MAX_BUSY_WORKER");
4025
+ if (p)
4026
+ {
4027
+ n = atoi(p);
4028
+ s_max_busy_workers = n;
4029
+ if (n >= 0)
4030
+ LSAPI_No_Check_ppid();
4031
+ }
4032
+
3410
4033
 
3411
4034
  p = getenv( "LSAPI_DUMP_DEBUG_INFO" );
3412
4035
  if ( p )
@@ -3460,6 +4083,7 @@ static void byteReverse(unsigned char *buf, unsigned longs)
3460
4083
  } while (--longs);
3461
4084
  }
3462
4085
 
4086
+
3463
4087
  /*
3464
4088
  * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
3465
4089
  * initialization constants.
@@ -3523,6 +4147,7 @@ void lsapi_MD5Update(struct lsapi_MD5Context *ctx, unsigned char const *buf, uns
3523
4147
  memmove(ctx->in, buf, len);
3524
4148
  }
3525
4149
 
4150
+
3526
4151
  /*
3527
4152
  * Final wrapup - pad to 64-byte boundary with the bit pattern
3528
4153
  * 1 0* (64-bit count of bits processed, MSB-first)
@@ -3568,6 +4193,7 @@ void lsapi_MD5Final(unsigned char digest[16], struct lsapi_MD5Context *ctx)
3568
4193
  memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
3569
4194
  }
3570
4195
 
4196
+
3571
4197
  /* The four core functions - F1 is optimized somewhat */
3572
4198
 
3573
4199
  /* #define F1(x, y, z) (x & y | ~x & z) */
@@ -3668,3 +4294,18 @@ static void lsapi_MD5Transform(uint32 buf[4], uint32 const in[16])
3668
4294
  buf[3] += d;
3669
4295
  }
3670
4296
 
4297
+
4298
+ int LSAPI_Set_Restored_Parent_Pid(int pid)
4299
+ {
4300
+ int old_ppid = s_ppid;
4301
+ s_restored_ppid = pid;
4302
+ return old_ppid;
4303
+ }
4304
+
4305
+
4306
+ int LSAPI_Inc_Req_Processed(int cnt)
4307
+ {
4308
+ return __sync_add_and_fetch(s_global_counter, cnt);
4309
+ }
4310
+
4311
+