Ticket #168: threadtest.py

File threadtest.py, 2.2 KB (added by Richard Boulton, 17 years ago)

Sample script demonstrating the failure

Line 
1
2import threading
3import xapian
4import time
5
6class context(object):
7 def __init__(self):
8 self.mutex = threading.Lock()
9 self.opencount = 0
10 self.threadcount = 0
11 self.logitems = []
12 self.failed = False
13
14 def get_threadnum(self):
15 self.threadcount += 1
16 return self.threadcount
17
18 def inccount(self):
19 self.mutex.acquire()
20 try:
21 self.opencount += 1
22 result = self.opencount
23 finally:
24 self.mutex.release()
25 return result
26
27 def deccount(self):
28 self.mutex.acquire()
29 try:
30 self.opencount -= 1
31 result = self.opencount
32 finally:
33 self.mutex.release()
34 return result
35
36 def log(self, msg):
37 self.logitems.append(msg)
38
39 def fail(self):
40 self.failed = True
41
42class test(threading.Thread):
43 def __init__(self, context, **kwargs):
44 threading.Thread.__init__(self, **kwargs)
45 self.context = context
46 self.threadnum = context.get_threadnum()
47
48 def run(self):
49 time.sleep(0.01)
50 self.context.log("opening %d" % self.threadnum)
51 try:
52 db = xapian.WritableDatabase('testdb', xapian.DB_CREATE_OR_OPEN)
53 except:
54 self.context.log("already open %d" % self.threadnum)
55 return
56
57 self.context.log("opened %d" % self.threadnum)
58 open = self.context.inccount()
59 if open != 1:
60 self.context.log("FAIL: simultanous open from thread %d" % self.threadnum)
61 self.context.fail()
62 raise RuntimeError("Opened %d databases simultaneously" % open)
63 time.sleep(0.01)
64 self.context.deccount() # Might be too soon, but we'll never overcount
65 self.context.log("closing %d" % self.threadnum)
66 del db
67 self.context.log("closed %d" % self.threadnum)
68
69def runtest():
70 c=context()
71 threads=[]
72 for num in xrange(10):
73 threads.append(test(c))
74
75 for thread in threads:
76 thread.start()
77
78 for thread in threads:
79 thread.join()
80
81 if c.failed:
82 print '\n'.join(c.logitems)
83 else:
84 print "passed"
85 return c.failed
86
87for i in xrange(100):
88 f = runtest()
89 if f:
90 break