1
0
mirror of https://github.com/stefanocasazza/ULib.git synced 2025-09-28 19:05:55 +08:00
ULib/include/ulib/thread.h
2015-01-23 17:24:36 +01:00

199 lines
4.4 KiB
C++

// ============================================================================
//
// = LIBRARY
// ULib - c++ library
//
// = FILENAME
// thread.h
//
// = AUTHOR
// Stefano Casazza
//
// ============================================================================
#ifndef ULIB_THREAD_H
#define ULIB_THREAD_H
#include <ulib/internal/common.h>
#define U_SIGSTOP (SIGRTMIN+5)
#define U_SIGCONT (SIGRTMIN+6)
#ifdef _MSWINDOWS_
#undef signal
#undef sleep
#endif
class U_EXPORT UThread {
public:
// Check for memory error
U_MEMORY_TEST
// Allocator e Deallocator
U_MEMORY_ALLOCATOR
U_MEMORY_DEALLOCATOR
enum Cancel {
cancelInitial, /* used internally, do not use */
cancelDeferred, /* exit thread on cancellation pointsuch as yield */
cancelImmediate, /* exit befor cancellation */
cancelDisabled /* ignore cancellation */
};
// COSTRUTTORI
UThread(bool suspendEnable = false, bool joinEnable = true);
virtual ~UThread();
// SERVICES
void lock()
{
U_TRACE(1, "UThread::lock()")
(void) U_SYSCALL(pthread_mutex_lock, "%p", &_lock);
}
void unlock()
{
U_TRACE(1, "UThread::unlock()")
(void) U_SYSCALL(pthread_mutex_unlock, "%p", &_lock);
}
static pid_t getTID();
static void sleep(time_t timeoutMS);
/**
* All threads execute by deriving the run method of UThread.
* This method is called after initial to begin normal operation
* of the thread. If the method terminates, then the thread will
* also terminate.
*/
virtual void run()
{
U_TRACE(0, "UThread::run()")
}
/**
* When a new thread is created, it does not begin immediate
* execution. This is because the derived class virtual tables
* are not properly loaded at the time the C++ object is created
* within the constructor itself, at least in some compiler/system
* combinations. It can be started directly after the constructor
* completes by calling the start() method.
*
* @return false if execution fails.
*/
void stop();
bool start(uint32_t timeoutMS = 0);
/**
* Start a new thread as "detached". This is an alternative
* start() method that resolves some issues with later glibc
* implimentations which incorrectly impliment self-detach.
*
* @return false if execution fails.
*/
bool detach();
/**
* Yields the current thread's CPU time slice to allow another thread to
* begin immediate execution.
*/
void yield();
/**
* Suspends execution of the selected thread. Pthreads do not
* normally support suspendable threads, so the behavior is
* simulated with signals.
*/
void suspend();
/**
* Resumes execution of the selected thread.
*/
void resume();
/**
* Check if this thread is detached.
*
* @return true if the thread is detached.
*/
bool isDetached() const;
/**
* Each time a thread receives a signal, it stores the
* signal number locally.
*/
void signal(int signo);
// Cancellation
void setCancel(int mode);
/**
* This is used to help build wrapper functions in libraries
* around system calls that should behave as cancellation
* points but don't.
*
* @return saved cancel type.
*/
int enterCancel();
/**
* This is used to restore a cancel block.
*
* @param cancel type that was saved.
*/
void exitCancel(int cancel);
#if defined(U_STDCPP_ENABLE) && defined(DEBUG)
const char* dump(bool reset) const;
#endif
protected:
UThread* next;
static UThread* first;
static pthread_cond_t cond;
static pthread_mutex_t _lock;
void close(); // close current thread, free all
void sigInstall(int signo);
static void sigHandler(int signo);
static void execHandler(UThread* th);
static void threadCleanup(UThread* th);
// A special global function, getThread(), is provided to identify the thread object that represents the current
// execution context you are running under. This is sometimes needed to deliver signals to the correct thread.
static UThread* getThread() __pure;
private:
// private data
class UThreadImpl* priv;
friend class UThreadImpl;
#ifdef U_COMPILER_DELETE_MEMBERS
UThread(const UThread&) = delete;
UThread& operator=(const UThread&) = delete;
#else
UThread(const UThread&) {}
UThread& operator=(const UThread&) { return *this; }
#endif
};
#endif