bitbake: cooker: Ensure we handle inotify before running the next command

The inotify watch events are handled "at idle" which could in theory mean
a command could run before any preceeding inotify events have been processed.
This leads to a theoretical race window where those events may have a
signficicant effect on the command.

Add a mechanism to allow us to ensure all pending events are processed before
running commands.

(Bitbake rev: bf76cd7e5881adf264b8ba64e27a5b6ca9df4fde)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Richard Purdie
2017-08-09 12:54:34 +01:00
parent 0cb62f8ca7
commit 019f518287
2 changed files with 12 additions and 7 deletions

View File

@@ -78,6 +78,7 @@ class Command:
if not hasattr(command_method, 'readonly') or False == getattr(command_method, 'readonly'):
return None, "Not able to execute not readonly commands in readonly mode"
try:
self.cooker.process_inotify_updates()
if getattr(command_method, 'needconfig', False):
self.cooker.updateCacheSync()
result = command_method(self, commandline)
@@ -98,6 +99,7 @@ class Command:
def runAsyncCommand(self):
try:
self.cooker.process_inotify_updates()
if self.cooker.state in (bb.cooker.state.error, bb.cooker.state.shutdown, bb.cooker.state.forceshutdown):
# updateCache will trigger a shutdown of the parser
# and then raise BBHandledException triggering an exit

View File

@@ -205,15 +205,11 @@ class BBCooker:
self.inotify_modified_files = []
def _process_inotify_updates(server, notifier_list, abort):
for n in notifier_list:
if n.check_events(timeout=0):
# read notified events and enqeue them
n.read_events()
n.process_events()
def _process_inotify_updates(server, cooker, abort):
cooker.process_inotify_updates()
return 1.0
self.configuration.server_register_idlecallback(_process_inotify_updates, [self.confignotifier, self.notifier])
self.configuration.server_register_idlecallback(_process_inotify_updates, self)
# TOSTOP must not be set or our children will hang when they output
try:
@@ -241,6 +237,13 @@ class BBCooker:
os.write(readypipe, b"ready")
os.close(readypipe)
def process_inotify_updates(self):
for n in [self.confignotifier, self.notifier]:
if n.check_events(timeout=0):
# read notified events and enqeue them
n.read_events()
n.process_events()
def config_notifications(self, event):
if event.maskname == "IN_Q_OVERFLOW":
bb.warn("inotify event queue overflowed, invalidating caches.")