[FASTCGI] libfcgi in multi threaded app

Rob rclemley at booksys.com
Wed May 5 11:02:44 EDT 2010


  On 05/05/2010 08:51 AM, AlannY wrote:
> On 03/05/10 21:05, Rob wrote:
>>   On 05/03/2010 10:27 AM, AlannY wrote:
>> 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
> I've done my research. And also, I've done my program with your method
> from your pseudo-code (nice code).
>
> Seems, that everything works and I can handle requests in parallel.
>
> Several new problems arrived: how to shutdown FCGI socket? My program
> want to restart all threads, close connection, open new, create new
> threads. But It's not possible to create socket again, because of
> "Address already in use" error. I'll continue investigation.

I'm not quite clear on the flow of your program from that description.  
I don't understand the how and why and the details of "restart all 
threads, close connection, open new, create new threads."

One possibility omitted from the pseudo-code would be to call 
FCGX_Finish_r() in worker threads before de-allocation.  Also in the 
"function get_fcgi_request()", the request should be deallocated if the 
FCGX_Accept_r() failed.  Another error in the pseudo-code is that the 
"Get" procedure "pushes" the item instead of "popping."

Some functionality is not in the pseudo code, such as how to startup and 
shutdown the worker threads.  The pseudo-code is inconsistent: the 
synchronized queue "Get" procedure doesn't return a value, yet the 
worker thread loop tests "Get()" for true.   This is a hint that the 
synchronized queue can have control methods and instance variables added 
so that the queue can be shutdown and can return false from "Get" to 
cause the worker threads to exit.

Another problem is to detect shutdown conditions.   We use signal 
handlers which detect shutdown events from the OS and set global 
variables.   Before calling FCGX_Accept_r(), there's a loop which calls 
select() to test when data is available on the listen socket.  The loop 
wakes up every second to check for shutdown events from the OS.   If a 
shutdown event is detected, then the synchronized queue can be told to 
shutdown, returning false from the "Get" functions and causing the 
worker threads to exit.

-- 
Rob



More information about the FastCGI-developers mailing list