diff options
-rwxr-xr-x | bitbake/bin/bitbake-worker | 9 | ||||
-rw-r--r-- | bitbake/lib/bb/cooker.py | 4 | ||||
-rw-r--r-- | bitbake/lib/bb/event.py | 6 | ||||
-rw-r--r-- | bitbake/lib/bb/server/process.py | 16 | ||||
-rw-r--r-- | bitbake/lib/bb/ui/uievent.py | 28 | ||||
-rw-r--r-- | bitbake/lib/bb/utils.py | 13 |
6 files changed, 40 insertions, 36 deletions
diff --git a/bitbake/bin/bitbake-worker b/bitbake/bin/bitbake-worker index ed266f0ac2..a3ea5d9618 100755 --- a/bitbake/bin/bitbake-worker +++ b/bitbake/bin/bitbake-worker | |||
@@ -121,11 +121,10 @@ def worker_child_fire(event, d): | |||
121 | 121 | ||
122 | data = b"<event>" + pickle.dumps(event) + b"</event>" | 122 | data = b"<event>" + pickle.dumps(event) + b"</event>" |
123 | try: | 123 | try: |
124 | worker_pipe_lock.acquire() | 124 | with bb.utils.lock_timeout(worker_pipe_lock): |
125 | while(len(data)): | 125 | while(len(data)): |
126 | written = worker_pipe.write(data) | 126 | written = worker_pipe.write(data) |
127 | data = data[written:] | 127 | data = data[written:] |
128 | worker_pipe_lock.release() | ||
129 | except IOError: | 128 | except IOError: |
130 | sigterm_handler(None, None) | 129 | sigterm_handler(None, None) |
131 | raise | 130 | raise |
diff --git a/bitbake/lib/bb/cooker.py b/bitbake/lib/bb/cooker.py index a5a635858c..738849d189 100644 --- a/bitbake/lib/bb/cooker.py +++ b/bitbake/lib/bb/cooker.py | |||
@@ -251,14 +251,14 @@ class BBCooker: | |||
251 | self.notifier = pyinotify.Notifier(self.watcher, self.notifications) | 251 | self.notifier = pyinotify.Notifier(self.watcher, self.notifications) |
252 | 252 | ||
253 | def process_inotify_updates(self): | 253 | def process_inotify_updates(self): |
254 | with self.inotify_threadlock: | 254 | with bb.utils.lock_timeout(self.inotify_threadlock): |
255 | for n in [self.confignotifier, self.notifier]: | 255 | for n in [self.confignotifier, self.notifier]: |
256 | if n and n.check_events(timeout=0): | 256 | if n and n.check_events(timeout=0): |
257 | # read notified events and enqueue them | 257 | # read notified events and enqueue them |
258 | n.read_events() | 258 | n.read_events() |
259 | 259 | ||
260 | def process_inotify_updates_apply(self): | 260 | def process_inotify_updates_apply(self): |
261 | with self.inotify_threadlock: | 261 | with bb.utils.lock_timeout(self.inotify_threadlock): |
262 | for n in [self.confignotifier, self.notifier]: | 262 | for n in [self.confignotifier, self.notifier]: |
263 | if n and n.check_events(timeout=0): | 263 | if n and n.check_events(timeout=0): |
264 | n.read_events() | 264 | n.read_events() |
diff --git a/bitbake/lib/bb/event.py b/bitbake/lib/bb/event.py index 7826541a64..8b05f93e2f 100644 --- a/bitbake/lib/bb/event.py +++ b/bitbake/lib/bb/event.py | |||
@@ -184,7 +184,7 @@ def fire_ui_handlers(event, d): | |||
184 | ui_queue.append(event) | 184 | ui_queue.append(event) |
185 | return | 185 | return |
186 | 186 | ||
187 | with _thread_lock: | 187 | with bb.utils.lock_timeout(_thread_lock): |
188 | errors = [] | 188 | errors = [] |
189 | for h in _ui_handlers: | 189 | for h in _ui_handlers: |
190 | #print "Sending event %s" % event | 190 | #print "Sending event %s" % event |
@@ -315,7 +315,7 @@ def set_eventfilter(func): | |||
315 | _eventfilter = func | 315 | _eventfilter = func |
316 | 316 | ||
317 | def register_UIHhandler(handler, mainui=False): | 317 | def register_UIHhandler(handler, mainui=False): |
318 | with _thread_lock: | 318 | with bb.utils.lock_timeout(_thread_lock): |
319 | bb.event._ui_handler_seq = bb.event._ui_handler_seq + 1 | 319 | bb.event._ui_handler_seq = bb.event._ui_handler_seq + 1 |
320 | _ui_handlers[_ui_handler_seq] = handler | 320 | _ui_handlers[_ui_handler_seq] = handler |
321 | level, debug_domains = bb.msg.constructLogOptions() | 321 | level, debug_domains = bb.msg.constructLogOptions() |
@@ -329,7 +329,7 @@ def unregister_UIHhandler(handlerNum, mainui=False): | |||
329 | if mainui: | 329 | if mainui: |
330 | global _uiready | 330 | global _uiready |
331 | _uiready = False | 331 | _uiready = False |
332 | with _thread_lock: | 332 | with bb.utils.lock_timeout(_thread_lock): |
333 | if handlerNum in _ui_handlers: | 333 | if handlerNum in _ui_handlers: |
334 | del _ui_handlers[handlerNum] | 334 | del _ui_handlers[handlerNum] |
335 | return | 335 | return |
diff --git a/bitbake/lib/bb/server/process.py b/bitbake/lib/bb/server/process.py index ac7749d36c..b5f6faf6fb 100644 --- a/bitbake/lib/bb/server/process.py +++ b/bitbake/lib/bb/server/process.py | |||
@@ -113,7 +113,7 @@ class ProcessServer(): | |||
113 | def register_idle_function(self, function, data): | 113 | def register_idle_function(self, function, data): |
114 | """Register a function to be called while the server is idle""" | 114 | """Register a function to be called while the server is idle""" |
115 | assert hasattr(function, '__call__') | 115 | assert hasattr(function, '__call__') |
116 | with self._idlefuncsLock: | 116 | with bb.utils.lock_timeout(self._idlefuncsLock): |
117 | self._idlefuns[function] = data | 117 | self._idlefuns[function] = data |
118 | serverlog("Registering idle function %s" % str(function)) | 118 | serverlog("Registering idle function %s" % str(function)) |
119 | 119 | ||
@@ -379,7 +379,7 @@ class ProcessServer(): | |||
379 | 379 | ||
380 | def idle_thread(self): | 380 | def idle_thread(self): |
381 | def remove_idle_func(function): | 381 | def remove_idle_func(function): |
382 | with self._idlefuncsLock: | 382 | with bb.utils.lock_timeout(self._idlefuncsLock): |
383 | del self._idlefuns[function] | 383 | del self._idlefuns[function] |
384 | self.idle_cond.notify_all() | 384 | self.idle_cond.notify_all() |
385 | 385 | ||
@@ -387,7 +387,7 @@ class ProcessServer(): | |||
387 | nextsleep = 0.1 | 387 | nextsleep = 0.1 |
388 | fds = [] | 388 | fds = [] |
389 | 389 | ||
390 | with self._idlefuncsLock: | 390 | with bb.utils.lock_timeout(self._idlefuncsLock): |
391 | items = list(self._idlefuns.items()) | 391 | items = list(self._idlefuns.items()) |
392 | 392 | ||
393 | for function, data in items: | 393 | for function, data in items: |
@@ -743,7 +743,7 @@ class BBUIEventQueue: | |||
743 | self.t.start() | 743 | self.t.start() |
744 | 744 | ||
745 | def getEvent(self): | 745 | def getEvent(self): |
746 | with self.eventQueueLock: | 746 | with bb.utils.lock_timeout(self.eventQueueLock): |
747 | if len(self.eventQueue) == 0: | 747 | if len(self.eventQueue) == 0: |
748 | return None | 748 | return None |
749 | 749 | ||
@@ -758,7 +758,7 @@ class BBUIEventQueue: | |||
758 | return self.getEvent() | 758 | return self.getEvent() |
759 | 759 | ||
760 | def queue_event(self, event): | 760 | def queue_event(self, event): |
761 | with self.eventQueueLock: | 761 | with bb.utils.lock_timeout(self.eventQueueLock): |
762 | self.eventQueue.append(event) | 762 | self.eventQueue.append(event) |
763 | self.eventQueueNotify.set() | 763 | self.eventQueueNotify.set() |
764 | 764 | ||
@@ -794,7 +794,7 @@ class ConnectionReader(object): | |||
794 | return self.reader.poll(timeout) | 794 | return self.reader.poll(timeout) |
795 | 795 | ||
796 | def get(self): | 796 | def get(self): |
797 | with self.rlock: | 797 | with bb.utils.lock_timeout(self.rlock): |
798 | res = self.reader.recv_bytes() | 798 | res = self.reader.recv_bytes() |
799 | return multiprocessing.reduction.ForkingPickler.loads(res) | 799 | return multiprocessing.reduction.ForkingPickler.loads(res) |
800 | 800 | ||
@@ -815,7 +815,7 @@ class ConnectionWriter(object): | |||
815 | 815 | ||
816 | def _send(self, obj): | 816 | def _send(self, obj): |
817 | gc.disable() | 817 | gc.disable() |
818 | with self.wlock: | 818 | with bb.utils.lock_timeout(self.wlock): |
819 | self.writer.send_bytes(obj) | 819 | self.writer.send_bytes(obj) |
820 | gc.enable() | 820 | gc.enable() |
821 | 821 | ||
@@ -828,7 +828,7 @@ class ConnectionWriter(object): | |||
828 | # pthread_sigmask block/unblock would be nice but doesn't work, https://bugs.python.org/issue47139 | 828 | # pthread_sigmask block/unblock would be nice but doesn't work, https://bugs.python.org/issue47139 |
829 | process = multiprocessing.current_process() | 829 | process = multiprocessing.current_process() |
830 | if process and hasattr(process, "queue_signals"): | 830 | if process and hasattr(process, "queue_signals"): |
831 | with process.signal_threadlock: | 831 | with bb.utils.lock_timeout(process.signal_threadlock): |
832 | process.queue_signals = True | 832 | process.queue_signals = True |
833 | self._send(obj) | 833 | self._send(obj) |
834 | process.queue_signals = False | 834 | process.queue_signals = False |
diff --git a/bitbake/lib/bb/ui/uievent.py b/bitbake/lib/bb/ui/uievent.py index d595f172ac..adbe698939 100644 --- a/bitbake/lib/bb/ui/uievent.py +++ b/bitbake/lib/bb/ui/uievent.py | |||
@@ -70,30 +70,22 @@ class BBUIEventQueue: | |||
70 | self.t.start() | 70 | self.t.start() |
71 | 71 | ||
72 | def getEvent(self): | 72 | def getEvent(self): |
73 | 73 | with bb.utils.lock_timeout(self.eventQueueLock): | |
74 | self.eventQueueLock.acquire() | 74 | if not self.eventQueue: |
75 | 75 | return None | |
76 | if not self.eventQueue: | 76 | item = self.eventQueue.pop(0) |
77 | self.eventQueueLock.release() | 77 | if not self.eventQueue: |
78 | return None | 78 | self.eventQueueNotify.clear() |
79 | 79 | return item | |
80 | item = self.eventQueue.pop(0) | ||
81 | |||
82 | if not self.eventQueue: | ||
83 | self.eventQueueNotify.clear() | ||
84 | |||
85 | self.eventQueueLock.release() | ||
86 | return item | ||
87 | 80 | ||
88 | def waitEvent(self, delay): | 81 | def waitEvent(self, delay): |
89 | self.eventQueueNotify.wait(delay) | 82 | self.eventQueueNotify.wait(delay) |
90 | return self.getEvent() | 83 | return self.getEvent() |
91 | 84 | ||
92 | def queue_event(self, event): | 85 | def queue_event(self, event): |
93 | self.eventQueueLock.acquire() | 86 | with bb.utils.lock_timeout(self.eventQueueLock): |
94 | self.eventQueue.append(event) | 87 | self.eventQueue.append(event) |
95 | self.eventQueueNotify.set() | 88 | self.eventQueueNotify.set() |
96 | self.eventQueueLock.release() | ||
97 | 89 | ||
98 | def send_event(self, event): | 90 | def send_event(self, event): |
99 | self.queue_event(pickle.loads(event)) | 91 | self.queue_event(pickle.loads(event)) |
diff --git a/bitbake/lib/bb/utils.py b/bitbake/lib/bb/utils.py index 0df522b372..8c79159573 100644 --- a/bitbake/lib/bb/utils.py +++ b/bitbake/lib/bb/utils.py | |||
@@ -1841,3 +1841,16 @@ def mkstemp(suffix=None, prefix=None, dir=None, text=False): | |||
1841 | else: | 1841 | else: |
1842 | prefix = tempfile.gettempprefix() + entropy | 1842 | prefix = tempfile.gettempprefix() + entropy |
1843 | return tempfile.mkstemp(suffix=suffix, prefix=prefix, dir=dir, text=text) | 1843 | return tempfile.mkstemp(suffix=suffix, prefix=prefix, dir=dir, text=text) |
1844 | |||
1845 | # If we don't have a timeout of some kind and a process/thread exits badly (for example | ||
1846 | # OOM killed) and held a lock, we'd just hang in the lock futex forever. It is better | ||
1847 | # we exit at some point than hang. 5 minutes with no progress means we're probably deadlocked. | ||
1848 | @contextmanager | ||
1849 | def lock_timeout(lock): | ||
1850 | held = lock.acquire(timeout=5*60) | ||
1851 | try: | ||
1852 | if not held: | ||
1853 | os._exit(1) | ||
1854 | yield held | ||
1855 | finally: | ||
1856 | lock.release() | ||