tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nspr_s_position_on_abrupt_thread_termination.rst (4772B)


      1 NSPR's position on abrupt thread termination
      2 ============================================
      3 
      4 This memo describes my position on a facility that is currently under
      5 discussion for inclusion in the NetScape Portable Runtime (NSPR); the
      6 ability of a thread to abruptly exit. I resist including this function
      7 in NSPR because it results in bad programming practice and unsupportable
      8 programs.
      9 
     10   *Threads are not processes.*
     11 
     12 Abrupt termination has been available in the UNIX/C environment for some
     13 time (``exit()``), and I assume that the basic semantics defined there
     14 are applicable here. In that environment, ``exit()`` may be called and
     15 any time, and results in the calling thread's immediate termination. In
     16 the situation where it was defined (UNIX), which has only a single
     17 thread of execution, that is equivalent to terminating the process. The
     18 process abstraction is then responsible for closing all open files and
     19 reclaiming all storage that may have been allocated during the process'
     20 lifetime.
     21 
     22 This practice does not extend to threads. Threads run within the
     23 confines of a process (or similar abstractions in other environments).
     24 Threads are lightweight because they do not maintain the full protection
     25 domain provided by a process. So in a threaded environment, what is the
     26 parallel to UNIX' ``exit()``?
     27 
     28 NSPR has defined a function, callable by any thread within a process at
     29 any time, called ``PR_ProcessExit()``. This is identical to UNIX
     30 ``exit()`` and was so named in an effort to make the obvious even more
     31 so. When called, the process exits, closing files and reclaiming the
     32 process' storage.
     33 
     34 Certain people have been disappointed when NSPR did not provide a
     35 functional equivalent to exit just a particular thread. Apparently they
     36 have failed to consider the ramifications. If a thread was to abruptly
     37 terminate, there is no recording of what resources it owns and should
     38 therefore be reclaimed. Those resources are in fact, owned by the
     39 process and shared by all the threads within the process.
     40 
     41 In the general course of events when programming with threads, it is
     42 very advantageous for a thread to have resources that it and only it
     43 knows about. In the natural course of events, these resources will be
     44 allocated by a thread, used for some period of time, and then freed as
     45 the stack unwinds. In these cases, the presence of the data is recorded
     46 only on the stack, known only to the single thread (normally referred to
     47 as *encapsulated*).
     48 
     49 The problem with abrupt termination is that it can happen at any time,
     50 to a thread that is coded correctly to handle both normal and
     51 exceptional situations, but will be unable to do so since it will be
     52 denied the opportunity to complete execution. It can happen because it
     53 called out of its own scope into some lazily implemented library.
     54 
     55 NSPR's answer to this is that there is no abrupt thread termination. All
     56 threads must unwind and return from their root function. If they cannot,
     57 because of some state corruption, then they must assume that the
     58 corruption, like the state, is shared, and their only resource is for
     59 the process to terminate.
     60 
     61 To make this solution work requires that a function that encounters an
     62 error be designed such that it first repairs its immediate state, and
     63 then reports that error to its caller. If the caller cannot deal with
     64 the failure, it must do the same. This process continues until the
     65 thread either recovers from the malady or returns from the root
     66 function. This is not all that difficult (though having done it a number
     67 of times to already existing code, I will admit it isn't much fun
     68 either).
     69 
     70 The implementation of either strategy within the NSPR runtime is not
     71 difficult. That is not what this memo is about. This is about providing
     72 an API that coaxes people to do the right thing in as many ways as
     73 possible. The existence of ``exit()`` in the UNIX/C environment is a
     74 perfect example of how programmers will employ the most expediant
     75 solution available. The definition of the language C is such that
     76 returning from ``main()`` is a perfectly fine thing to do. But what
     77 percentage of C programs actually bother? In UNIX, with its complex
     78 definition of a protection domain, it happens to work (one might even
     79 say it's more efficient) to exit from anywhere. But threads are not
     80 processes. If threads have to maintain the same type of resource
     81 knowledge as a process, they loose all of their benefit.
     82 
     83 Threads are an implementation strategy to provide the illusion of
     84 concurrency within a process. They are alternatives to large state
     85 machines with mostly non-blocking library functions. When the latter is
     86 used to provide concurrency, calling ``exit()`` will terminate the
     87 entire process. Why would anyone expect a thread to behave differently?
     88 Threads are not processes.