【问题标题】:FCGX_Accept_r returns success without valid RequestFCGX_Accept_r 在没有有效请求的情况下返回成功
【发布时间】:2015-06-21 13:50:11
【问题描述】:

这是相关代码,我尽量短了希望不排除错误源。

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); 不会阻止每个第二次呼叫,因为它应该。 (至少我希望这个函数应该是阻塞的)

一旦网络服务器发送请求,Function 就会释放,在没有记录任何错误的情况下运行循环,调用 Finish,循环到循环体的开头,当再次调用 iRet = FCGX_Accept_r (&requestFcgx); 时,它会立即返回iRet == 0requestFcgx 结构似乎无效(这是可以预料的,因为甚至没有发起附加请求)。此进程对应的日志文件包含:

[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?以及我必须在多大程度上考虑这种行为,如果预期这样做的话。

【问题讨论】:

    标签: c fastcgi


    【解决方案1】:

    有两个问题-

    1. 在进入while(1)循环之前需要调用FCGX_InitRequest(&requestFcgx, 0, 0)
    2. 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

    【讨论】:

    • 所以FCGX_InitRequest(&requestFcgx, 0, 0) 不是FCGX_Finish_r (&requestFcgx) 的对应部分吗?所以FCGX_Finish_r (&requestFcgx) 没有清理任何东西,需要重新初始化吗?
    • 这是众所周知的,但遗憾的是没有解决问题。知道while(1) 在多个pthread 中运行是否重要?正如您所说,我将代码放在我的main() 前面。
    • FCXG_Finish_r() 释放由 FCGX_Accept_r() 分配的资源,应该在 While(1) 循环结束或“继续”语句之前调用。
    • 如果你的 FCGI 循环在线程中,那么 FCGX_InitRequest() 应该在线程函数中,而不是在 main() 函数中。您可以在 while(1) 循环之前调用 FCGX_InitRequest()。
    • 我没有看到你调用 FCGX_Init() 必须在多线程应用程序中调用。我更新了关于 FCGX_Init() 的答案。请检查
    猜你喜欢
    • 2019-06-09
    • 1970-01-01
    • 2012-03-26
    • 1970-01-01
    • 2011-12-06
    • 1970-01-01
    • 2018-07-16
    • 2021-06-27
    • 2017-11-02
    相关资源
    最近更新 更多