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() | ||
