Author: Nathan Coulter <[email protected]> State: Draft Type: Project Vote: Pending Created: 18-Jan-2016 Post-History: Keywords: tcl Tcl-Version: 8.7 Tcl-Branch: bug-e593adf103-core-8
Simplify the implementation of
Tcl_DeleteNamespace in order to make behaviour
more consistent, facilitate the resolution of outstanding issues, and pave the
way for further developments.
Tcl_DeleteNamespace plays a key role in the deallocation of various
resources, from interpreters to objects in object systems, but the current
implementation is problematic. Troubling indicators include:
The accumulation of the flags
NS_KILLED, some of
which were added to fix things up when trouble arose, and indicate subtly
different states during cleanup.
Namespace.earlyDeleteProc was added in order to make namespaces usable by
TclOO and other object systems, but if the order of cleanup operations had been
different, it wouldn't have been necessary.
TclTeardownNamespace and then later calls
Tcl_DeleteNamespace, which also calls
TclTeardownNamespace. This currently
"works", but it's difficult to reason about interpreter cleanup and what latent
bugs might exist. It's likely that there are some.
After a namespace is deleted, any evaluation levels using it as the current namespace still have access to it, and commands and variables can still be created in it but they disappear at some later point depending on the state of the call stack. Although this behaviour is documented, it was probably a concession to the implementation rather than by original intent. A further complication is that it's possible to simultaneously access both the deleted namespace and a new namespace having the same name. Reports that illustrate these issues include:
Finally, the current cleanup routines perform enough contortions to be a real barrier to any further improvement of the system.
The work to simplify the TclOO implementation, lead to the work to simplify Tcl_DeleteNamespace.
There are various reports about traces that that silently fail under one
condtition or another. The simplification of
Tcl_DeleteNamespace is a
precursor to the resolution of those issues.
The implementation of
Tcl_DeleteNamespace will by simplified by reordering
its cleanup operations and tidying up related code. When a namespace is
deleted, any evaluation levels using that namespace as the current namespace
will instead use the global namespace. While this behaviour might be
surprising to the user, the current situation, where phantom namespaces
disappear at the will of the interpreter, is even more surprising. It is
easier to discover that the current namespace is the global namespace than it
is to determine why a namespace which exists at one point no longer exists at
another point, even though there is no point in between at which the namespace
The completion of this TIP will render more tractable the issue trace deletes the namespace when a command is replaced, producing "called Tcl_CreateHashEntry on deleted table".
activationCount is removed from the
Namespace structure, slightly reducing
its size. See also, Improve average size of
NS_KILLED will no longer be needed. A namespace being deleted is either
NS_DYING while deallocation of related resources is in progress or
while it's still referenced somewhere.
The issue (tailcall|yieldto) failed to find the proper namespace Abort becomes more straightforward to reason about since there are no longer namespaces that exist but that are not reachable by name.
It will be documented that when a namespace is deleted, ensemble commands, child namespaces, commands in the namespace, and variables in the namespace are deleted in that order. Because the deletion of a resource can trigger the creation of other resources, this process iterates until all relevant resources are deleted. It is left to the programmer to ensure that an loop does not occur. Currently variables are deleted before commands, but variables are more fundamental in the sense that commands can reference them, and it is reasonable to tear down the structure before removing the foundation.
See the bug-e593adf103-core-8 branch.
This document has been placed in the public domain.