/** @page threading Threading

    @tableofcontents

    A thread is an independent sequence of execution of %Qore code within a %Qore program or script. Each thread has a
    thread ID or TID.

    The first thread of execution in a %Qore program has TID 1. TID 0 is always reserved for the special
    @ref signal_handling "signal handler thread".

    The %Qore language is designed to be thread-safe and %Qore programs should not crash the %Qore executable due to
    threading errors.  Threading errors should only cause exceptions to be thrown or application errors to occur.

    Threading functionality in %Qore is provided by the operating system's POSIX threads library.

    @section creating_and_terminating_threads Creating and Terminating Threads

    New threads are created with the @ref background "background operator". This operator executes the expression
    given as an argument in a new thread and returns the TID (integer thread ID) of the new thread to the calling
    thread.  This is most useful for calling user functions or object methods designed to run in a separate thread.

    To terminate a thread, the @ref thread_exit "thread_exit statement" should be called, as calling the
    @ref Qore::exit() "exit()" function will terminate the entire process (and therefore all threads) immediately.

    @section threading_and_variables Threading and Variables

    All global variables are shared in %Qore programs, while local variables are
    generally local to each thread (and thus accessed without any mutual-exclusion locking), regardless of location.
    This means that if a local variable is declared at the top level, it will actually have global scope, but also
    each thread will have its own copy of the variable. In effect, declaring a top-level local variable actually
    creates a global thread-local variable.

    The following code gives an example of declaring a global thread-local variable by declaring it at the top-level:

    @code{.py}
%new-style
%require-types
%strict-args

sub t() {
    printf("x=%y\n", x);
}
int x = 2;
t();
background t();
    @endcode

    This will print out:
    @verbatim
x=2
x=null@endverbatim

    Note that the second time the local variable is accessed in the background thread, it has no value.

    Due to the way %Qore's local variables work, it is illegal to declare a top-level local variable after first block
    is parsed in the program; that is; if any call to @ref Qore::parse() "parse()" or
    @ref Qore::Program::parse() "Program::parse()" is made in an existing program (where a top-level block already
    exists), and an attempt to declare a new top-level local variable is made, then an
    \c ILLEGAL-TOP-LEVEL-LOCAL-VARIABLE parse exception will be raised.

    Access to global variables in qore is wrapped in mutual-exclusion locks to guarantee safe access to global
    variable data in a multithreaded context. Local variables are thread-local and therefore not locked, except when
    referenced in a @ref closure "closure" or when a @ref lvalue_references "reference" is taken of them, in which
    case the local variable's scope is extended to that of the @ref closure "closure's" or the
    @ref lvalue_references "reference's", and all accesses to the bound local variable are made within
    mutual-exclusion locks as these variables may be used in multithreaded contexts.

    An alternative to global thread-local variables is offered by the
    @ref Qore::save_thread_data() "save_thread_data()" and @ref Qore::get_thread_data() "get_thread_data()" functions
    (documented in @ref threading_functions).

    @section thread_synchronization Thread Management and Inter-Thread Communication

    @anchor synchronized
    @par synchronized
    The <tt><b>synchronized</b></tt> keyword can be used before function or class method definitions in order to
    guarantee that the function or method call will only be executed in one thread at a time. As in Java, this keyword
    can also be used safely with recursive functions and methods (internally a recursive mutual exclusion lock that
    participates in %Qore's deadlock detection framework is used to guarantee thread-exclusivity and allow recursion).\n\n
    <tt><b>synchronized</b></tt> functions have a dedicated reentrant lock associated with the function, while
    <tt><b>synchronized</b></tt> normal class methods share a reentrant lock associated with the object, and a
    <tt><b>synchronized</b></tt> static class methods share a reentrant lock associated with the class itself.

    @par Classes Useful With Threading
    The following classes are useful when developing multi-threaded %Qore programs:\n
    |!Class|!Description
    |@ref Qore::Thread::AbstractThreadResource "AbstractThreadResource"|Allows %Qore user code to implement thread \
        resources
    |@ref Qore::Thread::AutoGate "AutoGate"|A helper class to automatically exit @ref Qore::Thread::Gate "Gate" locks \
        when the @ref Qore::Thread::AutoGate "AutoGate" object is deleted
    |@ref Qore::Thread::AutoLock "AutoLock"|A helper class to automatically release @ref Qore::Thread::Mutex "Mutex" \
        locks when the @ref Qore::Thread::AutoLock "AutoLock" object is deleted
    |@ref Qore::Thread::AutoReadLock "AutoReadLock"|A helper class to automatically release read locks when the \
        @ref Qore::Thread::AutoReadLock "AutoReadLock" object is deleted
    |@ref Qore::Thread::AutoWriteLock "AutoWriteLock"|A helper class to automatically release read locks when the \
        @ref Qore::Thread::AutoReadLock "AutoWriteLock" object is deleted
    |@ref Qore::Thread::Condition "Condition"|Allows %Qore programs to block until a certain condition becomes true
    |@ref Qore::Thread::Counter "Counter"|A blocking counter class
    |@ref Qore::Thread::Gate "Gate"|A recursive thread lock
    |@ref Qore::Thread::Mutex "Mutex"|A mutual-exclusion thread lock
    |@ref Qore::Thread::Queue "Queue"|A thread-safe, blocking queue class (useful for message passing)
    |@ref Qore::Thread::RWLock "RWLock"|A read-write thread lock
    |@ref Qore::Thread::Sequence "Sequence"|A simple, thread-atomic sequence object (increment-only)
    |@ref Qore::Thread::ThreadPool "ThreadPool"|A flexible, dynamically scalable thread pool

    @par Functions Useful With Threading
    The following functions assist writing safe and efficient multi-threaded %Qore programs:\n
    |!Function|!Description
    |@ref Qore::delete_all_thread_data() "delete_all_thread_data()"|Deletes the entire thread-local data hash
    |@ref Qore::delete_thread_data() "delete_thread_data()"|Delete the value of a key in the thread-local data hash
    |@ref Qore::get_all_thread_data() "get_all_thread_data()"|Retrieves the entire thread-local hash
    |@ref Qore::get_thread_data() "get_thread_data()"|Retrieves a thread-local value based on a key
    |@ref Qore::gettid() "gettid()"|Gets the thread's TID (thread identifier)
    |@ref Qore::mark_thread_resources() "mark_thread_resources()"|sets a checkpoint for throwing thread resource \
        exceptions
    |@ref Qore::num_threads() "num_threads()"|Returns the number of running threads
    |@ref Qore::remove_thread_resource() "remove_thread_resource()"|removes a thread resource from the current thread
    |@ref Qore::save_thread_data() "save_thread_data()"|Saves a thread-local value against a key
    |@ref Qore::set_thread_init() "set_thread_init()"|Sets a @ref closure "closure" or \
        @ref call_reference "call reference" to run every time a new thread is started in a \
        @ref Qore::Program "Program" object
    |@ref Qore::set_thread_resource() "set_thread_resource()"|sets a thread resource against the current thread
    |@ref Qore::thread_list() "thread_list()"|Returns a list of TIDs of running threads
    |@ref Qore::throw_thread_resource_exceptions() "throw_thread_resource_exceptions()"|runs thread-resource cleanup \
        routines and throws the associated exceptions
    |@ref Qore::throw_thread_resource_exceptions_to_mark() "throw_thread_resource_exceptions_to_mark()"|runs \
        thread-resource cleanup routines and throws the associated exceptions to the last mark and clears the mark

    @section thread_resources Thread Resources

    %Qore supports a concept called thread resources; thread resources are resources that belong to a particular
    thread and that require some sort of cleanup of the resource in case the thread is exited without releasing the
    resource.  Examples of thread resources in %Qore are as follows:
    - @ref Qore::Thread::Mutex "Mutex": when a lock is acquired, the lock is tracked as a thread resource.  If the
      thread is exited without releasing the lock, the @ref Qore::Thread::Mutex "Mutex" thread resource cleanup
      routine is executed which releases the lock and throws a user-friendly exception explaining what happened.  When
      the lock is released, the thread resource is removed.
    - @ref Qore::Thread::RWLock "RWLock": read-write locks are treated as thread resources in the same way described
      for @ref Qore::Thread::Mutex "Mutex" locks
    - @ref Qore::Thread::Gate "Gate": gate locks are treated as thread resources in the same way described for
      @ref Qore::Thread::Mutex "Mutex" locks
    - @ref Qore::SQL::Datasource "Datasource": the transaction lock is handled as a thread resource; if a thread exits
      holding the transaction lock, the @ref Qore::SQL::Datasource "Datasource" cleanup routine is executed; this will
      rollback the transaction (freeing the transaction lock) and throw an appropriate exception.
    - @ref Qore::SQL::DatasourcePool "DatasourcePool": datasource allocations are handled as a thread resources; if a
      thread exits without releasing the connection, the @ref Qore::SQL::DatasourcePool "DatasourcePool" cleanup
      routine is executed; this will rollback the transaction (releasing the dtasource connection back to the pool)
      and throw an appropriate exception.

    User classes can implement their own thread resource handling by subclassing
    @ref Qore::Thread::AbstractThreadResource "AbstractThreadResource"  (implementing custom cleanup code in the
    @ref Qore::Thread::AbstractThreadResource::cleanup() "AbstractThreadResource::cleanup()" method) and then calling:
    - @ref Qore::set_thread_resource() "set_thread_resource()": to set the resource against the thread
    - @ref Qore::remove_thread_resource() "remove_thread_resource()": to remove the resource from the thread

    If the thread is exited or one of the thread resource cleanup functions is called while the thread resource is
    set, then the @ref Qore::Thread::AbstractThreadResource::cleanup() "AbstractThreadResource::cleanup()" method is
    called, which should cleanup the thread resource and normally throw a user-friendly exception describing the
    error, the cleanup actions takenm and how to prevent it in the future.

    The thread-resource cleanup functions are:
    - @ref Qore::throw_thread_resource_exceptions() "throw_thread_resource_exceptions()": runs thread-resource cleanup
      routines explicitly
    - @ref Qore::throw_thread_resource_exceptions_to_mark() "throw_thread_resource_exceptions_to_mark()": runs
      thread-resource cleanup routines for all thread resources set since the last explicit call to
      @ref Qore::mark_thread_resources() "mark_thread_resources()"

    @see @ref Qore::Thread::AbstractThreadResource "AbstractThreadResource" for an example of custom thread resource
    handling

    @section deadlocks Deadlocks

    %Qore supports deadlock detection in complex locking scenarios and will throw a \c THREAD-DEADLOCK exception
    rather than allow an operation to be performed that would cause a deadlock. Deadlock detection is implemented for
    internal locking (global variable and object access), @ref synchronized "synchronized" methods and functions, etc,
    as well as for all %Qore threading classes.

    %Qore can only detect deadlocks when a lock resource acquired by one thread is required by another who holds a
    lock that the first thread also needs. Other errors such as forgetting to unlock a global lock and trying to
    acquire that lock in another thread cannot be differentiated from valid use of threading primitives and will
    result in a process that never terminates (a deadlocked process). However, common threading errors such as trying
    to lock the same @ref Qore::Thread::Mutex "Mutex" twice in the same thread without unlocking it between the two
    @ref Qore::Thread::Mutex::lock() "Mutex::lock()" calls are caught in %Qore and exceptions are thrown.
    Additionally, locks are tracked as thread resources, so if a thread terminates while holding a lock, an exception
    will be thrown and the lock will be automatically released.
*/
