1 |
|
2 import unittest |
|
3 import os |
|
4 import tempfile |
|
5 import signal |
|
6 import threading |
|
7 import time |
|
8 |
|
9 class testLogLock(unittest.TestCase): |
|
10 def test_ThreadingAndLocks(self): |
|
11 #create a thread, have that thread grab a lock, and sleep. |
|
12 fd, file = tempfile.mkstemp('.nonlog') |
|
13 _lock = threading.RLock() |
|
14 os.close(fd) |
|
15 def locker(): |
|
16 os.write(fd, 'Thread acquiring lock\n') |
|
17 _lock.acquire() |
|
18 os.write(fd, 'Thread acquired lock\n') |
|
19 time.sleep(0.4) |
|
20 os.write(fd, 'Thread releasing lock\n') |
|
21 _lock.release() |
|
22 os.write(fd, 'Thread released lock\n') |
|
23 |
|
24 #Then in the main thread, throw a signal to self |
|
25 def handleSignal(sigNum, frame): |
|
26 os.write(fd, 'Main Thread acquiring lock\n') |
|
27 lock = False |
|
28 endtime = time.time() + 1.0 |
|
29 while not lock: |
|
30 lock = _lock.acquire(blocking=0) |
|
31 time.sleep(0.01) |
|
32 if time.time() > endtime: |
|
33 break |
|
34 if not lock: |
|
35 os.write(fd, 'Main Thread could not acquire lock\n') |
|
36 return |
|
37 os.write(fd, 'Main Thread acquired lock\n') |
|
38 os.write(fd, 'Main Thread releasing lock\n') |
|
39 _lock.release() |
|
40 os.write(fd, 'Main Thread released lock\n') |
|
41 |
|
42 sighndlr = signal.signal(signal.SIGUSR1, handleSignal) |
|
43 try: |
|
44 fd = os.open(file, os.O_SYNC | os.O_WRONLY | os.O_CREAT) |
|
45 thread = threading.Thread(target=locker) |
|
46 thread.start() |
|
47 time.sleep(0.1) |
|
48 os.kill(os.getpid(), signal.SIGUSR1) |
|
49 thread.join() |
|
50 |
|
51 #check the results |
|
52 os.close(fd) |
|
53 fileconts = open(file, 'r').read() |
|
54 self.assertTrue('Main Thread released lock' in fileconts) |
|
55 self.assertEqual(fileconts, |
|
56 '''Thread acquiring lock |
|
57 Thread acquired lock |
|
58 Main Thread acquiring lock |
|
59 Thread releasing lock |
|
60 Thread released lock |
|
61 Main Thread acquired lock |
|
62 Main Thread releasing lock |
|
63 Main Thread released lock |
|
64 ''') |
|
65 |
|
66 #Now try after acquiring the lock from the main thread |
|
67 fd = os.open(file, os.O_SYNC | os.O_WRONLY | os.O_CREAT) |
|
68 _lock.acquire() |
|
69 thread = threading.Thread(target=locker) |
|
70 thread.start() |
|
71 time.sleep(0.1) |
|
72 os.kill(os.getpid(), signal.SIGUSR1) |
|
73 _lock.release() |
|
74 thread.join() |
|
75 os.close(fd) |
|
76 fileconts = open(file, 'r').read() |
|
77 self.assertEqual(fileconts, |
|
78 '''Thread acquiring lock |
|
79 Main Thread acquiring lock |
|
80 Main Thread acquired lock |
|
81 Main Thread releasing lock |
|
82 Main Thread released lock |
|
83 Thread acquired lock |
|
84 Thread releasing lock |
|
85 Thread released lock |
|
86 ''') |
|
87 |
|
88 finally: |
|
89 signal.signal(signal.SIGUSR1, sighndlr) |
|
90 try: |
|
91 os.close(fd) |
|
92 except OSError: |
|
93 pass |
|
94 try: |
|
95 os.unlink(file) |
|
96 except OSError: |
|
97 pass |
|
98 |
|