Updated tinythread to 1.1
This commit is contained in:
parent
1c20982004
commit
c1844e2ee9
2 changed files with 118 additions and 32 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/* -*- mode: c++; tab-width: 2; indent-tabs-mode: nil; -*-
|
||||||
Copyright (c) 2010 Marcus Geelnard
|
Copyright (c) 2010-2012 Marcus Geelnard
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any damages
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
@ -171,7 +171,7 @@ void * thread::wrapper_function(void * aArg)
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
// Uncaught exceptions will terminate the application (default behavior
|
// Uncaught exceptions will terminate the application (default behavior
|
||||||
// according to the C++0x draft)
|
// according to C++11)
|
||||||
std::terminate();
|
std::terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,6 +228,7 @@ void thread::join()
|
||||||
{
|
{
|
||||||
#if defined(_TTHREAD_WIN32_)
|
#if defined(_TTHREAD_WIN32_)
|
||||||
WaitForSingleObject(mHandle, INFINITE);
|
WaitForSingleObject(mHandle, INFINITE);
|
||||||
|
CloseHandle(mHandle);
|
||||||
#elif defined(_TTHREAD_POSIX_)
|
#elif defined(_TTHREAD_POSIX_)
|
||||||
pthread_join(mHandle, NULL);
|
pthread_join(mHandle, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
@ -242,6 +243,21 @@ bool thread::joinable() const
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void thread::detach()
|
||||||
|
{
|
||||||
|
mDataMutex.lock();
|
||||||
|
if(!mNotAThread)
|
||||||
|
{
|
||||||
|
#if defined(_TTHREAD_WIN32_)
|
||||||
|
CloseHandle(mHandle);
|
||||||
|
#elif defined(_TTHREAD_POSIX_)
|
||||||
|
pthread_detach(mHandle);
|
||||||
|
#endif
|
||||||
|
mNotAThread = true;
|
||||||
|
}
|
||||||
|
mDataMutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
thread::id thread::get_id() const
|
thread::id thread::get_id() const
|
||||||
{
|
{
|
||||||
if(!joinable())
|
if(!joinable())
|
||||||
|
|
128
src/tinythread.h
128
src/tinythread.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/* -*- mode: c++; tab-width: 2; indent-tabs-mode: nil; -*-
|
||||||
Copyright (c) 2010 Marcus Geelnard
|
Copyright (c) 2010-2012 Marcus Geelnard
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any damages
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
@ -24,6 +24,37 @@ freely, subject to the following restrictions:
|
||||||
#ifndef _TINYTHREAD_H_
|
#ifndef _TINYTHREAD_H_
|
||||||
#define _TINYTHREAD_H_
|
#define _TINYTHREAD_H_
|
||||||
|
|
||||||
|
/// @file
|
||||||
|
/// @mainpage TinyThread++ API Reference
|
||||||
|
///
|
||||||
|
/// @section intro_sec Introduction
|
||||||
|
/// TinyThread++ is a minimal, portable implementation of basic threading
|
||||||
|
/// classes for C++.
|
||||||
|
///
|
||||||
|
/// They closely mimic the functionality and naming of the C++11 standard, and
|
||||||
|
/// should be easily replaceable with the corresponding std:: variants.
|
||||||
|
///
|
||||||
|
/// @section port_sec Portability
|
||||||
|
/// The Win32 variant uses the native Win32 API for implementing the thread
|
||||||
|
/// classes, while for other systems, the POSIX threads API (pthread) is used.
|
||||||
|
///
|
||||||
|
/// @section class_sec Classes
|
||||||
|
/// In order to mimic the threading API of the C++11 standard, subsets of
|
||||||
|
/// several classes are provided. The fundamental classes are:
|
||||||
|
/// @li tthread::thread
|
||||||
|
/// @li tthread::mutex
|
||||||
|
/// @li tthread::recursive_mutex
|
||||||
|
/// @li tthread::condition_variable
|
||||||
|
/// @li tthread::lock_guard
|
||||||
|
/// @li tthread::fast_mutex
|
||||||
|
///
|
||||||
|
/// @section misc_sec Miscellaneous
|
||||||
|
/// The following special keywords are available: #thread_local.
|
||||||
|
///
|
||||||
|
/// For more detailed information (including additional classes), browse the
|
||||||
|
/// different sections of this documentation. A good place to start is:
|
||||||
|
/// tinythread.h.
|
||||||
|
|
||||||
// Which platform are we on?
|
// Which platform are we on?
|
||||||
#if !defined(_TTHREAD_PLATFORM_DEFINED_)
|
#if !defined(_TTHREAD_PLATFORM_DEFINED_)
|
||||||
#if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)
|
#if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)
|
||||||
|
@ -36,7 +67,15 @@ freely, subject to the following restrictions:
|
||||||
|
|
||||||
// Platform specific includes
|
// Platform specific includes
|
||||||
#if defined(_TTHREAD_WIN32_)
|
#if defined(_TTHREAD_WIN32_)
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#define __UNDEF_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#ifdef __UNDEF_LEAN_AND_MEAN
|
||||||
|
#undef WIN32_LEAN_AND_MEAN
|
||||||
|
#undef __UNDEF_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
@ -50,22 +89,22 @@ freely, subject to the following restrictions:
|
||||||
/// TinyThread++ version (major number).
|
/// TinyThread++ version (major number).
|
||||||
#define TINYTHREAD_VERSION_MAJOR 1
|
#define TINYTHREAD_VERSION_MAJOR 1
|
||||||
/// TinyThread++ version (minor number).
|
/// TinyThread++ version (minor number).
|
||||||
#define TINYTHREAD_VERSION_MINOR 0
|
#define TINYTHREAD_VERSION_MINOR 1
|
||||||
/// TinyThread++ version (full version).
|
/// TinyThread++ version (full version).
|
||||||
#define TINYTHREAD_VERSION (TINYTHREAD_VERSION_MAJOR * 100 + TINYTHREAD_VERSION_MINOR)
|
#define TINYTHREAD_VERSION (TINYTHREAD_VERSION_MAJOR * 100 + TINYTHREAD_VERSION_MINOR)
|
||||||
|
|
||||||
// Do we have a fully featured C++0x compiler?
|
// Do we have a fully featured C++11 compiler?
|
||||||
#if (__cplusplus > 199711L) || (defined(__STDCXX_VERSION__) && (__STDCXX_VERSION__ >= 201001L))
|
#if (__cplusplus > 199711L) || (defined(__STDCXX_VERSION__) && (__STDCXX_VERSION__ >= 201001L))
|
||||||
#define _TTHREAD_CPP0X_
|
#define _TTHREAD_CPP11_
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ...at least partial C++0x?
|
// ...at least partial C++11?
|
||||||
#if defined(_TTHREAD_CPP0X_) || defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(__GXX_EXPERIMENTAL_CPP0X__)
|
#if defined(_TTHREAD_CPP11_) || defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(__GXX_EXPERIMENTAL_CPP0X__)
|
||||||
#define _TTHREAD_CPP0X_PARTIAL_
|
#define _TTHREAD_CPP11_PARTIAL_
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Macro for disabling assignments of objects.
|
// Macro for disabling assignments of objects.
|
||||||
#ifdef _TTHREAD_CPP0X_PARTIAL_
|
#ifdef _TTHREAD_CPP11_PARTIAL_
|
||||||
#define _TTHREAD_DISABLE_ASSIGNMENT(name) \
|
#define _TTHREAD_DISABLE_ASSIGNMENT(name) \
|
||||||
name(const name&) = delete; \
|
name(const name&) = delete; \
|
||||||
name& operator=(const name&) = delete;
|
name& operator=(const name&) = delete;
|
||||||
|
@ -75,7 +114,28 @@ freely, subject to the following restrictions:
|
||||||
name& operator=(const name&);
|
name& operator=(const name&);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(_TTHREAD_CPP0X_) && !defined(thread_local)
|
/// @def thread_local
|
||||||
|
/// Thread local storage keyword.
|
||||||
|
/// A variable that is declared with the @c thread_local keyword makes the
|
||||||
|
/// value of the variable local to each thread (known as thread-local storage,
|
||||||
|
/// or TLS). Example usage:
|
||||||
|
/// @code
|
||||||
|
/// // This variable is local to each thread.
|
||||||
|
/// thread_local int variable;
|
||||||
|
/// @endcode
|
||||||
|
/// @note The @c thread_local keyword is a macro that maps to the corresponding
|
||||||
|
/// compiler directive (e.g. @c __declspec(thread)). While the C++11 standard
|
||||||
|
/// allows for non-trivial types (e.g. classes with constructors and
|
||||||
|
/// destructors) to be declared with the @c thread_local keyword, most pre-C++11
|
||||||
|
/// compilers only allow for trivial types (e.g. @c int). So, to guarantee
|
||||||
|
/// portable code, only use trivial types for thread local storage.
|
||||||
|
/// @note This directive is currently not supported on Mac OS X (it will give
|
||||||
|
/// a compiler error), since compile-time TLS is not supported in the Mac OS X
|
||||||
|
/// executable format. Also, some older versions of MinGW (before GCC 4.x) do
|
||||||
|
/// not support this directive.
|
||||||
|
/// @hideinitializer
|
||||||
|
|
||||||
|
#if !defined(_TTHREAD_CPP11_) && !defined(thread_local)
|
||||||
#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
|
#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
|
||||||
#define thread_local __thread
|
#define thread_local __thread
|
||||||
#else
|
#else
|
||||||
|
@ -85,8 +145,8 @@ freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
|
||||||
/// Main name space for TinyThread++.
|
/// Main name space for TinyThread++.
|
||||||
/// This namespace is more or less equivalent to the \c std namespace for the
|
/// This namespace is more or less equivalent to the @c std namespace for the
|
||||||
/// C++0x thread classes. For instance, the tthread::mutex class corresponds to
|
/// C++11 thread classes. For instance, the tthread::mutex class corresponds to
|
||||||
/// the std::mutex class.
|
/// the std::mutex class.
|
||||||
namespace tthread {
|
namespace tthread {
|
||||||
|
|
||||||
|
@ -123,7 +183,7 @@ class mutex {
|
||||||
|
|
||||||
/// Lock the mutex.
|
/// Lock the mutex.
|
||||||
/// The method will block the calling thread until a lock on the mutex can
|
/// The method will block the calling thread until a lock on the mutex can
|
||||||
/// be obtained. The mutex remains locked until \c unlock() is called.
|
/// be obtained. The mutex remains locked until @c unlock() is called.
|
||||||
/// @see lock_guard
|
/// @see lock_guard
|
||||||
inline void lock()
|
inline void lock()
|
||||||
{
|
{
|
||||||
|
@ -139,7 +199,7 @@ class mutex {
|
||||||
/// Try to lock the mutex.
|
/// Try to lock the mutex.
|
||||||
/// The method will try to lock the mutex. If it fails, the function will
|
/// The method will try to lock the mutex. If it fails, the function will
|
||||||
/// return immediately (non-blocking).
|
/// return immediately (non-blocking).
|
||||||
/// @return \c true if the lock was acquired, or \c false if the lock could
|
/// @return @c true if the lock was acquired, or @c false if the lock could
|
||||||
/// not be acquired.
|
/// not be acquired.
|
||||||
inline bool try_lock()
|
inline bool try_lock()
|
||||||
{
|
{
|
||||||
|
@ -215,7 +275,7 @@ class recursive_mutex {
|
||||||
|
|
||||||
/// Lock the mutex.
|
/// Lock the mutex.
|
||||||
/// The method will block the calling thread until a lock on the mutex can
|
/// The method will block the calling thread until a lock on the mutex can
|
||||||
/// be obtained. The mutex remains locked until \c unlock() is called.
|
/// be obtained. The mutex remains locked until @c unlock() is called.
|
||||||
/// @see lock_guard
|
/// @see lock_guard
|
||||||
inline void lock()
|
inline void lock()
|
||||||
{
|
{
|
||||||
|
@ -229,7 +289,7 @@ class recursive_mutex {
|
||||||
/// Try to lock the mutex.
|
/// Try to lock the mutex.
|
||||||
/// The method will try to lock the mutex. If it fails, the function will
|
/// The method will try to lock the mutex. If it fails, the function will
|
||||||
/// return immediately (non-blocking).
|
/// return immediately (non-blocking).
|
||||||
/// @return \c true if the lock was acquired, or \c false if the lock could
|
/// @return @c true if the lock was acquired, or @c false if the lock could
|
||||||
/// not be acquired.
|
/// not be acquired.
|
||||||
inline bool try_lock()
|
inline bool try_lock()
|
||||||
{
|
{
|
||||||
|
@ -353,7 +413,7 @@ class condition_variable {
|
||||||
|
|
||||||
/// Wait for the condition.
|
/// Wait for the condition.
|
||||||
/// The function will block the calling thread until the condition variable
|
/// The function will block the calling thread until the condition variable
|
||||||
/// is woken by \c notify_one(), \c notify_all() or a spurious wake up.
|
/// is woken by @c notify_one(), @c notify_all() or a spurious wake up.
|
||||||
/// @param[in] aMutex A mutex that will be unlocked when the wait operation
|
/// @param[in] aMutex A mutex that will be unlocked when the wait operation
|
||||||
/// starts, an locked again as soon as the wait operation is finished.
|
/// starts, an locked again as soon as the wait operation is finished.
|
||||||
template <class _mutexT>
|
template <class _mutexT>
|
||||||
|
@ -429,7 +489,7 @@ class thread {
|
||||||
class id;
|
class id;
|
||||||
|
|
||||||
/// Default constructor.
|
/// Default constructor.
|
||||||
/// Construct a \c thread object without an associated thread of execution
|
/// Construct a @c thread object without an associated thread of execution
|
||||||
/// (i.e. non-joinable).
|
/// (i.e. non-joinable).
|
||||||
thread() : mHandle(0), mNotAThread(true)
|
thread() : mHandle(0), mNotAThread(true)
|
||||||
#if defined(_TTHREAD_WIN32_)
|
#if defined(_TTHREAD_WIN32_)
|
||||||
|
@ -438,7 +498,7 @@ class thread {
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/// Thread starting constructor.
|
/// Thread starting constructor.
|
||||||
/// Construct a \c thread object with a new thread of execution.
|
/// Construct a @c thread object with a new thread of execution.
|
||||||
/// @param[in] aFunction A function pointer to a function of type:
|
/// @param[in] aFunction A function pointer to a function of type:
|
||||||
/// <tt>void fun(void * arg)</tt>
|
/// <tt>void fun(void * arg)</tt>
|
||||||
/// @param[in] aArg Argument to the thread function.
|
/// @param[in] aArg Argument to the thread function.
|
||||||
|
@ -448,24 +508,34 @@ class thread {
|
||||||
thread(void (*aFunction)(void *), void * aArg);
|
thread(void (*aFunction)(void *), void * aArg);
|
||||||
|
|
||||||
/// Destructor.
|
/// Destructor.
|
||||||
/// @note If the thread is joinable upon destruction, \c std::terminate()
|
/// @note If the thread is joinable upon destruction, @c std::terminate()
|
||||||
/// will be called, which terminates the process. It is always wise to do
|
/// will be called, which terminates the process. It is always wise to do
|
||||||
/// \c join() before deleting a thread object.
|
/// @c join() before deleting a thread object.
|
||||||
~thread();
|
~thread();
|
||||||
|
|
||||||
/// Wait for the thread to finish (join execution flows).
|
/// Wait for the thread to finish (join execution flows).
|
||||||
|
/// After calling @c join(), the thread object is no longer associated with
|
||||||
|
/// a thread of execution (i.e. it is not joinable, and you may not join
|
||||||
|
/// with it nor detach from it).
|
||||||
void join();
|
void join();
|
||||||
|
|
||||||
/// Check if the thread is joinable.
|
/// Check if the thread is joinable.
|
||||||
/// A thread object is joinable if it has an associated thread of execution.
|
/// A thread object is joinable if it has an associated thread of execution.
|
||||||
bool joinable() const;
|
bool joinable() const;
|
||||||
|
|
||||||
|
/// Detach from the thread.
|
||||||
|
/// After calling @c detach(), the thread object is no longer assicated with
|
||||||
|
/// a thread of execution (i.e. it is not joinable). The thread continues
|
||||||
|
/// execution without the calling thread blocking, and when the thread
|
||||||
|
/// ends execution, any owned resources are released.
|
||||||
|
void detach();
|
||||||
|
|
||||||
/// Return the thread ID of a thread object.
|
/// Return the thread ID of a thread object.
|
||||||
id get_id() const;
|
id get_id() const;
|
||||||
|
|
||||||
/// Get the native handle for this thread.
|
/// Get the native handle for this thread.
|
||||||
/// @note Under Windows, this is a \c HANDLE, and under POSIX systems, this
|
/// @note Under Windows, this is a @c HANDLE, and under POSIX systems, this
|
||||||
/// is a \c pthread_t.
|
/// is a @c pthread_t.
|
||||||
inline native_handle_type native_handle()
|
inline native_handle_type native_handle()
|
||||||
{
|
{
|
||||||
return mHandle;
|
return mHandle;
|
||||||
|
@ -560,18 +630,18 @@ class thread::id {
|
||||||
// Related to <ratio> - minimal to be able to support chrono.
|
// Related to <ratio> - minimal to be able to support chrono.
|
||||||
typedef long long __intmax_t;
|
typedef long long __intmax_t;
|
||||||
|
|
||||||
/// Minimal implementation of the \c ratio class. This class provides enough
|
/// Minimal implementation of the @c ratio class. This class provides enough
|
||||||
/// functionality to implement some basic \c chrono classes.
|
/// functionality to implement some basic @c chrono classes.
|
||||||
template <__intmax_t N, __intmax_t D = 1> class ratio {
|
template <__intmax_t N, __intmax_t D = 1> class ratio {
|
||||||
public:
|
public:
|
||||||
static double _as_double() { return double(N) / double(D); }
|
static double _as_double() { return double(N) / double(D); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Minimal implementation of the \c chrono namespace.
|
/// Minimal implementation of the @c chrono namespace.
|
||||||
/// The \c chrono namespace provides types for specifying time intervals.
|
/// The @c chrono namespace provides types for specifying time intervals.
|
||||||
namespace chrono {
|
namespace chrono {
|
||||||
/// Duration template class. This class provides enough functionality to
|
/// Duration template class. This class provides enough functionality to
|
||||||
/// implement \c this_thread::sleep_for().
|
/// implement @c this_thread::sleep_for().
|
||||||
template <class _Rep, class _Period = ratio<1> > class duration {
|
template <class _Rep, class _Period = ratio<1> > class duration {
|
||||||
private:
|
private:
|
||||||
_Rep rep_;
|
_Rep rep_;
|
||||||
|
@ -599,7 +669,7 @@ namespace chrono {
|
||||||
typedef duration<__intmax_t, ratio<3600> > hours; ///< Duration with the unit hours.
|
typedef duration<__intmax_t, ratio<3600> > hours; ///< Duration with the unit hours.
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The namespace \c this_thread provides methods for dealing with the
|
/// The namespace @c this_thread provides methods for dealing with the
|
||||||
/// calling thread.
|
/// calling thread.
|
||||||
namespace this_thread {
|
namespace this_thread {
|
||||||
/// Return the thread ID of the calling thread.
|
/// Return the thread ID of the calling thread.
|
||||||
|
|
Loading…
Add table
Reference in a new issue