def _decide_on_what_to_do(self):
if self.native.job.startup_user_interaction_required: logger.info( _("Sending ShowInteractiveUI() and not starting the job..."))
# Ask the application to show the interaction GUI self._session_wrapper.ShowInteractiveUI(self)
else: logger.info(_("Running %r right away"), self.native.job)
NOTE: here we're taking the result lock and call the method below:
with self._result_lock: self._result_future = self._run_and_set_callback()
def _run_and_set_callback(self):
"""
Internal method of PrimedJobWrapper
Starts the future for the job result, adds a callbacks to it and
returns the future.
"""
future = self.native.run() logger.info("Added callback %r to future %r", self._result_ready, future)
NOTE: here we're running under the lock and we call the add_done_callback() method. By this time the future is already executed and ready. Calling the method now calls the callback immediately. This calls the last method in the pack below
def _result_ready(self, result_future):
"""
Internal method called when the result future becomes ready
""" logger.debug("_result_ready(%r)", result_future)
NOTE: here we try to to re-acquire the same lock. Bam. Deadlock
The problem is right here:
def _decide_ on_what_ to_do(self) : job.startup_ user_interactio n_required:
logger. info(
_("Sending ShowInteractiveUI() and not starting the job..."))
self. _session_ wrapper. ShowInteractive UI(self)
logger. info(_( "Running %r right away"), self.native.job)
if self.native.
# Ask the application to show the interaction GUI
else:
NOTE: here we're taking the result lock and call the method below:
with self._result_lock:
self. _result_ future = self._run_ and_set_ callback( )
def _run_and_ set_callback( self):
"""
Internal method of PrimedJobWrapper
Starts the future for the job result, adds a callbacks to it and
logger. info("Added callback %r to future %r", self._result_ready, future)
returns the future.
"""
future = self.native.run()
NOTE: here we're running under the lock and we call the add_done_callback() method. By this time the future is already executed and ready. Calling the method now calls the callback immediately. This calls the last method in the pack below
return future
def _result_ready(self, result_future):
logger. debug(" _result_ ready(% r)", result_future)
"""
Internal method called when the result future becomes ready
"""
NOTE: here we try to to re-acquire the same lock. Bam. Deadlock
with self._result_lock: