[Erp5-report] r35627 jm - in /erp5/trunk/products/ERP5Type: ./ patches/
nobody at svn.erp5.org
nobody at svn.erp5.org
Tue May 25 19:20:54 CEST 2010
Author: jm
Date: Tue May 25 19:20:51 2010
New Revision: 35627
URL: http://svn.erp5.org?rev=35627&view=rev
Log:
Zope 2.8: prevent invalidations from being processed in any order
This fix requires that I/O for ZEO storages are processed only the main thread.
Added:
erp5/trunk/products/ERP5Type/patches/ClientStorage.py
Modified:
erp5/trunk/products/ERP5Type/ZopePatch.py
Modified: erp5/trunk/products/ERP5Type/ZopePatch.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/ZopePatch.py?rev=35627&r1=35626&r2=35627&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/ZopePatch.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/ZopePatch.py [utf8] Tue May 25 19:20:51 2010
@@ -59,6 +59,7 @@
from Products.ERP5Type.patches import transforms
from Products.ERP5Type.patches import OFSPdata
from Products.ERP5Type.patches import make_hidden_input
+from Products.ERP5Type.patches import ClientStorage
from Products.ERP5Type.patches import DemoStorage
# BACK: Forward Compatibility with Zope 2.12 or CMF 2.2. Remove when we've
# dropped support for older versions.
Added: erp5/trunk/products/ERP5Type/patches/ClientStorage.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/patches/ClientStorage.py?rev=35627&view=auto
==============================================================================
--- erp5/trunk/products/ERP5Type/patches/ClientStorage.py (added)
+++ erp5/trunk/products/ERP5Type/patches/ClientStorage.py [utf8] Tue May 25 19:20:51 2010
@@ -1,0 +1,97 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# Copyright (c) 2010 Nexedi SARL and Contributors. All Rights Reserved.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+#
+##############################################################################
+
+# This is a backport of http://svn.zope.org/?rev=106514&view=rev for Zope 2.8.
+
+try:
+ from ThreadedAsync import LoopCallback
+
+except ImportError:
+ pass # nothing to do for recent Zope
+
+else:
+ # Switch Zope 2.8 to async I/O for ZEO client storages
+
+ import Lifetime
+ Lifetime_lifetime_loop = Lifetime.lifetime_loop
+
+ def lifetime_loop():
+ from asyncore import socket_map as map
+ LoopCallback._loop_lock.acquire()
+ try:
+ LoopCallback._looping = map
+ while LoopCallback._loop_callbacks:
+ cb, args, kw = LoopCallback._loop_callbacks.pop()
+ cb(map, *args, **(kw or {}))
+ finally:
+ LoopCallback._loop_lock.release()
+ return Lifetime_lifetime_loop()
+
+ Lifetime.lifetime_loop = lifetime_loop
+
+ # Prevent invalidations from being processed out of order
+
+ from ZEO.ClientStorage import ClientStorage
+
+ def tpc_finish(self, txn, f=None):
+ """Storage API: finish a transaction."""
+ if txn is not self._transaction:
+ return
+ self._load_lock.acquire()
+ try:
+ if self._midtxn_disconnect:
+ raise ClientDisconnected(
+ 'Calling tpc_finish() on a disconnected transaction')
+
+ # The calls to tpc_finish() and _update_cache() should
+ # never run currently with another thread, because the
+ # tpc_cond condition variable prevents more than one
+ # thread from calling tpc_finish() at a time.
+ # <patch/>
+ self._lock.acquire() # for atomic processing of invalidations
+ try:
+ tid = self._server.tpc_finish(id(txn)) # <patch/>
+ self._update_cache(tid)
+ if f is not None:
+ f(tid)
+ finally:
+ self._lock.release()
+
+ r = self._check_serials()
+ assert r is None or len(r) == 0, "unhandled serialnos: %s" % r
+ finally:
+ self._load_lock.release()
+ self.end_transaction()
+
+ ClientStorage.tpc_finish = tpc_finish
+
+ from ZODB.Connection import Connection
+
+ def invalidate(self, tid, oids):
+ """Notify the Connection that transaction 'tid' invalidated oids."""
+ self._inv_lock.acquire()
+ try:
+ if self._txn_time is None:
+ self._txn_time = tid
+ # <patch>
+ elif tid < self._txn_time:
+ raise AssertionError("invalidations out of order, %r < %r"
+ % (tid, self._txn_time))
+ # </patch>
+ self._invalidated.update(oids)
+ finally:
+ self._inv_lock.release()
+
+ Connection.invalidate = invalidate
More information about the Erp5-report
mailing list