Commit 1ef99d7b authored by Ryan Bloom's avatar Ryan Bloom
Browse files

Close the accepted socket before creating the CGI process in mod_cgid.

This is safe, because we have already dup'ed the socket for the CGI
process itself.  This change allows CGI processes to fork long-lived
child processes without affecting how quickly the response gets back
to the broswer.

PR:	7273
Submitted by:	Taketo Kabe <kabe@sra-tohoku.co.jp>
Reviewed by:	Ryan Bloom


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@88264 13f79535-47bb-0310-9956-ffa450edef68
parent 01a5d515
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
Changes with Apache 2.0.12-dev

  *) Close one copy of the CGI's stdout before creating the new process.
     The CGI will still have stdout, because we have already dup'ed it.
     This keeps Apache from waiting forever to send the results of a CGI
     process that has forked a long-lived child process.
     [Taketo Kabe <kabe@sra-tohoku.co.jp>]

  *) Remove the rest of the pthreads functions from the threaded MPM.
     This requires the APR support for a signal thread that was just
     added.  [Ryan Bloom]
+10 −1
Original line number Diff line number Diff line
@@ -549,11 +549,20 @@ static int cgid_server(void *data)
        }
        else {
            argv = (const char * const *)create_argv(r->pool, NULL, NULL, NULL, argv0, r->args);

           /* We want to sd2 close for new CGI process too.
            * If it's remained open it'll make ap_pass_brigade() block
            * waiting for EOF if CGI forked something running long.
            * close(sd2) here should be okay, as CGI channel
            * is already dup()ed by apr_procattr_child_{in,out}_set()
            * above.
            */
            close(sd2);

            rc = ap_os_create_privileged_process(r, procnew, argv0, argv, 
                                                 (const char * const *)env, 
                                                 procattr, p);

            close(sd2);
            if (rc != APR_SUCCESS) {
                /* Bad things happened. Everyone should have cleaned up. */
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r,