# HG changeset patch # User Sylvain Thénault # Date 1304944510 -7200 # Node ID 9303fd71c2eeef7e83d87a149c8ec71db42d4322 # Parent dd5e49a5dcab793e4627ea4afa7de713c7542892 [session] lock self._closed and session.close to avoid race conditions diff -r dd5e49a5dcab -r 9303fd71c2ee server/session.py --- a/server/session.py Mon May 09 14:34:23 2011 +0200 +++ b/server/session.py Mon May 09 14:35:10 2011 +0200 @@ -182,6 +182,7 @@ self.__threaddata = threading.local() self._threads_in_transaction = set() self._closed = False + self._closed_lock = threading.Lock() def __unicode__(self): return '<%ssession %s (%s 0x%x)>' % ( @@ -618,21 +619,22 @@ def set_pool(self): """the session need a pool to execute some queries""" - if self._closed: - self.reset_pool(True) - raise Exception('try to set pool on a closed session') - if self.pool is None: - # get pool first to avoid race-condition - self._threaddata.pool = pool = self.repo._get_pool() - try: - pool.pool_set() - except: - self._threaddata.pool = None - self.repo._free_pool(pool) - raise - self._threads_in_transaction.add( - (threading.currentThread(), pool) ) - return self._threaddata.pool + with self._closed_lock: + if self._closed: + self.reset_pool(True) + raise Exception('try to set pool on a closed session') + if self.pool is None: + # get pool first to avoid race-condition + self._threaddata.pool = pool = self.repo._get_pool() + try: + pool.pool_set() + except: + self._threaddata.pool = None + self.repo._free_pool(pool) + raise + self._threads_in_transaction.add( + (threading.currentThread(), pool) ) + return self._threaddata.pool def _free_thread_pool(self, thread, pool, force_close=False): try: @@ -870,7 +872,8 @@ def close(self): """do not close pool on session close, since they are shared now""" - self._closed = True + with self._closed_lock: + self._closed = True # copy since _threads_in_transaction maybe modified while waiting for thread, pool in self._threads_in_transaction.copy(): if thread is threading.currentThread():