Back to index

php5  5.3.10
fpm_request.c
Go to the documentation of this file.
00001 
00002        /* $Id: fpm_request.c,v 1.9.2.1 2008/11/15 00:57:24 anight Exp $ */
00003        /* (c) 2007,2008 Andrei Nigmatulin */
00004 #ifdef HAVE_TIMES
00005 #include <sys/times.h>
00006 #endif
00007 
00008 #include "fpm_config.h"
00009 
00010 #include "fpm.h"
00011 #include "fpm_php.h"
00012 #include "fpm_str.h"
00013 #include "fpm_clock.h"
00014 #include "fpm_conf.h"
00015 #include "fpm_trace.h"
00016 #include "fpm_php_trace.h"
00017 #include "fpm_process_ctl.h"
00018 #include "fpm_children.h"
00019 #include "fpm_scoreboard.h"
00020 #include "fpm_status.h"
00021 #include "fpm_request.h"
00022 #include "fpm_log.h"
00023 
00024 #include "zlog.h"
00025 
00026 static const char *requests_stages[] = {
00027        [FPM_REQUEST_ACCEPTING]       = "Idle",
00028        [FPM_REQUEST_READING_HEADERS] = "Reading headers",
00029        [FPM_REQUEST_INFO]            = "Getting request informations",
00030        [FPM_REQUEST_EXECUTING]       = "Running",
00031        [FPM_REQUEST_END]             = "Ending",
00032        [FPM_REQUEST_FINISHED]        = "Finishing",
00033 };
00034 
00035 const char *fpm_request_get_stage_name(int stage) {
00036        return requests_stages[stage];
00037 }
00038 
00039 void fpm_request_accepting() /* {{{ */
00040 {
00041        struct fpm_scoreboard_proc_s *proc;
00042        struct timeval now;
00043 
00044        fpm_clock_get(&now);
00045 
00046        proc = fpm_scoreboard_proc_acquire(NULL, -1, 0);
00047        if (proc == NULL) {
00048               zlog(ZLOG_WARNING, "failed to acquire proc scoreboard");
00049               return;
00050        }
00051 
00052        proc->request_stage = FPM_REQUEST_ACCEPTING;
00053        proc->tv = now;
00054        fpm_scoreboard_proc_release(proc);
00055 
00056        /* idle++, active-- */
00057        fpm_scoreboard_update(1, -1, 0, 0, 0, 0, FPM_SCOREBOARD_ACTION_INC, NULL);
00058 }
00059 /* }}} */
00060 
00061 void fpm_request_reading_headers() /* {{{ */
00062 {
00063        struct fpm_scoreboard_proc_s *proc;
00064 
00065        struct timeval now;
00066        clock_t now_epoch;
00067 #ifdef HAVE_TIMES
00068        struct tms cpu;
00069 #endif
00070 
00071        fpm_clock_get(&now);
00072        now_epoch = time(NULL);
00073 #ifdef HAVE_TIMES
00074        times(&cpu);
00075 #endif
00076 
00077        proc = fpm_scoreboard_proc_acquire(NULL, -1, 0);
00078        if (proc == NULL) {
00079               zlog(ZLOG_WARNING, "failed to acquire proc scoreboard");
00080               return;
00081        }
00082 
00083        proc->request_stage = FPM_REQUEST_READING_HEADERS;
00084        proc->tv = now;
00085        proc->accepted = now;
00086        proc->accepted_epoch = now_epoch;
00087 #ifdef HAVE_TIMES
00088        proc->cpu_accepted = cpu;
00089 #endif
00090        proc->requests++;
00091        proc->request_uri[0] = '\0';
00092        proc->request_method[0] = '\0';
00093        proc->script_filename[0] = '\0';
00094        proc->query_string[0] = '\0';
00095        proc->query_string[0] = '\0';
00096        proc->auth_user[0] = '\0';
00097        proc->content_length = 0;
00098        fpm_scoreboard_proc_release(proc);
00099 
00100        /* idle--, active++, request++ */
00101        fpm_scoreboard_update(-1, 1, 0, 0, 1, 0, FPM_SCOREBOARD_ACTION_INC, NULL);
00102 }
00103 /* }}} */
00104 
00105 void fpm_request_info() /* {{{ */
00106 {
00107        TSRMLS_FETCH();
00108        struct fpm_scoreboard_proc_s *proc;
00109        char *request_uri = fpm_php_request_uri(TSRMLS_C);
00110        char *request_method = fpm_php_request_method(TSRMLS_C);
00111        char *script_filename = fpm_php_script_filename(TSRMLS_C);
00112        char *query_string = fpm_php_query_string(TSRMLS_C);
00113        char *auth_user = fpm_php_auth_user(TSRMLS_C);
00114        size_t content_length = fpm_php_content_length(TSRMLS_C);
00115        struct timeval now;
00116 
00117        fpm_clock_get(&now);
00118 
00119        proc = fpm_scoreboard_proc_acquire(NULL, -1, 0);
00120        if (proc == NULL) {
00121               zlog(ZLOG_WARNING, "failed to acquire proc scoreboard");
00122               return;
00123        }
00124 
00125        proc->request_stage = FPM_REQUEST_INFO;
00126        proc->tv = now;
00127 
00128        if (request_uri) {
00129               strlcpy(proc->request_uri, request_uri, sizeof(proc->request_uri));
00130        }
00131 
00132        if (request_method) {
00133               strlcpy(proc->request_method, request_method, sizeof(proc->request_method));
00134        }
00135 
00136        if (query_string) {
00137               strlcpy(proc->query_string, query_string, sizeof(proc->query_string));
00138        }
00139 
00140        if (auth_user) {
00141               strlcpy(proc->auth_user, auth_user, sizeof(proc->auth_user));
00142        }
00143 
00144        proc->content_length = content_length;
00145 
00146        /* if cgi.fix_pathinfo is set to "1" and script cannot be found (404)
00147               the sapi_globals.request_info.path_translated is set to NULL */
00148        if (script_filename) {
00149               strlcpy(proc->script_filename, script_filename, sizeof(proc->script_filename));
00150        }
00151 
00152        fpm_scoreboard_proc_release(proc);
00153 }
00154 /* }}} */
00155 
00156 void fpm_request_executing() /* {{{ */
00157 {
00158        struct fpm_scoreboard_proc_s *proc;
00159        struct timeval now;
00160 
00161        fpm_clock_get(&now);
00162 
00163        proc = fpm_scoreboard_proc_acquire(NULL, -1, 0);
00164        if (proc == NULL) {
00165               zlog(ZLOG_WARNING, "failed to acquire proc scoreboard");
00166               return;
00167        }
00168 
00169        proc->request_stage = FPM_REQUEST_EXECUTING;
00170        proc->tv = now;
00171        fpm_scoreboard_proc_release(proc);
00172 }
00173 /* }}} */
00174 
00175 void fpm_request_end(TSRMLS_D) /* {{{ */
00176 {
00177        struct fpm_scoreboard_proc_s *proc;
00178        struct timeval now;
00179 #ifdef HAVE_TIMES
00180        struct tms cpu;
00181 #endif
00182        size_t memory = zend_memory_peak_usage(1 TSRMLS_CC);
00183 
00184        fpm_clock_get(&now);
00185 #ifdef HAVE_TIMES
00186        times(&cpu);
00187 #endif
00188 
00189        proc = fpm_scoreboard_proc_acquire(NULL, -1, 0);
00190        if (proc == NULL) {
00191               zlog(ZLOG_WARNING, "failed to acquire proc scoreboard");
00192               return;
00193        }
00194        proc->request_stage = FPM_REQUEST_FINISHED;
00195        proc->tv = now;
00196        timersub(&now, &proc->accepted, &proc->duration);
00197 #ifdef HAVE_TIMES
00198        timersub(&proc->tv, &proc->accepted, &proc->cpu_duration);
00199        proc->last_request_cpu.tms_utime = cpu.tms_utime - proc->cpu_accepted.tms_utime;
00200        proc->last_request_cpu.tms_stime = cpu.tms_stime - proc->cpu_accepted.tms_stime;
00201        proc->last_request_cpu.tms_cutime = cpu.tms_cutime - proc->cpu_accepted.tms_cutime;
00202        proc->last_request_cpu.tms_cstime = cpu.tms_cstime - proc->cpu_accepted.tms_cstime;
00203 #endif
00204        proc->memory = memory;
00205        fpm_scoreboard_proc_release(proc);
00206 }
00207 /* }}} */
00208 
00209 void fpm_request_finished() /* {{{ */
00210 {
00211        struct fpm_scoreboard_proc_s *proc;
00212        struct timeval now;
00213 
00214        fpm_clock_get(&now);
00215 
00216        proc = fpm_scoreboard_proc_acquire(NULL, -1, 0);
00217        if (proc == NULL) {
00218               zlog(ZLOG_WARNING, "failed to acquire proc scoreboard");
00219               return;
00220        }
00221 
00222        proc->request_stage = FPM_REQUEST_FINISHED;
00223        proc->tv = now;
00224        memset(&proc->accepted, 0, sizeof(proc->accepted));
00225        proc->accepted_epoch = 0;
00226        fpm_scoreboard_proc_release(proc);
00227 }
00228 /* }}} */
00229 
00230 void fpm_request_check_timed_out(struct fpm_child_s *child, struct timeval *now, int terminate_timeout, int slowlog_timeout) /* {{{ */
00231 {
00232        struct fpm_scoreboard_proc_s proc, *proc_p;
00233 
00234        proc_p = fpm_scoreboard_proc_acquire(child->wp->scoreboard, child->scoreboard_i, 1);
00235        if (!proc_p) {
00236               zlog(ZLOG_WARNING, "failed to acquire scoreboard");
00237               return;
00238        }
00239 
00240        proc = *proc_p;
00241        fpm_scoreboard_proc_release(proc_p);
00242 
00243 #if HAVE_FPM_TRACE
00244        if (child->slow_logged.tv_sec) {
00245               if (child->slow_logged.tv_sec != proc.accepted.tv_sec || child->slow_logged.tv_usec != proc.accepted.tv_usec) {
00246                      child->slow_logged.tv_sec = 0;
00247                      child->slow_logged.tv_usec = 0;
00248               }
00249        }
00250 #endif
00251 
00252        if (proc.request_stage > FPM_REQUEST_ACCEPTING && proc.request_stage < FPM_REQUEST_END) {
00253               char purified_script_filename[sizeof(proc.script_filename)];
00254               struct timeval tv;
00255 
00256               timersub(now, &proc.accepted, &tv);
00257 
00258 #if HAVE_FPM_TRACE
00259               if (child->slow_logged.tv_sec == 0 && slowlog_timeout &&
00260                             proc.request_stage == FPM_REQUEST_EXECUTING && tv.tv_sec >= slowlog_timeout) {
00261                      
00262                      str_purify_filename(purified_script_filename, proc.script_filename, sizeof(proc.script_filename));
00263 
00264                      child->slow_logged = proc.accepted;
00265                      child->tracer = fpm_php_trace;
00266 
00267                      fpm_trace_signal(child->pid);
00268 
00269                      zlog(ZLOG_WARNING, "[pool %s] child %d, script '%s' (request: \"%s %s\") executing too slow (%d.%06d sec), logging",
00270                             child->wp->config->name, (int) child->pid, purified_script_filename, proc.request_method, proc.request_uri,
00271                             (int) tv.tv_sec, (int) tv.tv_usec);
00272               }
00273               else
00274 #endif
00275               if (terminate_timeout && tv.tv_sec >= terminate_timeout) {
00276                      str_purify_filename(purified_script_filename, proc.script_filename, sizeof(proc.script_filename));
00277                      fpm_pctl_kill(child->pid, FPM_PCTL_TERM);
00278 
00279                      zlog(ZLOG_WARNING, "[pool %s] child %d, script '%s' (request: \"%s %s\") execution timed out (%d.%06d sec), terminating",
00280                             child->wp->config->name, (int) child->pid, purified_script_filename, proc.request_method, proc.request_uri,
00281                             (int) tv.tv_sec, (int) tv.tv_usec);
00282               }
00283        }
00284 }
00285 /* }}} */
00286 
00287 int fpm_request_is_idle(struct fpm_child_s *child) /* {{{ */
00288 {
00289        struct fpm_scoreboard_proc_s *proc;
00290 
00291        /* no need in atomicity here */
00292        proc = fpm_scoreboard_proc_get(child->wp->scoreboard, child->scoreboard_i);
00293        if (!proc) {
00294               return 0;
00295        }
00296 
00297        return proc->request_stage == FPM_REQUEST_ACCEPTING;
00298 }
00299 /* }}} */
00300 
00301 int fpm_request_last_activity(struct fpm_child_s *child, struct timeval *tv) /* {{{ */
00302 {
00303        struct fpm_scoreboard_proc_s *proc;
00304 
00305        if (!tv) return -1;
00306 
00307        proc = fpm_scoreboard_proc_get(child->wp->scoreboard, child->scoreboard_i);
00308        if (!proc) {
00309               return -1;
00310        }
00311 
00312        *tv = proc->tv;
00313 
00314        return 1;
00315 }
00316 /* }}} */