diff options
| -rw-r--r-- | bitbake/lib/bb/event.py | 10 | ||||
| -rw-r--r-- | bitbake/lib/bb/utils.py | 15 |
2 files changed, 24 insertions, 1 deletions
diff --git a/bitbake/lib/bb/event.py b/bitbake/lib/bb/event.py index 952c85c0bd..a12adbc937 100644 --- a/bitbake/lib/bb/event.py +++ b/bitbake/lib/bb/event.py | |||
| @@ -194,7 +194,12 @@ def fire_ui_handlers(event, d): | |||
| 194 | ui_queue.append(event) | 194 | ui_queue.append(event) |
| 195 | return | 195 | return |
| 196 | 196 | ||
| 197 | with bb.utils.lock_timeout(_thread_lock): | 197 | with bb.utils.lock_timeout_nocheck(_thread_lock) as lock: |
| 198 | if not lock: | ||
| 199 | # If we can't get the lock, we may be recursively called, queue and return | ||
| 200 | ui_queue.append(event) | ||
| 201 | return | ||
| 202 | |||
| 198 | errors = [] | 203 | errors = [] |
| 199 | for h in _ui_handlers: | 204 | for h in _ui_handlers: |
| 200 | #print "Sending event %s" % event | 205 | #print "Sending event %s" % event |
| @@ -213,6 +218,9 @@ def fire_ui_handlers(event, d): | |||
| 213 | for h in errors: | 218 | for h in errors: |
| 214 | del _ui_handlers[h] | 219 | del _ui_handlers[h] |
| 215 | 220 | ||
| 221 | while ui_queue: | ||
| 222 | fire_ui_handlers(ui_queue.pop(), d) | ||
| 223 | |||
| 216 | def fire(event, d): | 224 | def fire(event, d): |
| 217 | """Fire off an Event""" | 225 | """Fire off an Event""" |
| 218 | 226 | ||
diff --git a/bitbake/lib/bb/utils.py b/bitbake/lib/bb/utils.py index da026fe5bf..67e22f4389 100644 --- a/bitbake/lib/bb/utils.py +++ b/bitbake/lib/bb/utils.py | |||
| @@ -1857,6 +1857,9 @@ def path_is_descendant(descendant, ancestor): | |||
| 1857 | # If we don't have a timeout of some kind and a process/thread exits badly (for example | 1857 | # If we don't have a timeout of some kind and a process/thread exits badly (for example |
| 1858 | # OOM killed) and held a lock, we'd just hang in the lock futex forever. It is better | 1858 | # OOM killed) and held a lock, we'd just hang in the lock futex forever. It is better |
| 1859 | # we exit at some point than hang. 5 minutes with no progress means we're probably deadlocked. | 1859 | # we exit at some point than hang. 5 minutes with no progress means we're probably deadlocked. |
| 1860 | # This function can still deadlock python since it can't signal the other threads to exit | ||
| 1861 | # (signals are handled in the main thread) and even os._exit() will wait on non-daemon threads | ||
| 1862 | # to exit. | ||
| 1860 | @contextmanager | 1863 | @contextmanager |
| 1861 | def lock_timeout(lock): | 1864 | def lock_timeout(lock): |
| 1862 | try: | 1865 | try: |
| @@ -1869,3 +1872,15 @@ def lock_timeout(lock): | |||
| 1869 | finally: | 1872 | finally: |
| 1870 | lock.release() | 1873 | lock.release() |
| 1871 | signal.pthread_sigmask(signal.SIG_SETMASK, s) | 1874 | signal.pthread_sigmask(signal.SIG_SETMASK, s) |
| 1875 | |||
| 1876 | # A version of lock_timeout without the check that the lock was locked and a shorter timeout | ||
| 1877 | @contextmanager | ||
| 1878 | def lock_timeout_nocheck(lock): | ||
| 1879 | try: | ||
| 1880 | s = signal.pthread_sigmask(signal.SIG_BLOCK, signal.valid_signals()) | ||
| 1881 | l = lock.acquire(timeout=10) | ||
| 1882 | yield l | ||
| 1883 | finally: | ||
| 1884 | if l: | ||
| 1885 | lock.release() | ||
| 1886 | signal.pthread_sigmask(signal.SIG_SETMASK, s) | ||
