From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- ...spr_s_position_on_abrupt_thread_termination.rst | 88 ++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 docs/nspr/nspr_s_position_on_abrupt_thread_termination.rst (limited to 'docs/nspr/nspr_s_position_on_abrupt_thread_termination.rst') diff --git a/docs/nspr/nspr_s_position_on_abrupt_thread_termination.rst b/docs/nspr/nspr_s_position_on_abrupt_thread_termination.rst new file mode 100644 index 0000000000..7cbda0c2c6 --- /dev/null +++ b/docs/nspr/nspr_s_position_on_abrupt_thread_termination.rst @@ -0,0 +1,88 @@ +NSPR's position on abrupt thread termination +============================================ + +This memo describes my position on a facility that is currently under +discussion for inclusion in the NetScape Portable Runtime (NSPR); the +ability of a thread to abruptly exit. I resist including this function +in NSPR because it results in bad programming practice and unsupportable +programs. + + *Threads are not processes.* + +Abrupt termination has been available in the UNIX/C environment for some +time (``exit()``), and I assume that the basic semantics defined there +are applicable here. In that environment, ``exit()`` may be called and +any time, and results in the calling thread's immediate termination. In +the situation where it was defined (UNIX), which has only a single +thread of execution, that is equivalent to terminating the process. The +process abstraction is then responsible for closing all open files and +reclaiming all storage that may have been allocated during the process' +lifetime. + +This practice does not extend to threads. Threads run within the +confines of a process (or similar abstractions in other environments). +Threads are lightweight because they do not maintain the full protection +domain provided by a process. So in a threaded environment, what is the +parallel to UNIX' ``exit()``? + +NSPR has defined a function, callable by any thread within a process at +any time, called ``PR_ProcessExit()``. This is identical to UNIX +``exit()`` and was so named in an effort to make the obvious even more +so. When called, the process exits, closing files and reclaiming the +process' storage. + +Certain people have been disappointed when NSPR did not provide a +functional equivalent to exit just a particular thread. Apparently they +have failed to consider the ramifications. If a thread was to abruptly +terminate, there is no recording of what resources it owns and should +therefore be reclaimed. Those resources are in fact, owned by the +process and shared by all the threads within the process. + +In the general course of events when programming with threads, it is +very advantageous for a thread to have resources that it and only it +knows about. In the natural course of events, these resources will be +allocated by a thread, used for some period of time, and then freed as +the stack unwinds. In these cases, the presence of the data is recorded +only on the stack, known only to the single thread (normally referred to +as *encapsulated*). + +The problem with abrupt termination is that it can happen at any time, +to a thread that is coded correctly to handle both normal and +exceptional situations, but will be unable to do so since it will be +denied the opportunity to complete execution. It can happen because it +called out of its own scope into some lazily implemented library. + +NSPR's answer to this is that there is no abrupt thread termination. All +threads must unwind and return from their root function. If they cannot, +because of some state corruption, then they must assume that the +corruption, like the state, is shared, and their only resource is for +the process to terminate. + +To make this solution work requires that a function that encounters an +error be designed such that it first repairs its immediate state, and +then reports that error to its caller. If the caller cannot deal with +the failure, it must do the same. This process continues until the +thread either recovers from the malady or returns from the root +function. This is not all that difficult (though having done it a number +of times to already existing code, I will admit it isn't much fun +either). + +The implementation of either strategy within the NSPR runtime is not +difficult. That is not what this memo is about. This is about providing +an API that coaxes people to do the right thing in as many ways as +possible. The existence of ``exit()`` in the UNIX/C environment is a +perfect example of how programmers will employ the most expediant +solution available. The definition of the language C is such that +returning from ``main()`` is a perfectly fine thing to do. But what +percentage of C programs actually bother? In UNIX, with its complex +definition of a protection domain, it happens to work (one might even +say it's more efficient) to exit from anywhere. But threads are not +processes. If threads have to maintain the same type of resource +knowledge as a process, they loose all of their benefit. + +Threads are an implementation strategy to provide the illusion of +concurrency within a process. They are alternatives to large state +machines with mostly non-blocking library functions. When the latter is +used to provide concurrency, calling ``exit()`` will terminate the +entire process. Why would anyone expect a thread to behave differently? +Threads are not processes. -- cgit v1.2.3