Threads and socket.setdefaulttimeout

Russell Warren russandheather at gmail.com
Wed Oct 12 14:33:25 EDT 2005


It appears that the timeout setting is contained within a process
(thanks for the confirmation), but I've realized that the function
doesn't play friendly with threads.  If I have multiple threads using
sockets and one (or more) is using timeouts, one thread affects the
other and you get unpredictable behavior sometimes.  I included a short
script at the end of this that demonstrates the threading problem.

I'm trying to get around this by forcing all locations that want to set
a timeout to use a 'safe' call immediately prior to socket creation
that locks out setting the timeout again until the lock is released.
Something like this:

try:
  SafeSetSocketTimeout(Timeout_s)
  #lock currently acquired to prevent other threads sneaking in here
  CreateSocket()
finally:
  ReleaseSocketTimeoutSettingLock()
UseSocket()

However - this is getting increasingly painful because I don't have
easy access to all of the socket creations where I'd like to do this.
The biggest pain right now is that I'm using xmlrpclib which has some
seriously/frustratingly heavy use of __ prefixes that makes getting
inside to do this at socket creation near impossible (at least I think
so).  Right now the best I can do is surround the xmlrpclib calls with
this (effectively putting the lock release after the UseSocket), but
then other threads get hung up for the duration of the call or timeout,
rather than just the simple socket creation.

It would be nice if the timeout were implemented as an argument in the
socket constructor rather than having this global method.  Is there a
reason for this?  I tried sifting through the cvs source and got lost -
couldn't even find the call definition for socket(family, type, proto)
and gave up...

Does anybody have any idea of another way to do what I need (indpendent
socket timeouts per thread), or have suggestions on how to break into
xmlrpclib (actually down into httplib) to do the methdo I was trying?

Related question: Is there some global way that I'm unaware of to make
it so that some few lines of code are atomic/uninterruptable and no
other thread can sneak in between?

All suggestions appreciated!  Hopefully I'm just missing something
obvious.

Russ

#--- This script confirms that settimeout's affect is across threads
import threading, xmlrpclib, socket

def st():
  socket.setdefaulttimeout(0.1)

try:
  proxy = xmlrpclib.ServerProxy("http://localhost:10000")
  print proxy.NonExistentCallThatShouldTimeout()
except Exception, E:  print "Exception caught: %s" % (E,)

cbThread = threading.Thread(target = st)
cbThread.start()

try:
  print proxy.NonExistentCallThatShouldTimeout()
except Exception, E:  print "Exception caught: %s" % (E,)

#Output is:
#Exception caught: (10061, 'Connection refused')
#Exception caught: timed out




More information about the Python-list mailing list