[/
  (C) Copyright 2007-8 Anthony Williams.
  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE_1_0.txt or copy at
  http://www.boost.org/LICENSE_1_0.txt).
]

[section Thread Local Storage]

[heading Synopsis]

Thread local storage allows multi-threaded applications to have a separate instance of a given data item for each thread. Where a
single-threaded application would use static or global data, this could lead to contention, deadlock or data corruption in a
multi-threaded application. One example is the C `errno` variable, used for storing the error code related to functions from the
Standard C library. It is common practice (and required by POSIX) for compilers that support multi-threaded applications to provide
a separate instance of `errno` for each thread, in order to avoid different threads competing to read or update the value.

Though compilers often provide this facility in the form of extensions to the declaration syntax (such as `__declspec(thread)` or
`__thread` annotations on `static` or namespace-scope variable declarations), such support is non-portable, and is often limited in
some way, such as only supporting POD types.

[heading Portable thread-local storage with `boost::thread_specific_ptr`]

`boost::thread_specific_ptr` provides a portable mechanism for thread-local storage that works on all compilers supported by
__boost_thread__. Each instance of `boost::thread_specific_ptr` represents a pointer to an object (such as `errno`) where each
thread must have a distinct value. The value for the current thread can be obtained using the `get()` member function, or by using
the `*` and `->` pointer deference operators. Initially the pointer has a value of `NULL` in each thread, but the value for the
current thread can be set using the `reset()` member function.

If the value of the pointer for the current thread is changed using `reset()`, then the previous value is destroyed by calling the
cleanup routine. Alternatively, the stored value can be reset to `NULL` and the prior value returned by calling the `release()`
member function, allowing the application to take back responsibility for destroying the object.

[heading Cleanup at thread exit]

When a thread exits, the objects associated with each `boost::thread_specific_ptr` instance are destroyed. By default, the object
pointed to by a pointer `p` is destroyed by invoking `delete p`, but this can be overridden for a specific instance of
`boost::thread_specific_ptr` by providing a cleanup routine to the constructor. In this case, the object is destroyed by invoking
`func(p)` where `func` is the cleanup routine supplied to the constructor. The cleanup functions are called in an unspecified
order. If a cleanup routine sets the value of associated with an instance of `boost::thread_specific_ptr` that has already been
cleaned up, that value is added to the cleanup list. Cleanup finishes when there are no outstanding instances of
`boost::thread_specific_ptr` with values.


[section:thread_specific_ptr Class `thread_specific_ptr`]

    #include <boost/thread/tss.hpp>

    template <typename T>
    class thread_specific_ptr
    {
    public:
        thread_specific_ptr();
        explicit thread_specific_ptr(void (*cleanup_function)(T*));
        ~thread_specific_ptr();

        T* get() const;
        T* operator->() const;
        T& operator*() const;

        T* release();
        void reset(T* new_value=0);
    };

[section:default_constructor `thread_specific_ptr();`]

[variablelist

[[Requires:] [`delete this->get()` is well-formed.]]

[[Effects:] [Construct a `thread_specific_ptr` object for storing a pointer to an object of type `T` specific to each thread. The
default `delete`-based cleanup function will be used to destroy any thread-local objects when `reset()` is called, or the thread
exits.]]

[[Throws:] [`boost::thread_resource_error` if an error occurs.]]

]

[endsect]

[section:constructor_with_custom_cleanup `explicit thread_specific_ptr(void (*cleanup_function)(T*));`]

[variablelist

[[Requires:] [`cleanup_function(this->get())` does not throw any exceptions.]]

[[Effects:] [Construct a `thread_specific_ptr` object for storing a pointer to an object of type `T` specific to each thread. The
supplied `cleanup_function` will be used to destroy any thread-local objects when `reset()` is called, or the thread exits.]]

[[Throws:] [`boost::thread_resource_error` if an error occurs.]]

]

[endsect]

[section:destructor `~thread_specific_ptr();`]

[variablelist

[[Effects:] [Calls `this->reset()` to clean up the associated value for the current thread, and destroys `*this`.]]

[[Throws:] [Nothing.]]

]

[note Care needs to be taken to ensure that any threads still running after an instance of `boost::thread_specific_ptr` has been
destroyed do not call any member functions on that instance.]

[endsect]

[section:get `T* get() const;`]

[variablelist

[[Returns:] [The pointer associated with the current thread.]]

[[Throws:] [Nothing.]]

]

[note The initial value associated with an instance of `boost::thread_specific_ptr` is `NULL` for each thread.]

[endsect]

[section:operator_arrow `T* operator->() const;`]

[variablelist

[[Returns:] [`this->get()`]]

[[Throws:] [Nothing.]]

]

[endsect]

[section:operator_star `T& operator*() const;`]

[variablelist

[[Requires:] [`this->get` is not `NULL`.]]

[[Returns:] [`*(this->get())`]]

[[Throws:] [Nothing.]]

]

[endsect]

[section:reset `void reset(T* new_value=0);`]

[variablelist

[[Effects:] [If `this->get()!=new_value` and `this->get()` is non-`NULL`, invoke `delete this->get()` or
`cleanup_function(this->get())` as appropriate. Store `new_value` as the pointer associated with the current thread.]]

[[Postcondition:] [`this->get()==new_value`]]

[[Throws:] [`boost::thread_resource_error` if an error occurs.]]

]

[endsect]

[section:release `T* release();`]

[variablelist

[[Effects:] [Return `this->get()` and store `NULL` as the pointer associated with the current thread without invoking the cleanup
function.]]

[[Postcondition:] [`this->get()==0`]]

[[Throws:] [Nothing.]]

]

[endsect]


[endsect]

[endsect]
