Author: Nathan Coulter <tcltips@pooryorick.com>
State: Draft
Type: Project
Vote: Pending
Created: 18-Jan-2016
Post-History:
Keywords: tcl
Tcl-Version: 8.7
Abstract
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.
Rationale
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_DYING
, NS_DEAD
, and 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.
DeleteInterpProc
calls 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:
A namespace loses track of itself
command found in deleted namespace
namespace deletion: trace that calls [apply], specifying the namespace, doesn't fire.
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.
Proposal
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
is deleted.
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
is size. See also, Improve average size of
Namespace.
NS_KILLED
will no longer be needed. A namespace being deleted is either
NS_DYING
while deallocation of related resources is in progress or NS_DEAD
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.
Implementation
See the bug-e593adf103-core-8 branch.
Copyright
This document has been placed in the public domain.