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

View File

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