Skip to content

Commit

Permalink
Incubates #6390. Re issues #2892 and #5380.
Browse files Browse the repository at this point in the history
  • Loading branch information
jcsteh committed Sep 22, 2016
2 parents 2808f0f + f6e6433 commit 7b00844
Showing 1 changed file with 30 additions and 1 deletion.
31 changes: 30 additions & 1 deletion source/appModuleHandler.py
Expand Up @@ -178,16 +178,43 @@ def fetchAppModule(processID,appName):
def reloadAppModules():
"""Reloads running appModules.
especially, it clears the cache of running appModules and deletes them from sys.modules.
Each appModule will be reloaded immediately as a reaction on a first event coming from the process.
Each appModule will then be reloaded immediately.
"""
global appModules
state = []
for mod in runningTable.itervalues():
state.append({key: getattr(mod, key) for key in ("processID",
# #2892: We must save nvdaHelperRemote handles, as we can't reinitialize without a foreground/focus event.
# Also, if there is an active context handle such as a loaded buffer,
# nvdaHelperRemote can't reinit until that handle dies.
"helperLocalBindingHandle", "_inprocRegistrationHandle",
# #5380: We must save config profile triggers so they can be cleaned up correctly.
# Otherwise, they'll remain active forever.
"_configProfileTrigger",
) if hasattr(mod, key)})
# #2892: Don't disconnect from nvdaHelperRemote during termination.
mod._helperPreventDisconnect = True
terminate()
del appModules
mods=[k for k,v in sys.modules.iteritems() if k.startswith("appModules") and v is not None]
for mod in mods:
del sys.modules[mod]
import appModules
initialize()
for entry in state:
pid = entry.pop("processID")
mod = getAppModuleFromProcessID(pid)
mod.__dict__.update(entry)
# The appModule property for existing NVDAObjects will now be None, since their AppModule died.
# Force focus, navigator, etc. objects to re-fetch,
# since NVDA depends on the appModule property for these.
for obj in itertools.chain((api.getFocusObject(), api.getNavigatorObject()), api.getFocusAncestors()):
try:
del obj._appModuleRef
except AttributeError:
continue
# Fetch and cache right away; the process could die any time.
obj.appModule

def initialize():
"""Initializes the appModule subsystem.
Expand Down Expand Up @@ -381,6 +408,8 @@ def terminate(self):
Subclasses should call the superclass method first.
"""
winKernel.closeHandle(self.processHandle)
if getattr(self, "_helperPreventDisconnect", False):
return
if self._inprocRegistrationHandle:
ctypes.windll.rpcrt4.RpcSsDestroyClientContext(ctypes.byref(self._inprocRegistrationHandle))
if self.helperLocalBindingHandle:
Expand Down

0 comments on commit 7b00844

Please sign in to comment.