这是相关的代码,我希望尽可能地缩短它,而不希望排除错误源。
DebugLogMsg是类似于printf的日志文件编写工具,可以认为未引起错误。
//Some init stuff and smthng
while (1)
{
memset (&requestFcgx, 0, sizeof (requestFcgx));
iRet = FCGX_InitRequest (&requestFcgx, 0, 0);
DebugLogMsg ("FCGX_InitRequest() called!!\r\n");
if (iRet != 0)
{
DebugLogMsg ("FCGX_InitRequest failed, return val:%d!\r\n", iRet);
return NULL;
}
iRet = FCGX_Accept_r (&requestFcgx);
if (iRet != 0)
{
DebugLogMsg1 ("FCGX_Accept_r failed!\r\n");
continue;
}
char *foo = FCGX_GetParam("SOME_CUSTOM_VAL", requestFcgx.envp);
DebugLogMsg ("CustomParam:%s\r\n", foo);
do
{
//processing the request...
if (ERROR == TRUE)
{
DebugLogMsg ("FatalError!\r\n");
return NULL;
}
DebugLogMsg ("no errors occured!");
}
while (0);
FCGX_Finish_r (&requestFcgx);
DebugLogMsg ("Cleanup.... DONE!\r\n");
}
我的问题是
iRet = FCGX_Accept_r (&requestFcgx);
不会像应该的那样阻塞每个第二个调用。 (至少我希望此功能能够被阻止)网络服务器发送请求后,该函数将释放,在循环中运行且不会记录任何错误,调用Finish,循环到循环主体的开头,再次调用
iRet = FCGX_Accept_r (&requestFcgx);
时,它会立即返回iRet == 0
但是requestFcgx
结构似乎无效(可以预期,因为甚至没有发起附加请求)。相应的日志文件包含此过程:[Wed Apr 15 15:41:26 2015][Thread:0;0x802420040] FCGX_InitRequest() called!
----------------------------------------
[Wed Apr 15 15:41:26 2015][Thread:0;0x802420040] CustomParam:ExpectedStuff
[Wed Apr 15 15:41:26 2015][Thread:0;0x802420040] no errors occured!
[Wed Apr 15 15:41:26 2015][Thread:0;0x802420040] Cleanup.... DONE!
[Wed Apr 15 15:41:26 2015][Thread:0;0x802420040] FCGX_InitRequest() called!
----------------------------------------
[Wed Apr 15 15:41:26 2015][Thread:0;0x802420040] CustomParam:(null)
[Wed Apr 15 15:41:26 2015][Thread:0;0x802420040] FatalError!
//////////////////////////////
////////Protocol closed///////
//////////////////////////////
(请有人将Logtext编辑为不格式化为代码,我不知道该怎么做)
由于请求不提供信息并被关闭,因此发生致命错误。关键是,为什么
iRet = FCGX_Accept_r (&requestFcgx);
在明显失败时返回0
?如果可以预期的话,我还必须考虑这种行为的程度。 最佳答案
有两个问题-
进入FCGX_InitRequest(&requestFcgx, 0, 0)
循环之前,必须先调用while(1)
。
SIGPIPE信号也会导致这种现象。尝试忽略它。将此块添加到main()
函数的开头-
struct sigaction sa_ign;
sa_ign.sa_handler = SIG_IGN;
sa_ign.sa_flags = 0;
sigemptyset(&sa_ign.sa_mask);
sigaction(SIGPIPE, &sa_ign, NULL);
您提到该应用是多线程的。如果是这样,还必须调用
FCGX_Init()
。以下是fcgiapp.h
头文件中的信息-/*
*----------------------------------------------------------------------
*
* FCGX_Init --
*
* Initialize the FCGX library. Call in multi-threaded apps
* before calling FCGX_Accept_r().
*
* Returns 0 upon success.
*
*----------------------------------------------------------------------
*/
DLLAPI int FCGX_Init(void);
检查这个简单的多线程FastCGI应用程序-
http://www.fastcgi.com/devkit/examples/threaded.c