Thread-blocking (was: socket.gethostbyname() thread-safe?)

Michael Ströder michael at stroeder.com
Tue Apr 10 22:34:28 EDT 2001


Aahz Maruch wrote:
> 
> >I used a lock around it but that didn't solve the problem.
> 
> What problem(s) are you having?

Hmm, hard to say. I have to tell the long story.

I'm using the C extension module python-ldap. For enabling my
application (HTTP-LDAP gateway web2ldap) to have persistent LDAP
connection objects I'm using threads now to serve the HTTP requests.
As a stand-alone server this is done by using the threading mix-in
class from SocketServer module (another code snippet using fcgi
module under mod_fastcgi below).

class MyThreadingHTTPServer(
  SocketServer.ThreadingMixIn,
  MyHTTPServer
)

The whole HTTP serving stuff seems to work just fine. But the
underlying LDAP libs (OpenLDAP 1.2.x in my case) are known not to be
thread-safe. Therefore I'm using locks to protect calls into
python-ldap methods. My problem is that sometimes the whole thing
blocks. Mainly if the ldap.open() call (creating a new connection)
does not return or the client aborts the connection.

Hmm, I guess it's hard to describe and I think it's difficult to
really track it down.

Two questions:
- Does the python-ldap module also has to set the global interpreter
lock as mentioned in the API docs (api/threads.html)?
- What is a good practice of exception handling to avoid blocking?
Should I catch all exceptions to avoid that the thread won't call
properly thread.exit(). Is this already done by
SocketServer.ThreadingMixIn?

Ciao, Michael (confused and tired...)

-----------------------------------------------------------------------
import w2lhandler

import fcgi,thread

class ThreadedFastCGIServer:

  def __init__(self):
    self.handles  = {}
    return

  def run(self):
    """create a new thread to handle requests"""
    while fcgi.isFCGI():
      req = fcgi.FCGI()
      thread.start_new_thread(self.handler,(req,0))
    return

  def handler(self,*args):
    req = args[0]
    try:
      w2lhandler.HandleHTTPRequest(req.inp,req.out,req.err,req.env)
    except:
      # Avoid blocking 
      pass
    req.Finish()
    thread.exit()

fcgiServer = ThreadedFastCGIServer()
fcgiServer.run()



More information about the Python-list mailing list