Use context manager for handling G.progress_lock

Manually calling `G.progress_lock.release()` is error-prone as it's not
called when an exception is raised while the lock is acquired.
This commit is contained in:
2018-08-14 13:43:29 +02:00
parent d252f75acf
commit c915a486cb
2 changed files with 74 additions and 86 deletions

View File

@@ -50,46 +50,42 @@ class ProgressProviderSink:
self.process = None self.process = None
def progress(self, count, total, prefix="", suffix=""): def progress(self, count, total, prefix="", suffix=""):
G.progress_lock.acquire() with G.progress_lock:
if total != 0: if total != 0:
self.current_progress = float(count) / float(total) self.current_progress = float(count) / float(total)
else: else:
self.current_progress = 0.0 self.current_progress = 0.0
G.progress_lock.release()
def clear(self): def clear(self):
G.progress_lock.acquire() with G.progress_lock:
self.current_progress = 0 self.current_progress = 0
G.progress_lock.release()
def step(self, step_name): def step(self, step_name):
G.progress_lock.acquire() with G.progress_lock:
if self.current_step != step_name: if self.current_step != step_name:
self.current_step = step_name self.current_step = step_name
self.current_progress = 0 self.current_progress = 0
G.progress_lock.release()
def scene(self, scene_name): def scene(self, scene_name):
G.progress_lock.acquire() with G.progress_lock:
self.current_scene = scene_name self.current_scene = scene_name
if scene_name: if scene_name:
G.scene_status[scene_name] = "Rendering..." G.scene_status[scene_name] = "Rendering..."
G.progress_lock.release()
def scene_stats(self, scene_name, stats): def scene_stats(self, scene_name, stats):
G.progress_lock.acquire() with G.progress_lock:
if stats: if stats:
G.scene_status[scene_name] = util.humanReadableTimeDifference( G.scene_status[scene_name] = util.humanReadableTimeDifference(
stats.total_render_time) stats.total_render_time)
else: else:
G.scene_status[scene_name] = "Crashed :(" G.scene_status[scene_name] = "Crashed :("
G.progress_lock.release()
def render_process(self, process): def render_process(self, process):
self.process = process self.process = process
def is_canceled(self): def is_canceled(self):
return G.cancel with G.progress_lock:
return G.cancel
class LoggerProviderSink: class LoggerProviderSink:
@@ -229,12 +225,10 @@ def modify_device_info(device_info):
def benchmark_thread(ctx): def benchmark_thread(ctx):
G.progress_lock.acquire() with G.progress_lock:
G.progress_status = "Collecting system information." G.progress_status = "Collecting system information."
if G.cancel: if G.cancel:
G.progress_lock.release() return
return
G.progress_lock.release()
blender_system_info = system_info_get(ctx) blender_system_info = system_info_get(ctx)
@@ -245,13 +239,11 @@ def benchmark_thread(ctx):
# TODO(sergey): Report an error somehow. # TODO(sergey): Report an error somehow.
return return
G.progress_lock.acquire() with G.progress_lock:
G.result_platform = construct_platform_string(blender_system_info) G.result_platform = construct_platform_string(blender_system_info)
if G.cancel: if G.cancel:
G.progress_lock.release() return
return G.progress_status = "Prepating render."
G.progress_status = "Prepating render."
G.progress_lock.release()
all_stats = benchrunner.benchmarkAll(ctx) all_stats = benchrunner.benchmarkAll(ctx)
# Gather all information together. # Gather all information together.
@@ -264,11 +256,9 @@ def benchmark_thread(ctx):
"scenes": all_stats if all_stats else {} "scenes": all_stats if all_stats else {}
}) })
G.progress_lock.acquire() with G.progress_lock:
if G.cancel: if G.cancel:
G.progress_lock.release() return
return
G.progress_lock.release()
G.result_dict = result G.result_dict = result
@@ -377,12 +367,11 @@ class BENCHMARK_PT_main(Panel):
def draw(self, context): def draw(self, context):
screen_index = 0 screen_index = 0
G.progress_lock.acquire() with G.progress_lock:
if G.result_dict: if G.result_dict:
screen_index = 2 screen_index = 2
elif G.result_stats or G.progress_status: elif G.result_stats or G.progress_status:
screen_index = 1 screen_index = 1
G.progress_lock.release()
if screen_index == 0: if screen_index == 0:
self.draw_welcome(context) self.draw_welcome(context)
@@ -444,31 +433,30 @@ class BENCHMARK_OT_run_base(bpy.types.Operator):
logger.setProvider(self.logger_provider) logger.setProvider(self.logger_provider)
def update_status(self, context): def update_status(self, context):
G.progress_lock.acquire() with G.progress_lock:
step = self.progress_provider.current_step step = self.progress_provider.current_step
if G.cancel: if G.cancel:
G.progress_status = "Canceling..." G.progress_status = "Canceling..."
elif step == 'WARM_UP': elif step == 'WARM_UP':
G.progress_status = "Rendering warm-up pass..." G.progress_status = "Rendering warm-up pass..."
elif step == 'RUN': elif step == 'RUN':
G.current_progress = self.progress_provider.current_progress G.current_progress = self.progress_provider.current_progress
G.progress_status = "Rendering... Press Esc to stop." G.progress_status = "Rendering... Press Esc to stop."
context.area.tag_redraw() context.area.tag_redraw()
# Path to currently displayed background image. # Path to currently displayed background image.
current_scene = self.progress_provider.current_scene current_scene = self.progress_provider.current_scene
if current_scene: if current_scene:
G.background_image_path = os.path.join( G.background_image_path = os.path.join(
self.benchmark_context.scenes_dir, self.benchmark_context.scenes_dir,
current_scene, current_scene,
current_scene + ".png") current_scene + ".png")
else: else:
G.background_image_path = "" G.background_image_path = ""
# Update per-scene status string # Update per-scene status string
G.result_stats = "" G.result_stats = ""
for scene in G.scene_status: for scene in G.scene_status:
G.result_stats += "{}: {}\n".format( G.result_stats += "{}: {}\n".format(
scene, G.scene_status[scene]) scene, G.scene_status[scene])
G.progress_lock.release()
def done(self, context): def done(self, context):
wm = context.window_manager wm = context.window_manager
@@ -502,6 +490,7 @@ class BENCHMARK_OT_run_base(bpy.types.Operator):
# TOGO(sergey): Use some more nice picture for the final slide. # TOGO(sergey): Use some more nice picture for the final slide.
G.background_image_path = "" G.background_image_path = ""
# Tag for nice redraw # Tag for nice redraw
# TODO(Sybren): lock G.progress_lock
G.progress_status = None G.progress_status = None
G.current_progress = 0.0 G.current_progress = 0.0
context.area.tag_redraw() context.area.tag_redraw()
@@ -567,10 +556,10 @@ class BENCHMARK_OT_run_base(bpy.types.Operator):
return {'RUNNING_MODAL'} return {'RUNNING_MODAL'}
def cancel_request(self, context): def cancel_request(self, context):
G.progress_lock.acquire() with G.progress_lock:
G.cancel = True G.cancel = True
context.area.tag_redraw() context.area.tag_redraw()
G.progress_lock.release()
if self.progress_provider.process: if self.progress_provider.process:
if platform.system() == "Windows": if platform.system() == "Windows":
self.progress_provider.process.kill() self.progress_provider.process.kill()

View File

@@ -77,12 +77,11 @@ def draw_image(filepath, x, y, w, h):
# Draw. # Draw.
def benchmark_draw_post_pixel(arg1, arg2): def benchmark_draw_post_pixel(arg1, arg2):
G.progress_lock.acquire() with G.progress_lock:
progress_status = G.progress_status progress_status = G.progress_status
result_platform = G.result_platform result_platform = G.result_platform
result_stats = G.result_stats result_stats = G.result_stats
result_dict = G.result_dict result_dict = G.result_dict
G.progress_lock.release()
ui_scale = bpy.context.user_preferences.system.ui_scale ui_scale = bpy.context.user_preferences.system.ui_scale
blf.color(font_id, 1.0, 1.0, 1.0, 1.0) blf.color(font_id, 1.0, 1.0, 1.0, 1.0)