Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4219095

inheritable thread locals: need way to snapshot and recreate complete state



    • Type: Enhancement
    • Status: Closed
    • Priority: P4
    • Resolution: Won't Fix
    • Affects Version/s: 1.2.0, 1.3.1
    • Fix Version/s: None
    • Component/s: core-libs
    • Labels:
    • Subcomponent:
    • CPU:
      x86, sparc
    • OS:
      solaris_2.5, windows_2000


      There should be an API for taking a complete snapshot of the current state of all of the inheritable thread local variables in the current thread and for restoring the current thread's inheritable thread local variables to the values stored in such a snapshot. The semantics of a combination of the snapshot and restore operations on a complete set of inheritable thread local variables should probably be the same as when such thread local variables are inherited by the newly-created child thread (i.e. calling childValue(), etc.). The execution of at least the restore operation, if not the snapshot operation as well, should probably require a specific (new) runtime permission.

      This functionality is important for system libraries that invoke callbacks into application-level code, especially as the use of inheritable thread local variables becomes more common. Oftentimes, a system library will lazily create the threads that it will use to invoke callbacks the first time such a callback is registered. In the interest of performance and scalability, the library will pool and reuse those threads to invoke callbacks to other application-level code that is completely unrelated to the first component that registered a callback with the library, yet all of the callbacks invoked in the reused thread will have the inheritable thread local variables set to the values that were inherited from when the thread was created in the context of the first client of the library. This behavior seems wrong and surprisingly unpredictable, it causes the library to expose a global state that it was not intending to expose, and depending on the use of the affected inheritable thread local variables, it could represent a security hole.

      With RMI, for example, if a certain context-specific inheritable thread local variable Foo is set to X when the first remote object happens to be exported on a particular port in a given VM instance, currently, whenever the code for *any* remote method received on that port for any, potentially unrelated remote object is executed, Foo will still have the value X. Depending on the meaning of Foo, this behavior could have surprising results and cause non-deterministic bugs.

      Say that Foo is being used to represent the identity, for authorization purposes, that the code in the current thread (that is exporting the first remote object) is executing as: all future remote methods will execute in a thread with the same identity. The Java Authentication and Authorization Service documentation describes how it uses java.lang.InheritableThreadLocal in this sort of way:


      Without such an API as requested by this RFE, there is nothing that a system library like RMI can do to control the values of inheritable thread local variables that it does not know about (to preserve them appropriately on behalf of each client's application context). Note that the desired behavior could be effected by simply using thread creation to preserve inheritable thread local state: RMI could create a new pool of threads for every single remote object exported and only dispatch remote methods to a given remote object using threads in the pool for that particular object, but few would argue that in practice, RMI should be constrained to such a wasteful threading model.

      RMI makes the explicit effort to preserve the "access control context" and the "context class loader" from when a remote object was exported to when one of its remote methods is executed. The current access control context can be viewed as a special kind of thread local variable that is stack-scoped, and the context class loader is basically an inherited thread local as well-- it is a field of java.lang.Thread that is inherited by child threads-- but it isn't based on the java.lang.InheritableThreadLocal framework (for whatever reason). RMI goes through the necessary explicit effort of preserving these properties of thread context from remote export to invocation because it knows about them, but it is quite conceivable that there could be other such properties that deserve similar treatment that RMI doesn't know about. If other such properties are implemented using java.lang.InheritableThreadLocal, RMI should be able to save and restore them as appropriate without compromising or constraining its threading model.


          Issue Links



              jjb Josh Bloch
              peterjones Peter Jones
              0 Vote for this issue
              0 Start watching this issue