def _quit(code=0, _self=cmd): pymol = _self._pymol # WARNING: internal routine, subject to change _self.interrupt() try: _self.lock(_self) try: # flush and close log if possible to avoid threading exception if pymol._log_file is not None: try: pymol._log_file.flush() except: pass pymol._log_file.close() del pymol._log_file except: pass if _self.reaper is not None: try: _self.reaper.join() except: pass r = _cmd.quit(_self._COb, int(code)) finally: _self.unlock(-1, _self) return r
def unlock(result=None, _self=cmd): # INTERNAL if (thread.get_ident() == pymol.glutThread): if _self.reaper: try: if not _self.reaper.isAlive(): if pymol.invocation.options.no_gui: _cmd.quit(_self._COb) # TO FIX else: _self.reaper = None except: pass _self.lock_api.release() # print "lock: released by 0x%x (glut)"%thread.get_ident() if _self.lock_api_allow_flush: if result == None: # don't flush if we have an incipient error (negative input) _cmd.flush_now(_self._COb) elif _self.is_ok(result): _cmd.flush_now(_self._COb) else: # print "lock: released by 0x%x (not glut), waiting queue"%thread.get_ident() _self.lock_api.release() if _cmd.wait_queue(_self._COb): # commands waiting to be executed? e = threading.Event( ) # abdicate control for a 100 usec for quick tasks e.wait(0.0001) del e # then give PyMOL increasingly longer intervals to get its work done... w = 0.0005 # NOTE: affects API perf. for "do" and delayed-exec while _cmd.wait_queue(_self._COb): e = threading.Event( ) # abdicate control for a 100 usec for quick tasks e.wait(w) del e if w > 0.1: # wait up 0.2 sec max for PyMOL to flush queue if _self._feedback(fb_module.cmd, fb_mask.debugging, _self): fb_debug.write("Debug: avoiding possible dead-lock?\n") # print "dead locked as 0x%x"%thread.get_ident() break w = w * 2 # wait twice as long each time until flushed
def unlock(result=None, _self=cmd): # INTERNAL ''' Release the API lock and flush the command queue ''' thread_owns_gui = _self.is_gui_thread() if thread_owns_gui and _self.reaper is not None: # TODO what's the use case? How can the finish_launching() thread # die and what's the expected behavior? (see PYMOL-3247) try: if not _self.reaper.is_alive(): if _self._pymol.invocation.options.no_gui: _cmd.quit(_self._COb) # TO FIX else: _self.reaper = None except: pass _self.lock_api.release() # don't flush if we have an incipient error (negative input) if _self.is_error(result): return if thread_owns_gui: if _self.lock_api_allow_flush: _cmd.flush_now(_self._COb) else: # TODO: what's the logic here? We assume we have to wait for # cmd.do() calls being executed by GUI thread, but only for 200ms? # What's the concrete use case and would there be a better (more # predictable) logic for it? Isn't this an invitation for race # conditions, e.g. other threads could call cmd.do() and make us # wait for it? (see PYMOL-3248) # NOTE: affects API perf. for "do" and delayed-exec w = 0.0005 while w < 0.1 and _cmd.wait_queue(_self._COb): threading.Event().wait(w) w *= 2
def unlock(result=None,_self=cmd): # INTERNAL if (thread.get_ident() == pymol.glutThread): if _self.reaper: try: if not _self.reaper.isAlive(): if pymol.invocation.options.no_gui: _cmd.quit(_self._COb) # TO FIX else: _self.reaper = None except: pass _self.lock_api.release() # print "lock: released by 0x%x (glut)"%thread.get_ident() if _self.lock_api_allow_flush: if result==None: # don't flush if we have an incipient error (negative input) _cmd.flush_now(_self._COb) elif _self.is_ok(result): _cmd.flush_now(_self._COb) else: # print "lock: released by 0x%x (not glut), waiting queue"%thread.get_ident() _self.lock_api.release() if _cmd.wait_queue(_self._COb): # commands waiting to be executed? e = threading.Event() # abdicate control for a 100 usec for quick tasks e.wait(0.0001) del e # then give PyMOL increasingly longer intervals to get its work done... w = 0.0005 # NOTE: affects API perf. for "do" and delayed-exec while _cmd.wait_queue(_self._COb): e = threading.Event() # abdicate control for a 100 usec for quick tasks e.wait(w) del e if w > 0.1: # wait up 0.2 sec max for PyMOL to flush queue if _self._feedback(fb_module.cmd,fb_mask.debugging,_self): fb_debug.write("Debug: avoiding possible dead-lock?\n") # print "dead locked as 0x%x"%thread.get_ident() break w = w * 2 # wait twice as long each time until flushed
def _quit(code=0, _self=cmd): pymol=_self._pymol # WARNING: internal routine, subject to change try: _self.lock(_self) try: # flush and close log if possible to avoid threading exception if pymol._log_file!=None: try: pymol._log_file.flush() except: pass pymol._log_file.close() del pymol._log_file except: pass if _self.reaper!=None: try: _self.reaper.join() except: pass r = _cmd.quit(_self._COb, int(code)) finally: _self.unlock(-1,_self) return r