// Copyright (C) 2003 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #ifndef DLIB_THREADS_KERNEl_2_ #define DLIB_THREADS_KERNEl_2_ #ifdef DLIB_ISO_CPP_ONLY #error "DLIB_ISO_CPP_ONLY is defined so you can't use this OS dependent code. Turn DLIB_ISO_CPP_ONLY off if you want to use it." #endif #include "threads_kernel_abstract.h" #include <pthread.h> #include <errno.h> #include <sys/time.h> #include "../algs.h" namespace dlib { // ---------------------------------------------------------------------------------------- typedef pthread_t thread_id_type; inline thread_id_type get_thread_id ( ) { return pthread_self(); } // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- // mutex object // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- // forward declaration of signaler class signaler; class mutex { // give signaler access to hMutex friend class signaler; public: mutex ( ) { if (pthread_mutex_init(&myMutex,0)) { throw dlib::thread_error(ECREATE_MUTEX, "in function mutex::mutex() an error occurred making the mutex" ); } } ~mutex ( ) { pthread_mutex_destroy(&myMutex); } void lock ( ) const { pthread_mutex_lock(&myMutex); } void unlock ( ) const { pthread_mutex_unlock(&myMutex); } private: mutable pthread_mutex_t myMutex; // restricted functions mutex(mutex&); // copy constructor mutex& operator=(mutex&); // assignement opertor }; // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- // signaler object // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- class signaler { public: signaler ( const mutex& assoc_mutex ) : associated_mutex(&assoc_mutex.myMutex), m(assoc_mutex) { if (pthread_cond_init(&cond,0)) { throw dlib::thread_error(ECREATE_SIGNALER, "in function signaler::signaler() an error occurred making the signaler" ); } } ~signaler ( ) { pthread_cond_destroy(&cond); } void wait ( ) const { pthread_cond_wait(&cond,associated_mutex); } bool wait_or_timeout ( unsigned long milliseconds ) const { timespec time_to_wait; timeval curtime; gettimeofday(&curtime,0); // get the time and adjust the timespec object by the appropriate amount time_to_wait.tv_sec = milliseconds/1000 + curtime.tv_sec; time_to_wait.tv_nsec = curtime.tv_usec; time_to_wait.tv_nsec *= 1000; time_to_wait.tv_nsec += (milliseconds%1000)*1000000; time_to_wait.tv_sec += time_to_wait.tv_nsec/1000000000; time_to_wait.tv_nsec = time_to_wait.tv_nsec%1000000000; if ( pthread_cond_timedwait(&cond,associated_mutex,&time_to_wait) == ETIMEDOUT) { return false; } else { return true; } } void signal ( ) const { pthread_cond_signal(&cond); } void broadcast ( ) const { pthread_cond_broadcast(&cond); } const mutex& get_mutex ( ) const { return m; } private: pthread_mutex_t* const associated_mutex; mutable pthread_cond_t cond; const mutex& m; // restricted functions signaler(signaler&); // copy constructor signaler& operator=(signaler&); // assignement opertor }; // ---------------------------------------------------------------------------------------- namespace threads_kernel_shared_helpers { bool spawn_thread ( void (*funct)(void*), void* param ); /*! is identical to create_new_thread() but just doesn't use any thread pooling. !*/ } // ---------------------------------------------------------------------------------------- } #include "threads_kernel_shared.h" #ifdef NO_MAKEFILE #include "threads_kernel_2.cpp" #endif #endif // DLIB_THREADS_KERNEl_2_