Skip to content

Commit 765311b

Browse files
author
Richard Jones
committed
[SF#571170] gdbm deadlock
1 parent c4f8ddd commit 765311b

File tree

3 files changed

+90
-66
lines changed

3 files changed

+90
-66
lines changed

CHANGES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Fixed:
66
. #576086 ] dumb copying mistake (frontends/ZRoundup.py)
77
. installation instructions now mention "python2" in "testing your python".
88
. bsddb3 backend should use 'c' for create, not 'n' for nuke
9+
. #571170 ] gdbm deadlock
910

1011

1112
2002-06-24 0.4.2

roundup/backends/back_anydbm.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
#$Id: back_anydbm.py,v 1.37 2002-06-20 23:52:35 richard Exp $
18+
#$Id: back_anydbm.py,v 1.37.2.1 2002-07-10 06:30:47 richard Exp $
1919
'''
2020
This module defines a backend that saves the hyperdatabase in a database
2121
chosen by anydbm. It is guaranteed to always be available in python
@@ -338,7 +338,9 @@ def getjournal(self, classname, nodeid):
338338
try:
339339
journal = marshal.loads(db[nodeid])
340340
except KeyError:
341+
db.close()
341342
raise KeyError, 'no such %s %s'%(classname, nodeid)
343+
db.close()
342344
res = []
343345
for entry in journal:
344346
(nodeid, date_stamp, user, action, params) = entry
@@ -486,6 +488,9 @@ def rollback(self):
486488

487489
#
488490
#$Log: not supported by cvs2svn $
491+
#Revision 1.37 2002/06/20 23:52:35 richard
492+
#More informative error message
493+
#
489494
#Revision 1.36 2002/06/19 03:07:19 richard
490495
#Moved the file storage commit into blobfiles where it belongs.
491496
#

roundup/hyperdb.py

Lines changed: 83 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
# $Id: hyperdb.py,v 1.69 2002-06-17 23:15:29 richard Exp $
18+
# $Id: hyperdb.py,v 1.69.2.1 2002-07-10 06:30:47 richard Exp $
1919

2020
__doc__ = """
2121
Hyperdatabase implementation, especially field types.
@@ -769,12 +769,15 @@ def lookup(self, keyvalue):
769769
otherwise a KeyError is raised.
770770
"""
771771
cldb = self.db.getclassdb(self.classname)
772-
for nodeid in self.db.getnodeids(self.classname, cldb):
773-
node = self.db.getnode(self.classname, nodeid, cldb)
774-
if node.has_key(self.db.RETIRED_FLAG):
775-
continue
776-
if node[self.key] == keyvalue:
777-
return nodeid
772+
try:
773+
for nodeid in self.db.getnodeids(self.classname, cldb):
774+
node = self.db.getnode(self.classname, nodeid, cldb)
775+
if node.has_key(self.db.RETIRED_FLAG):
776+
continue
777+
if node[self.key] == keyvalue:
778+
return nodeid
779+
finally:
780+
cldb.close()
778781
raise KeyError, keyvalue
779782

780783
# XXX: change from spec - allows multiple props to match
@@ -801,20 +804,23 @@ def find(self, **propspec):
801804
# ok, now do the find
802805
cldb = self.db.getclassdb(self.classname)
803806
l = []
804-
for id in self.db.getnodeids(self.classname, db=cldb):
805-
node = self.db.getnode(self.classname, id, db=cldb)
806-
if node.has_key(self.db.RETIRED_FLAG):
807-
continue
808-
for propname, nodeid in propspec:
809-
# can't test if the node doesn't have this property
810-
if not node.has_key(propname):
807+
try:
808+
for id in self.db.getnodeids(self.classname, db=cldb):
809+
node = self.db.getnode(self.classname, id, db=cldb)
810+
if node.has_key(self.db.RETIRED_FLAG):
811811
continue
812-
prop = self.properties[propname]
813-
property = node[propname]
814-
if isinstance(prop, Link) and nodeid == property:
815-
l.append(id)
816-
elif isinstance(prop, Multilink) and nodeid in property:
817-
l.append(id)
812+
for propname, nodeid in propspec:
813+
# can't test if the node doesn't have this property
814+
if not node.has_key(propname):
815+
continue
816+
prop = self.properties[propname]
817+
property = node[propname]
818+
if isinstance(prop, Link) and nodeid == property:
819+
l.append(id)
820+
elif isinstance(prop, Multilink) and nodeid in property:
821+
l.append(id)
822+
finally:
823+
cldb.close()
818824
return l
819825

820826
def stringFind(self, **requirements):
@@ -832,27 +838,33 @@ def stringFind(self, **requirements):
832838
requirements[propname] = requirements[propname].lower()
833839
l = []
834840
cldb = self.db.getclassdb(self.classname)
835-
for nodeid in self.db.getnodeids(self.classname, cldb):
836-
node = self.db.getnode(self.classname, nodeid, cldb)
837-
if node.has_key(self.db.RETIRED_FLAG):
838-
continue
839-
for key, value in requirements.items():
840-
if node[key] and node[key].lower() != value:
841-
break
842-
else:
843-
l.append(nodeid)
841+
try:
842+
for nodeid in self.db.getnodeids(self.classname, cldb):
843+
node = self.db.getnode(self.classname, nodeid, cldb)
844+
if node.has_key(self.db.RETIRED_FLAG):
845+
continue
846+
for key, value in requirements.items():
847+
if node[key] and node[key].lower() != value:
848+
break
849+
else:
850+
l.append(nodeid)
851+
finally:
852+
cldb.close()
844853
return l
845854

846855
def list(self):
847856
"""Return a list of the ids of the active nodes in this class."""
848857
l = []
849858
cn = self.classname
850859
cldb = self.db.getclassdb(cn)
851-
for nodeid in self.db.getnodeids(cn, cldb):
852-
node = self.db.getnode(cn, nodeid, cldb)
853-
if node.has_key(self.db.RETIRED_FLAG):
854-
continue
855-
l.append(nodeid)
860+
try:
861+
for nodeid in self.db.getnodeids(cn, cldb):
862+
node = self.db.getnode(cn, nodeid, cldb)
863+
if node.has_key(self.db.RETIRED_FLAG):
864+
continue
865+
l.append(nodeid)
866+
finally:
867+
cldb.close()
856868
l.sort()
857869
return l
858870

@@ -915,37 +927,40 @@ def filter(self, search_matches, filterspec, sort, group,
915927
# now, find all the nodes that are active and pass filtering
916928
l = []
917929
cldb = self.db.getclassdb(cn)
918-
for nodeid in self.db.getnodeids(cn, cldb):
919-
node = self.db.getnode(cn, nodeid, cldb)
920-
if node.has_key(self.db.RETIRED_FLAG):
921-
continue
922-
# apply filter
923-
for t, k, v in filterspec:
924-
# this node doesn't have this property, so reject it
925-
if not node.has_key(k): break
926-
927-
if t == 0 and node[k] not in v:
928-
# link - if this node'd property doesn't appear in the
929-
# filterspec's nodeid list, skip it
930-
break
931-
elif t == 1:
932-
# multilink - if any of the nodeids required by the
933-
# filterspec aren't in this node's property, then skip
934-
# it
935-
for value in v:
936-
if value not in node[k]:
937-
break
938-
else:
939-
continue
940-
break
941-
elif t == 2 and (node[k] is None or not v.search(node[k])):
942-
# RE search
943-
break
944-
elif t == 6 and node[k] != v:
945-
# straight value comparison for the other types
946-
break
947-
else:
948-
l.append((nodeid, node))
930+
try:
931+
for nodeid in self.db.getnodeids(cn, cldb):
932+
node = self.db.getnode(cn, nodeid, cldb)
933+
if node.has_key(self.db.RETIRED_FLAG):
934+
continue
935+
# apply filter
936+
for t, k, v in filterspec:
937+
# this node doesn't have this property, so reject it
938+
if not node.has_key(k): break
939+
940+
if t == 0 and node[k] not in v:
941+
# link - if this node'd property doesn't appear in the
942+
# filterspec's nodeid list, skip it
943+
break
944+
elif t == 1:
945+
# multilink - if any of the nodeids required by the
946+
# filterspec aren't in this node's property, then skip
947+
# it
948+
for value in v:
949+
if value not in node[k]:
950+
break
951+
else:
952+
continue
953+
break
954+
elif t == 2 and (node[k] is None or not v.search(node[k])):
955+
# RE search
956+
break
957+
elif t == 6 and node[k] != v:
958+
# straight value comparison for the other types
959+
break
960+
else:
961+
l.append((nodeid, node))
962+
finally:
963+
cldb.close()
949964
l.sort()
950965

951966
# filter based on full text search
@@ -1169,6 +1184,9 @@ def Choice(name, db, *options):
11691184

11701185
#
11711186
# $Log: not supported by cvs2svn $
1187+
# Revision 1.69 2002/06/17 23:15:29 richard
1188+
# Can debug to stdout now
1189+
#
11721190
# Revision 1.68 2002/06/11 06:52:03 richard
11731191
# . #564271 ] find() and new properties
11741192
#

0 commit comments

Comments
 (0)