Local thread singleton objects

The x::threadsingleton template implements support for thread-scoped singletons. It combines singletons with local thread objects. This template defines a singleton with a lifetime that's scoped to each execution thread. The difference between this template and x::singleton is that each thread that invokes get() gets a reference to a separate singleton instance in each execution thread.

#include <x/threads/singleton.H>

class myClassObj : virtual public x::obj {

// class definition


typedef x::ptr<myClassObj> myClass;

x::threadsingleton<myClass> myClassInstance;

// ...

myClass c(myClassInstance.get());


The template parameter to x::threadsingleton must be some x::ptr. The object gets constructed the first time get() gets invoked by an execution thread. Subsequent calls to get() from the same thread returns a reference to the same object. Invoking get() from a different thread return a different class instance.

get() returns a reference, no different than any other reference to a reference-counted object. The reference returned by get() can be used by other threads too. If no other references to the object exist, the object gets destroyed when its execution thread terminates, automatically. If the reference to the underlying object exists, in some other thread, that reference, just like any other reference, would keep that object from being destroyed. When a thread terminates, only that thread's local reference to the object goes out of scope.

get() return the x::ptr template parameter, however it's never null() Normally, get() returns a reference, it does not except when it's called when the entire process, or its thread, is in the process of starting and shutting down (as noted below). In a normal environment, get() should not return a null().


Local thread singleton objects work only in the main execution thread or execution threads started by x::run().

The parameter to the template class must be a reference-counted object that has a default constructor.


get() may not be invoked from constructors or destructors of other classes. Constructors and destructors can get called when a thread or an application is in the middle of initializing or terminating, and the underlying support for singleton objects is not available.