/*
* mod_fastcgi.c --
*
* Apache server module for FastCGI.
*
* $Id: mod_fastcgi.c,v 1.162 2007/11/12 23:00:10 robs Exp $
*
* Copyright (c) 1995-1996 Open Market, Inc.
*
* See the file "LICENSE.TERMS" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
*
* Patches for Apache-1.1 provided by
* Ralf S. Engelschall
* <rse@en.muc.de>
*
* Patches for Linux provided by
* Scott Langley
* <langles@vote-smart.org>
*
* Patches for suexec handling by
* Brian Grossman <brian@SoftHome.net> and
* Rob Saccoccio <robs@ipass.net>
*/
/*
* Module design notes.
*
* 1. Restart cleanup.
*
* mod_fastcgi spawns several processes: one process manager process
* and several application processes. None of these processes
* handle SIGHUP, so they just go away when the Web server performs
* a restart (as Apache does every time it starts.)
*
* In order to allow the process manager to properly cleanup the
* running fastcgi processes (without being disturbed by Apache),
* an intermediate process was introduced. The diagram is as follows;
*
* ApacheWS --> MiddleProc --> ProcMgr --> FCGI processes
*
* On a restart, ApacheWS sends a SIGKILL to MiddleProc and then
* collects it via waitpid(). The ProcMgr periodically checks for
* its parent (via getppid()) and if it does not have one, as in
* case when MiddleProc has terminated, ProcMgr issues a SIGTERM
* to all FCGI processes, waitpid()s on them and then exits, so it
* can be collected by init(1). Doing it any other way (short of
* changing Apache API), results either in inconsistent results or
* in generation of zombie processes.
*
* XXX: How does Apache 1.2 implement "gentle" restart
* that does not disrupt current connections? How does
* gentle restart interact with restart cleanup?
*
* 2. Request timeouts.
*
* Earlier versions of this module used ap_soft_timeout() rather than
* ap_hard_timeout() and ate FastCGI server output until it completed.
* This precluded the FastCGI server from having to implement a
* SIGPIPE handler, but meant hanging the application longer than
* necessary. SIGPIPE handler now must be installed in ALL FastCGI
* applications. The handler should abort further processing and go
* back into the accept() loop.
*
* Although using ap_soft_timeout() is better than ap_hard_timeout()
* we have to be more careful about SIGINT handling and subsequent
* processing, so, for now, make it hard.
*/
#include "fcgi.h"
#ifdef APACHE2
#ifndef WIN32
#include <unistd.h>
#if APR_HAVE_CTYPE_H
#include <ctype.h>
#endif
#include "unixd.h"
#endif
#endif
#ifndef timersub
#define timersub(a, b, result) \
do { \
(result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
(result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
if ((result)->tv_usec < 0) { \
--(result)->tv_sec; \
(result)->tv_usec += 1000000; \
} \
} while (0)
#endif
/*
* Global variables
*/
pool *fcgi_config_pool; /* the config pool */
server_rec *fcgi_apache_main_server;
const char *fcgi_wrapper = NULL; /* wrapper path */
uid_t fcgi_user_id; /* the run uid of Apache & PM */
gid_t fcgi_group_id; /* the run gid of Apache & PM */
fcgi_server *fcgi_servers = NULL; /* AppClasses */
char *fcgi_socket_dir = NULL; /* default FastCgiIpcDir */
char *fcgi_dynamic_dir = NULL; /* directory for the dynamic
* fastcgi apps' sockets */
#ifdef WIN32
#pragma warning( disable : 4706 4100 4127)
fcgi_pm_job *fcgi_dynamic_mbox = NULL;
HANDLE *fcgi_dynamic_mbox_mutex = NULL;
HANDLE fcgi_pm_thread = INVALID_HANDLE_VALUE;
#else
int fcgi_pm_pipe[2] = { -1, -1 };
pid_t fcgi_pm_pid = -1;
#endif
char *fcgi_empty_env = NULL;
u_int dynamicMaxProcs = FCGI_DEFAULT_MAX_PROCS;
int dynamicMinProcs = FCGI_DEFAULT_MIN_PROCS;
int dynamicMaxClassProcs = FCGI_DEFAULT_MAX_CLASS_PROCS;
u_int dynamicKillInterval = FCGI_DEFAULT_KILL_INTERVAL;
u_int dynamicUpdateInterval = FCGI_DEFAULT_UPDATE_INTERVAL;
float dynamicGain = FCGI_DEFAULT_GAIN;
int dynamicThreshold1 = FCGI_DEFAULT_THRESHOLD_1;
int dynamicThresholdN = FCGI_DEFAULT_THRESHOLD_N;
u_int dynamicPleaseStartDelay = FCGI_DEFAULT_START_PROCESS_DELAY;
u_int dynamicAppConnectTimeout = FCGI_DEFAULT_APP_CONN_TIMEOUT;
char **dynamicEnvp = &fcgi_empty_env;
u_int dynamicProcessSlack = FCGI_DEFAULT_PROCESS_SLACK;
int dynamicAutoRestart = FCGI_DEFAULT_RESTART_DYNAMIC;
int dynamicAutoUpdate = FCGI_DEFAULT_AUTOUPDATE;
int dynamicFlush = FCGI_FLUSH;
u_int dynamicListenQueueDepth = FCGI_DEFAULT_LISTEN_Q;
u_int dynamicInitStartDelay = DEFAULT_INIT_START_DELAY;
u_int dynamicRestartDelay = FCGI_DEFAULT_RESTART_DELAY;
array_header *dynamic_pass_headers = NULL;
u_int dynamic_idle_timeout = FCGI_DEFAULT_IDLE_TIMEOUT;
int dynamicMinServerLife = FCGI_DEFAULT_MIN_SERVER_LIFE;
/*******************************************************************************
* Construct a message and write it to the pm_pipe.
*/
static void send_to_pm(const char id, const char * const fs_path,
const char *user, const char * const group, const unsigned long q_usec,
const unsigned long req_usec)
{
#ifdef WIN32
fcgi_pm_job *job = NULL;
if (!(job = (fcgi_pm_job *) malloc(sizeof(fcgi_pm_job))))
return;
#else
static int failed_count = 0;
int buflen = 0;
char buf[FCGI_MAX_MSG_LEN];
#endif
if (strlen(fs_path) > FCGI_MAXPATH) {
ap_log_error(FCGI_LOG_ERR_NOERRNO, fcgi_apache_main_server,
"FastCGI: the path \"%s\" is too long (>%d) for a dynamic server", fs_path, FCGI_MAXPATH);
return;
}
switch(id) {
case FCGI_SERVER_START_JOB:
case FCGI_SERVER_RESTART_JOB:
#ifdef WIN32
job->id = id;
job->fs_path = strdup(fs_path);
job->user = strdup(user);
job->group = strdup(group);
job->qsec = 0L;
job->start_time = 0L;
#else
buflen = sprintf(buf, "%c %s %s %s*", id, fs_path, user, group);
#endif
break;
case FCGI_REQUEST_TIMEOUT_JOB:
#ifdef WIN32
job->id = id;
job->fs_path = strdup(fs_path);
job->user = strdup(user);
job->group = strdup(group);
job->qsec = 0L;
job->start_time = 0L;
#else
buflen = sprintf(buf, "%c %s %s %s*", id, fs_path, user, group);
#endif
break;
case FCGI_REQUEST_COMPLETE_JOB:
#ifdef WIN32
job->id = id;
job->fs_path = strdup(fs_path);
job->qsec = q_usec;
job->start_time = req_usec;
job->user = strdup(user);
job->group = strdup(group);
#else
buflen = sprintf(buf, "%c %s %s %s %lu %lu*", id, fs_path, user, group, q_usec, req_usec);
#endif
break;
}
#ifdef WIN32
if (fcgi_pm_add_job(job)) return;
SetEvent(fcgi_event_handles[MBOX_EVENT]);
#else
ASSERT(buflen <= FCGI_MAX_MSG_LEN);
/* There is no apache flag or function that can be used to id
* restart/shutdown pending so ignore the first few failures as
* once it breaks it will stay broke */
if (write(fcgi_pm_pipe[1], (const void *)buf, buflen) != buflen
&& failed_count++ > 10)
{
ap_log_error(FCGI_LOG_WARN, fcgi_apache_main_server,
"FastCGI: write() to PM failed (ignore if a restart or shutdown is pending)");
}
#endif
}
/*
*----------------------------------------------------------------------
*
* init_module
*
* An Apache module initializer, called by the Apache core
* after reading the server config.
*
* Start the process manager no matter what, since there may be a
* request
wangkangluo1
- 粉丝: 0
- 资源: 12
最新资源
- VMware虚拟机安装、备份与恢复全攻略
- 昆仑通态MCGS与3台英威腾GD变频器通讯 器件:昆仑通态触摸屏,3台英威腾GD系列变频器,附送接线说明和设置说明 功能:实现频率设定,启停控制,实际频率读取等,状态指示
- 机会约束最优潮流:不确定性下的风险感知网络控制 python源代码,代码按照高水平文章复现,保证正确 当不可控制的资源波动时,电力行业通常使用最优潮流(OPF)在输电网络的控制区域重新调度每小时可控的
- 最优控制电池储能模型 蓄电池储能模型的最优控制python源代码,代码按照高水平文章复现 包含五个python脚本,它从data .csv读取价格、负载和温度数据 然后用本文中描述的决策变量、目标和
- 项目管理表格,用来管理项目进度以及把控项目过程
- 一种分布式鲁棒优化的微电网单元分配方法 python源代码,代码按照高水平文章复现,保证正确 针对电网负荷和电力市场价格不确定的情况,提出了一种分布式鲁棒单元承诺方法 提出的关键推力的方法是利用Ku
- 不同操作系统下Node.js安装与环境配置教程:涵盖Windows、macOS和Linux系统
- VMware虚拟机安装与备份恢复全解析:覆盖下载、安装、配置到高级数据保护策略
- 变压器励磁模型 Matlab simulink 质量过硬 可用于模拟电压暂降等电能质量问题,适配于本家的IEEE 33节点模型
- 微信小程序开发全流程解析:从账号注册到API调用与发布
- 利用插电式电动汽车提高电网暂态稳定性 python联合PSS E源代码,代码按照高水平文章复现,保证正确 插电式电动汽车(pev)在放电模式下可以作为分布式能源和电力资源,作为车到网(V2G)设备运行
- 基于自适应在线学习的概率负荷预测python联合matlab源代码 负荷预测对于多种能源管理任务是至关重要的,例如调度发电能力,规划供应和需求,最小化能源交易成本 近年来,由于可再生能源、电动汽车和
- 示例:在 Python 中定义链表
- 平台采用小米1代扫地机 目前只有32端代码能实现延边避障防跌 落充电等功能 适合需要学习项目与代码规范的工程师 硬件驱动包含 陀螺仪姿态传感器bmi160、电源管理bq24733等 软件驱
- 电网经济和频率控制的多层,多时间尺度模型方法 Julia源代码,代码按照高水平文章复现,保证正确,可先发您文章看是否满足您的要求 由于分散的可再生能源和存储的不断增加,电力系统受到根本性变化的影响
- java将八进制转换为十进制的自定义方法
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
- 1
- 2
- 3
- 4
- 5
- 6
前往页