[Zope-dev] thread safety in external methods

Robin Becker robin@jessikat.demon.co.uk
Thu, 2 Sep 1999 20:14:41 +0100


In article <37CE7664.395D31F5@digicool.com>, Jim Fulton
<jim@digicool.com> writes
>Robin Becker wrote:
>> 
>> How do I do thread safety inside an External method.
>> 
>
...
>e).
>> 
>> It would be sufficient for my purposes if I could guarantee to get certain 
>code run just once
>> at startup time.
>
>Is this actually necessary?  Is it cirtical that only one ZGA_calculator
>gets created?  If not, you don't really have a thread-safety problem
>here. If it is, then you could protect the section above with a lock:
>
> import thread
> zgalock=tread.allocate_lock()
> def __ZGA():
>     zgaloc.acquire()
>     try:
>       if not hasattr(sys.modules['__main__'],'__ZGA'):
>           #unsafe here...
>           Z=ZGA_calculator()
>           # initialise things to do with Z
>           sys.modules['__main__'].__dict__['__ZGA']=Z
>       return sys.modules['__main__'].__dict__['__ZGA']
>     finally: zgaloc.release()
> 
>> Do I have to make a product or is there some easier way to do this.
>
>I think that a product would be easier. With a product, you could
>simply put the above code in the product __init__ module.
>
>BTW, why do you want to hack __main__?
>
>Jim
>

I do indeed need only a single calculator. My process is so big that I
can afford only one running at a time. I therefore implement queuing etc
via the singleton.

My original reply to Michel shows that doing as you suggest in the
external method isn't sufficient. If two calls hit the method together
then two locks may be created simultaneously and then the lock doesn't
work. It seems that each invocation of an external method gets a private
global space.

I have to move the lock into an imported file to get a lock to work. And
in fact you're right as soon as I have the imported file I can keep
__ZGA there and not in __main__.
-- 
Robin Becker