You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
181 lines
4.8 KiB
C++
181 lines
4.8 KiB
C++
// 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_
|
|
|