[FASTCGI] libfcgi in multi threaded app
Rob
rclemley at booksys.com
Mon May 3 15:30:43 EDT 2010
The variables mentioned (FCGI_MPXS_CONNS, FCGI_MAX_REQS, and
FCGI_MAX_CONNS) are not referenced anywhere in either the libfcgi or the
apache2 mod_fastcgi libraries. They are set only in the code fragment
you included, but never referenced.
However in the introduction to the spec, we find this (emphasis mine):
After a FastCGI process accepts a connection on its listening
socket, the process executes a simple protocol to receive and send
data. The protocol serves two purposes. /*First, the protocol
multiplexes a single transport connection between several
independent FastCGI requests. This supports applications that are
able to **process concurrent requests using event-driven or
multi-threaded programming techniques. Second, within each request
the protocol provides several independent data streams in each
direction.*/ This way, for instance, both stdout and stderr data
pass over a single transport connection from the application to the
Web server, rather than requiring separate pipes as with CGI/1.1.
By using FCGX_Accept*_r*(), which keeps these streams separate, we're
able to simultaneously handle multiple FastCGI connections within one App.
Also, in Appendix B, example #4, we see:
4. Two instances of example 1, multiplexed onto a single connection.
The first request is more difficult than the second, so the
application finishes the requests out of order: [...]
I think the variables that we're discussing probably don't mean what you
think they mean.
Rob
On 05/03/2010 01:32 PM, Dave Bender wrote:
> Section 4.1 ( http://www.fastcgi.com/devkit/doc/fcgi-spec.html#SA )
> states:
>
> FCGI_MPXS_CONNS: "0" if this application does not multiplex
> connections (i.e. handle concurrent requests over each connection),
> "1" otherwise.
>
> Seeing as how the library is limited to 1 connection and 1 request,
>
> On Mon, May 3, 2010 at 2:27 PM, Rob <rclemley at booksys.com
> <mailto:rclemley at booksys.com>> wrote:
>
> I cannot really address your question because you're touching
> deeper into the internals of libfcgi and attempting to reconcile
> it with "the spec", without explicit references to which part of
> the spec. I just don't have time to do that much research right now.
>
> Section 4.1 ( http://www.fastcgi.com/devkit/doc/fcgi-spec.html#SA )
> states:
>
> FCGI_MPXS_CONNS: "0" if this application does not multiplex
> connections (i.e. handle concurrent requests over each connection),
> "1" otherwise.
>
> This would imply connections are handled one at a time.
>
> I would guess that you're missing some understanding of the
> complete flow of processing web requests, and how the requests are
> handled in the various nooks and crannies of FastCGI.
>
> Rob
>
>
>
> On 05/03/2010 12:22 PM, Dave Bender wrote:
>> I'm also curious, how does the library even accept multiple
>> requests simultaneously when the librar returns the following
>> values for its management records:
>>
>> if(strcmp(name, FCGI_MAX_CONNS) == 0) {
>> value = '1';
>> } else if(strcmp(name, FCGI_MAX_REQS) == 0) {
>> value = '1';
>> } else if(strcmp(name, FCGI_MPXS_CONNS) == 0) {
>> value = '0';
>> } else {
>> name = NULL;
>> }
>> (taken from fcgiapp.c, version 2.4.0)
>>
>> According to the spec, the web server should only be sending 1 at
>> a time.
>>
>> -Dave
>>
>> On Mon, May 3, 2010 at 1:14 PM, Martin Chapman
>> <chapmanm at pixia.com <mailto:chapmanm at pixia.com>> wrote:
>>
>> Rob,
>>
>> So how does this solution account for the fact that
>> FCGX_Accept_r () resets
>> the stdio global structure each time it's called? If you are
>> synchronizing
>> the code between each request, regardless of it's processed
>> on a separate
>> worker thread then only one request at a time is really being
>> executed.
>>
>> Martin
>>
>>
>> -----Original Message-----
>> From: fastcgi-developers-bounces+chapmanm=pixia.com
>> <http://pixia.com>@mailman.fastcgi.com
>> <http://mailman.fastcgi.com>
>> [mailto:fastcgi-developers-bounces+chapmanm
>> <mailto:fastcgi-developers-bounces%2Bchapmanm>=pixia.com
>> <http://pixia.com>@mailman.fastcgi.com
>> <http://mailman.fastcgi.com>]
>> On Behalf Of Rob
>> Sent: Monday, May 03, 2010 11:06 AM
>> To: fastcgi-developers at mailman.pins.net
>> <mailto:fastcgi-developers at mailman.pins.net>
>> Subject: Re: [FASTCGI] libfcgi in multi threaded app
>>
>> On 05/03/2010 10:27 AM, AlannY wrote:
>> > I've created a socket via FCGX_OpenSocket. Everything all
>> right.
>> >
>> > Then, I'm creating threads (5, for example). In each
>> thread, I'm
>> > creating a request with FCGX_InitRequest (with socket,
>> created early and
>> > FCGI_FAIL_ACCEPT_ON_INTR).
>> >
>> > Then the main loop starts. In this loop I'm calling
>> FCGX_Accept_r on
>> > this request. Here is trouble. Some of threads can
>> successfully accept,
>> > but some of then can't. Return code from FCGX_Accept is -9.
>>
>> The main thread loop should repeatedly call FCGX_Accept_r().
>> Requests
>> successfully accepted by FCGX_Accept_r() must then be passed
>> off to your
>> worker threads for processing. Therefore, you might choose to
>> dynamically allocate an fcgi request structure before calling
>> FCGX_Accept_r() and then pass the dynamically allocated request
>> structure to an available worker thread. The worker thread
>> would then
>> process the request and then deallocate the request.
>>
>> The multi-threaded problem is: "how to pass the requests to
>> the worker
>> threads?" Your program will be simple and graceful if you
>> choose the
>> means of a synchronized queue data structure. In a
>> synchronized queue
>> object, all of the thread synchronization is performed upon
>> access to
>> get or put items on the queue. The mutex guards access to
>> the internal
>> data. The conditions NotFull and NotEmpty signal the threads
>> to wake up
>> appropriately via the condition primitives: notify_one or
>> notify_all.
>> We use C++ and boost::threads to do something like this:
>>
>> pseudo code for main thread:
>>
>> synchronized_queue_class synchronized_queue #this is the
>> only
>> object that must be visible from all threads
>>
>> function get_fcgi_request( request )
>> request = allocate(sizeof request)
>> FCGX_init_request(request ...)
>> if FCGX_Accept_r(request) is successful
>> then return TRUE
>> else return FALSE
>> endif
>> endfunction
>>
>> while get_fcgi_request( request )
>> synchronized_queue.Put(request)
>> endwhile
>>
>> pseudo code for worker threads:
>>
>> while synchronized_queue.Get(request)
>> process(request)
>> deallocate(request)
>> endwhile
>>
>> pseudo code for synchronized_queue_class:
>>
>> class synchronized_queue_class:
>> queue internal_queue
>> condition notFull_condition
>> condition notEmpty_condition
>> mutex monitor
>>
>> procedure Put(item):
>> scoped_lock(monitor)
>> while internal_queue.full()
>> notFull_condition.wait(monitor)
>> internal_queue.put(item)
>> notEmpty_condition.notify_one()
>> endprocedure
>>
>> procedure Get(item):
>> scoped_lock(monitor)
>> while internal_queue.empty:
>> notEmpty_condition.wait(monitor)
>> internal_queue.push(item)
>> notFull_condtion.notify_one()
>> endprocedure
>>
>> endclass
>>
>> (There are other details in the synchronized queue which
>> should be
>> addressed, such as how to shut down the queue at the end of
>> the program
>> and tell the worker threads to exit.)
>>
>>
>>
>>
>>
>> _______________________________________________
>> FastCGI-developers mailing list
>> FastCGI-developers at mailman.fastcgi.com
>> <mailto:FastCGI-developers at mailman.fastcgi.com>
>> http://mailman.pins.net/mailman/listinfo.cgi/fastcgi-developers
>>
>> _______________________________________________
>> FastCGI-developers mailing list
>> FastCGI-developers at mailman.fastcgi.com
>> <mailto:FastCGI-developers at mailman.fastcgi.com>
>> http://mailman.pins.net/mailman/listinfo.cgi/fastcgi-developers
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.pins.net/mailman/private.cgi/fastcgi-developers/attachments/20100503/3ecbab82/attachment-0001.html>
More information about the FastCGI-developers
mailing list