diff options
Diffstat (limited to 'src/3rd_party-static/message_broker/include/system.h')
-rw-r--r-- | src/3rd_party-static/message_broker/include/system.h | 320 |
1 files changed, 320 insertions, 0 deletions
diff --git a/src/3rd_party-static/message_broker/include/system.h b/src/3rd_party-static/message_broker/include/system.h new file mode 100644 index 0000000000..fac4f7926b --- /dev/null +++ b/src/3rd_party-static/message_broker/include/system.h @@ -0,0 +1,320 @@ +/** + * \file system.h + * \brief System utils. + * \author Sebastien Vincent + */ + +#ifndef SYSTEM_H +#define SYSTEM_H + +#ifdef _WIN32 + +#include <windows.h> + +#else + +#include <pthread.h> + +#endif + +/** + * \namespace System + * \brief System related class (thread, ...). + */ +namespace System +{ + + /** + * \brief Sleep for x milliseconds + * \param ms millisecond to sleep + */ + void msleep(unsigned long ms); + + /** + * \class ThreadArg + * \brief Abstract class to represent thread argument. + * \see ThreadArgImpl + * \see Thread + */ + class ThreadArg + { + public: + /** + * \brief Destructor. + */ + virtual ~ThreadArg(); + + /** + * \brief Call the method. + * \note Have to be implemented by subclasses + */ + virtual void* Call() = 0; + }; + + /** + * \class ThreadArgImpl + * \brief Template class that represent thread argument. + * + * This class is used to provide callback function within + * an object. The method which will be called during thread + * execution must be of the form <code>void* MyMethod(void* arg)</code>. + * Inside this method you are free to called any method of the object. + * + * \warning As class keep pointer of object reference, you should take + * care at the lifetime of object you pass in ThreadArgImpl constructor, + * else it could lead to crash your program.\n See Thread class documentation + * for an example of how to use ThreadArgImpl class. + * \see Thread + */ + template<class T> class ThreadArgImpl : public ThreadArg + { + public: + /** + * \typedef Method + * \brief T method signature. + */ + typedef void* (T::*Method)(void*); + + /** + * \brief Constructor. + * \param obj object + * \param method class method + * \param arg argument to method + */ + ThreadArgImpl(T& obj, Method method, void* arg) + { + m_obj = &obj; + m_method = method; + m_arg = arg; + } + + /** + * \brief Call the method. + */ + virtual void* Call() + { + return (m_obj->*m_method)(m_arg); + } + + private: + /** + * \brief Object pointer. + */ + T* m_obj; + + /** + * \brief Method of T class. + */ + Method m_method; + + /** + * \brief Argument of method. + */ + void* m_arg; + }; + + /** + * \class Thread + * \brief Thread implementation. + * + * Preferred use of this class is to construct ThreadArgImpl inside + * another class and pass <code>*this</code> as obj parameter:\n + * \n + * \code + * class MyClass + * { + * public: + * void MyMethod() + * { + * ThreadArg* arg = new ThreadArgImpl<MyClass>(*this, &MyClass::MethodForThread, NULL); + * Thread th(arg); + * th.Start(); + * } + * + * void* MethodForThread(void * arg) + * { + * // do stuff + * } + * }; + * \endcode + * + */ + class Thread + { + public: + /** + * \brief Constructor. + * \param arg thread argument (MUST be dynamically allocated using new) + * \note System::Thread object takes care of freeing method memory.\n + * The way of calling constructor is: + * <code> + * Thread thread(new ThreadArgImpl<MyClass>(instanceOfMyClass, &MyClass::Method)); + * </code> + * \warning You should take care of the object (instanceOfMyClass) lifetime pass + * into ThreadArgImpl constructor, else it could lead to a crash because ThreadArgImpl + * keep pointer of the reference. + * \warning The "arg" parameter MUST be dynamically allocated (using new). + * \see ThreadArgImpl + */ + Thread(ThreadArg* arg); + + /** + * \brief Destructor. + */ + virtual ~Thread(); + + /** + * \brief Start thread. + * \param detach if set to true, the thread will be in detach state so + * you do not have to call join on this type of thread. + * \return true if success, false otherwise + * \warning Do NOT <code>Join</code> a detached thread. + */ + bool Start(bool detach); + + /** + * \brief Stop thread. + * \return true if success, false otherwise + * \warning Calling this method could lead callback object to an + * incoherent state. You should call it really in desperate situations when + * you really want to stop thread and do not care about the rest. + * \warning With POSIX thread implementation, calling Stop (one or more times) + * will leak 28 bytes of memory. + */ + bool Stop(); + + /** + * \brief Join thread. + * \param ret pointer to return code of the joined thread + * \return true if success, false otherwise + * \warning Do NOT <code>Join</code> a detached thread. + */ + bool Join(void** ret = NULL); + +#ifdef _WIN32 + HANDLE +#else + pthread_t +#endif + GetId() const { + return m_id; + } + + private: + /** + * \brief Entry point of thread before calling specific + * callback. + * \param arg thread argument + * \return result of ThreadArg callback + */ +#ifdef _WIN32 + static DWORD WINAPI Call(LPVOID arg); +#else + static void* Call(void* arg); +#endif + /** + * \brief Thread identifier. + */ +#ifdef _WIN32 /* Win32 thread */ + HANDLE m_id; +#else /* POSIX thread */ + pthread_t m_id; +#endif + + /** + * \brief Thread argument. + */ + ThreadArg* m_arg; + }; + + /** + * \class Mutex + * \brief Mutex implementation. + */ + class Mutex + { + public: + /** + * \brief Constructor. + */ + Mutex(); + + /** + * \brief Destructor. + */ + ~Mutex(); + + /** + * \brief Lock the mutex. + * \return true if mutex is locked, false if error + */ + bool Lock(); + + /** + * \brief Unlock the mutex. + * \return true if mutex is unlocked, false if error + */ + bool Unlock(); + + private: + /** + * \brief The mutex. + */ +#ifdef _WIN32 + HANDLE m_mutex; +#else + pthread_mutex_t m_mutex; +#endif + }; + +#ifdef _WIN32 +#warning "BinarySemaphore is implemented for POSIX systems only" +#else + /** + * \class BinarySemaphore + * \brief Binary semaphore implementation. + */ + class BinarySemaphore { + public: + /** + * \brief Constructor. + */ + BinarySemaphore(); + + /** + * \brief Destructor. + */ + ~BinarySemaphore(); + + /** + * \brief Wait until the semaphore is unlocked. + */ + void Wait(); + + /** + * \brief Notify the semaphore. + */ + void Notify(); + + private: + /** + * \brief Mutex to prevent concurrent access to the flag. + */ + pthread_mutex_t m_mutex; + + /** + * \brief Conditional variable to block threads. + */ + pthread_cond_t m_cond; + + /** + * \brief Semaphore state: false = down, true = up. + */ + bool m_isUp; + }; +#endif /* _WIN32 */ + +} /* namespace System */ + +#endif /* SYSTEM_H */ + |