23.14. What's Safe

  1. Every thread has its own stack, so local variables are always safe. If a method is doing something with a static or member variable that it could do with a local (stack) variable, that will be safer.

  2. Because of the global scene graph read/write lock, we generally assume it is safe for a method to get the value of a field without any explicit locking. The developer must carefully consider the interaction of other traversal methods (for this node) that might be executing in other threads at the same time. Directly changing the value of a field during traversal is not recommended. Propagating changes through field-to-field connections is generally safe.

  3. So, in general, a traversal method that only reads field values and only uses local variables should already be thread safe. This restriction means that the traversal method does not modify any member variables. This could include, for example, simple nodes that just modify the traversal state or just make OpenGL calls

    [Important]

    The developer must also consider methods that are invoked by the traversal method.

  4. We assume OpenGL is thread safe.

  5. We assume that an action object (instance of an action class) will only be used by one thread at a time. Among other things, this ensures that if multiple threads are traversing the scene graph, each thread has its own traversal state (SoState) because each action has its own traversal state. So a traversal method can freely query and modify the traversal state associated with the action passed to it (action->getState()).

  6. We generally assume that a node’s initClass() method will be called exactly once, usually from the application’s main thread (all the built-in nodes are initialized in SoDB::init(), etc.). However a node could use its class mutex to protect special cases in the initClass() method. If a node uses Thread Local Storage, then its initTLSClass() method must be called once in every thread that uses Open Inventor objects.

    Starting with OpenInventor 8.0, the initTLSClass() method must not be explicitly called once in every thread that uses the wanted class (whereas it was mandatory in previous version). Now all TLS initialization is done for each thread automatically by calling the SoDB::initTLSClasses() method once in every running thread.