Added boost header

This commit is contained in:
Christophe Riccio
2012-01-08 01:26:07 +00:00
parent 9c3faaca40
commit c7d752cdf8
8946 changed files with 1732316 additions and 0 deletions

View File

@@ -0,0 +1,45 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include<boost/interprocess/exceptions.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/assert.hpp>
namespace boost {
namespace interprocess {
inline barrier::barrier(unsigned int count)
{
if (count == 0)
throw std::invalid_argument("count cannot be zero.");
ipcdetail::barrierattr_wrapper barrier_attr;
ipcdetail::barrier_initializer barrier
(m_barrier, barrier_attr, static_cast<int>(count));
barrier.release();
}
inline barrier::~barrier()
{
int res = pthread_barrier_destroy(&m_barrier);
BOOST_ASSERT(res == 0);(void)res;
}
inline bool barrier::wait()
{
int res = pthread_barrier_wait(&m_barrier);
if (res != PTHREAD_BARRIER_SERIAL_THREAD && res != 0){
throw interprocess_exception(res);
}
return res == PTHREAD_BARRIER_SERIAL_THREAD;
}
} //namespace interprocess {
} //namespace boost {

View File

@@ -0,0 +1,82 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/interprocess/sync/posix/ptime_to_timespec.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/assert.hpp>
namespace boost {
namespace interprocess {
inline interprocess_condition::interprocess_condition()
{
int res;
pthread_condattr_t cond_attr;
res = pthread_condattr_init(&cond_attr);
if(res != 0){
throw interprocess_exception("pthread_condattr_init failed");
}
res = pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED);
if(res != 0){
pthread_condattr_destroy(&cond_attr);
throw interprocess_exception(res);
}
res = pthread_cond_init(&m_condition, &cond_attr);
pthread_condattr_destroy(&cond_attr);
if(res != 0){
throw interprocess_exception(res);
}
}
inline interprocess_condition::~interprocess_condition()
{
int res = 0;
res = pthread_cond_destroy(&m_condition);
BOOST_ASSERT(res == 0);
}
inline void interprocess_condition::notify_one()
{
int res = 0;
res = pthread_cond_signal(&m_condition);
BOOST_ASSERT(res == 0);
}
inline void interprocess_condition::notify_all()
{
int res = 0;
res = pthread_cond_broadcast(&m_condition);
BOOST_ASSERT(res == 0);
}
inline void interprocess_condition::do_wait(interprocess_mutex &mut)
{
pthread_mutex_t* pmutex = &mut.m_mut;
int res = 0;
res = pthread_cond_wait(&m_condition, pmutex);
BOOST_ASSERT(res == 0);
}
inline bool interprocess_condition::do_timed_wait
(const boost::posix_time::ptime &abs_time, interprocess_mutex &mut)
{
timespec ts = ipcdetail::ptime_to_timespec(abs_time);
pthread_mutex_t* pmutex = &mut.m_mut;
int res = 0;
res = pthread_cond_timedwait(&m_condition, pmutex, &ts);
BOOST_ASSERT(res == 0 || res == ETIMEDOUT);
return res != ETIMEDOUT;
}
} //namespace interprocess
} // namespace boost

View File

@@ -0,0 +1,122 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
//
// Parts of the pthread code come from Boost Threads code:
//
//////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2003
// William E. Kempf
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
//////////////////////////////////////////////////////////////////////////////
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/sync/posix/ptime_to_timespec.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/exceptions.hpp>
#ifndef BOOST_INTERPROCESS_POSIX_TIMEOUTS
# include <boost/interprocess/detail/os_thread_functions.hpp>
#endif
#include <boost/assert.hpp>
namespace boost {
namespace interprocess {
inline interprocess_mutex::interprocess_mutex()
{
ipcdetail::mutexattr_wrapper mut_attr;
ipcdetail::mutex_initializer mut(m_mut, mut_attr);
mut.release();
}
inline interprocess_mutex::~interprocess_mutex()
{
int res = pthread_mutex_destroy(&m_mut);
BOOST_ASSERT(res == 0);(void)res;
}
inline void interprocess_mutex::lock()
{
#ifdef BOOST_INTERPROCESS_ENABLE_TIMEOUT_WHEN_LOCKING
boost::posix_time::ptime wait_time
= boost::posix_time::microsec_clock::universal_time()
+ boost::posix_time::milliseconds(BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS);
if (!timed_lock(wait_time))
{
throw interprocess_exception(timeout_when_locking_error, "Interprocess mutex timeout when locking. Possible deadlock: owner died without unlocking?");
}
#else
if (pthread_mutex_lock(&m_mut) != 0)
throw lock_exception();
#endif
}
inline bool interprocess_mutex::try_lock()
{
int res = pthread_mutex_trylock(&m_mut);
if (!(res == 0 || res == EBUSY))
throw lock_exception();
return res == 0;
}
inline bool interprocess_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
{
if(abs_time == boost::posix_time::pos_infin){
this->lock();
return true;
}
#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
timespec ts = ipcdetail::ptime_to_timespec(abs_time);
int res = pthread_mutex_timedlock(&m_mut, &ts);
if (res != 0 && res != ETIMEDOUT)
throw lock_exception();
return res == 0;
#else //BOOST_INTERPROCESS_POSIX_TIMEOUTS
//Obtain current count and target time
boost::posix_time::ptime now = microsec_clock::universal_time();
if(now >= abs_time) return false;
do{
if(this->try_lock()){
break;
}
now = microsec_clock::universal_time();
if(now >= abs_time){
return false;
}
// relinquish current time slice
ipcdetail::thread_yield();
}while (true);
return true;
#endif //BOOST_INTERPROCESS_POSIX_TIMEOUTS
}
inline void interprocess_mutex::unlock()
{
int res = 0;
res = pthread_mutex_unlock(&m_mut);
BOOST_ASSERT(res == 0);
}
} //namespace interprocess {
} //namespace boost {

View File

@@ -0,0 +1,122 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
//
// Parts of the pthread code come from Boost Threads code:
//
//////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2003
// William E. Kempf
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
//////////////////////////////////////////////////////////////////////////////
#include <boost/interprocess/sync/posix/ptime_to_timespec.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/exceptions.hpp>
#ifndef BOOST_INTERPROCESS_POSIX_TIMEOUTS
# include <boost/interprocess/detail/os_thread_functions.hpp>
#endif
#include <boost/assert.hpp>
namespace boost {
namespace interprocess {
inline interprocess_recursive_mutex::interprocess_recursive_mutex()
{
ipcdetail::mutexattr_wrapper mut_attr(true);
ipcdetail::mutex_initializer mut(m_mut, mut_attr);
mut.release();
}
inline interprocess_recursive_mutex::~interprocess_recursive_mutex()
{
int res = pthread_mutex_destroy(&m_mut);
BOOST_ASSERT(res == 0);(void)res;
}
inline void interprocess_recursive_mutex::lock()
{
#ifdef BOOST_INTERPROCESS_ENABLE_TIMEOUT_WHEN_LOCKING
boost::posix_time::ptime wait_time
= boost::posix_time::microsec_clock::universal_time()
+ boost::posix_time::milliseconds(BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS);
if (!timed_lock(wait_time))
{
throw interprocess_exception(timeout_when_locking_error, "Interprocess mutex timeout when locking. Possible deadlock: owner died without unlocking?");
}
#else
if (pthread_mutex_lock(&m_mut) != 0)
throw lock_exception();
#endif
}
inline bool interprocess_recursive_mutex::try_lock()
{
int res = pthread_mutex_trylock(&m_mut);
if (!(res == 0 || res == EBUSY))
throw lock_exception();
return res == 0;
}
inline bool interprocess_recursive_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
{
if(abs_time == boost::posix_time::pos_infin){
this->lock();
return true;
}
#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
timespec ts = ipcdetail::ptime_to_timespec(abs_time);
int res = pthread_mutex_timedlock(&m_mut, &ts);
if (res != 0 && res != ETIMEDOUT)
throw lock_exception();
return res == 0;
#else //BOOST_INTERPROCESS_POSIX_TIMEOUTS
//Obtain current count and target time
boost::posix_time::ptime now = microsec_clock::universal_time();
if(now >= abs_time) return false;
do{
if(this->try_lock()){
break;
}
now = microsec_clock::universal_time();
if(now >= abs_time){
return false;
}
// relinquish current time slice
ipcdetail::thread_yield();
}while (true);
return true;
#endif //BOOST_INTERPROCESS_POSIX_TIMEOUTS
}
inline void interprocess_recursive_mutex::unlock()
{
int res = 0;
res = pthread_mutex_unlock(&m_mut);
BOOST_ASSERT(res == 0);
}
} //namespace interprocess {
} //namespace boost {

View File

@@ -0,0 +1,49 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/interprocess/sync/posix/ptime_to_timespec.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
namespace boost {
namespace interprocess {
inline interprocess_semaphore::~interprocess_semaphore()
{}
inline interprocess_semaphore::interprocess_semaphore(unsigned int initialCount)
: m_sem(initialCount)
{}
inline void interprocess_semaphore::post()
{ m_sem.post(); }
inline void interprocess_semaphore::wait()
{ m_sem.wait(); }
inline bool interprocess_semaphore::try_wait()
{ return m_sem.try_wait(); }
inline bool interprocess_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
{
if(abs_time == boost::posix_time::pos_infin){
this->wait();
return true;
}
return m_sem.timed_wait(abs_time);
}
/*
inline int interprocess_semaphore::get_count() const
{ return m_sem.get_count(); }
*/
} //namespace interprocess {
} //namespace boost {

View File

@@ -0,0 +1,168 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTERPROCESS_PTHREAD_HELPERS_HPP
#define BOOST_INTERPROCESS_PTHREAD_HELPERS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <pthread.h>
#include <errno.h>
#include <boost/interprocess/exceptions.hpp>
namespace boost {
namespace interprocess {
namespace ipcdetail{
#if defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
//!Makes pthread_mutexattr_t cleanup easy when using exceptions
struct mutexattr_wrapper
{
//!Constructor
mutexattr_wrapper(bool recursive = false)
{
if(pthread_mutexattr_init(&m_attr)!=0 ||
pthread_mutexattr_setpshared(&m_attr, PTHREAD_PROCESS_SHARED)!= 0 ||
(recursive &&
pthread_mutexattr_settype(&m_attr, PTHREAD_MUTEX_RECURSIVE)!= 0 ))
throw interprocess_exception("pthread_mutexattr_xxxx failed");
}
//!Destructor
~mutexattr_wrapper() { pthread_mutexattr_destroy(&m_attr); }
//!This allows using mutexattr_wrapper as pthread_mutexattr_t
operator pthread_mutexattr_t&() { return m_attr; }
pthread_mutexattr_t m_attr;
};
//!Makes pthread_condattr_t cleanup easy when using exceptions
struct condattr_wrapper
{
//!Constructor
condattr_wrapper()
{
if(pthread_condattr_init(&m_attr)!=0 ||
pthread_condattr_setpshared(&m_attr, PTHREAD_PROCESS_SHARED)!= 0)
throw interprocess_exception("pthread_condattr_xxxx failed");
}
//!Destructor
~condattr_wrapper() { pthread_condattr_destroy(&m_attr); }
//!This allows using condattr_wrapper as pthread_condattr_t
operator pthread_condattr_t&(){ return m_attr; }
pthread_condattr_t m_attr;
};
//!Makes initialized pthread_mutex_t cleanup easy when using exceptions
class mutex_initializer
{
public:
//!Constructor. Takes interprocess_mutex attributes to initialize the interprocess_mutex
mutex_initializer(pthread_mutex_t &mut, pthread_mutexattr_t &mut_attr)
: mp_mut(&mut)
{
if(pthread_mutex_init(mp_mut, &mut_attr) != 0)
throw interprocess_exception("pthread_mutex_init failed");
}
~mutex_initializer() { if(mp_mut) pthread_mutex_destroy(mp_mut); }
void release() {mp_mut = 0; }
private:
pthread_mutex_t *mp_mut;
};
//!Makes initialized pthread_cond_t cleanup easy when using exceptions
class condition_initializer
{
public:
condition_initializer(pthread_cond_t &cond, pthread_condattr_t &cond_attr)
: mp_cond(&cond)
{
if(pthread_cond_init(mp_cond, &cond_attr)!= 0)
throw interprocess_exception("pthread_cond_init failed");
}
~condition_initializer() { if(mp_cond) pthread_cond_destroy(mp_cond); }
void release() { mp_cond = 0; }
private:
pthread_cond_t *mp_cond;
};
#endif // #if defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
#if defined(BOOST_INTERPROCESS_POSIX_BARRIERS) && defined(BOOST_INTERPROCESS_POSIX_PROCESS_SHARED)
//!Makes pthread_barrierattr_t cleanup easy when using exceptions
struct barrierattr_wrapper
{
//!Constructor
barrierattr_wrapper()
{
if(pthread_barrierattr_init(&m_attr)!=0 ||
pthread_barrierattr_setpshared(&m_attr, PTHREAD_PROCESS_SHARED)!= 0)
throw interprocess_exception("pthread_barrierattr_xxx failed");
}
//!Destructor
~barrierattr_wrapper() { pthread_barrierattr_destroy(&m_attr); }
//!This allows using mutexattr_wrapper as pthread_barrierattr_t
operator pthread_barrierattr_t&() { return m_attr; }
pthread_barrierattr_t m_attr;
};
//!Makes initialized pthread_barrier_t cleanup easy when using exceptions
class barrier_initializer
{
public:
//!Constructor. Takes barrier attributes to initialize the barrier
barrier_initializer(pthread_barrier_t &mut,
pthread_barrierattr_t &mut_attr,
int count)
: mp_barrier(&mut)
{
if(pthread_barrier_init(mp_barrier, &mut_attr, count) != 0)
throw interprocess_exception("pthread_barrier_init failed");
}
~barrier_initializer() { if(mp_barrier) pthread_barrier_destroy(mp_barrier); }
void release() {mp_barrier = 0; }
private:
pthread_barrier_t *mp_barrier;
};
#endif //#if defined(BOOST_INTERPROCESS_POSIX_BARRIERS) && defined(BOOST_INTERPROCESS_POSIX_PROCESS_SHARED)
}//namespace ipcdetail
}//namespace interprocess
}//namespace boost
#include <boost/interprocess/detail/config_end.hpp>
#endif //ifdef BOOST_INTERPROCESS_PTHREAD_HELPERS_HPP

View File

@@ -0,0 +1,38 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTERPROCESS_DETAIL_PTIME_TO_TIMESPEC_HPP
#define BOOST_INTERPROCESS_DETAIL_PTIME_TO_TIMESPEC_HPP
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
namespace boost {
namespace interprocess {
namespace ipcdetail {
inline timespec ptime_to_timespec (const boost::posix_time::ptime &tm)
{
const boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
boost::posix_time::time_duration duration (tm - epoch);
timespec ts;
ts.tv_sec = duration.total_seconds();
ts.tv_nsec = duration.total_nanoseconds() % 1000000000;
return ts;
}
} //namespace ipcdetail {
} //namespace interprocess {
} //namespace boost {
#endif //ifndef BOOST_INTERPROCESS_DETAIL_PTIME_TO_TIMESPEC_HPP

View File

@@ -0,0 +1,265 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTERPROCESS_POSIX_SEMAPHORE_WRAPPER_HPP
#define BOOST_INTERPROCESS_POSIX_SEMAPHORE_WRAPPER_HPP
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/creation_tags.hpp>
#include <boost/interprocess/detail/os_file_functions.hpp>
#include <boost/interprocess/detail/tmp_dir_helpers.hpp>
#include <boost/interprocess/permissions.hpp>
#include <string>
#include <semaphore.h>
#include <boost/assert.hpp>
#ifdef SEM_FAILED
#define BOOST_INTERPROCESS_POSIX_SEM_FAILED (reinterpret_cast<sem_t*>(SEM_FAILED))
#else
#define BOOST_INTERPROCESS_POSIX_SEM_FAILED (reinterpret_cast<sem_t*>(-1))
#endif
#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
#include <boost/interprocess/sync/posix/ptime_to_timespec.hpp>
#else
#include <boost/interprocess/detail/os_thread_functions.hpp>
#endif
namespace boost {
namespace interprocess {
/// @cond
namespace ipcdetail{ class interprocess_tester; }
/// @endcond
namespace ipcdetail {
inline bool semaphore_open
(sem_t *&handle, ipcdetail::create_enum_t type, const char *origname,
unsigned int count, const permissions &perm = permissions())
{
std::string name;
#ifndef BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES
ipcdetail::add_leading_slash(origname, name);
#else
ipcdetail::create_tmp_and_clean_old_and_get_filename(origname, name);
#endif
//Create new mapping
int oflag = 0;
switch(type){
case ipcdetail::DoOpen:
//No addition
break;
case ipcdetail::DoCreate:
oflag |= (O_CREAT | O_EXCL);
break;
case ipcdetail::DoOpenOrCreate:
oflag |= O_CREAT;
break;
default:
{
error_info err = other_error;
throw interprocess_exception(err);
}
}
//Open file using POSIX API
if(oflag & O_CREAT)
handle = sem_open(name.c_str(), oflag, perm.get_permissions(), count);
else
handle = sem_open(name.c_str(), oflag);
//Check for error
if(handle == BOOST_INTERPROCESS_POSIX_SEM_FAILED){
throw interprocess_exception(error_info(errno));
}
return true;
}
inline void semaphore_close(sem_t *handle)
{
int ret = sem_close(handle);
if(ret != 0){
BOOST_ASSERT(0);
}
}
inline bool semaphore_unlink(const char *semname)
{
try{
std::string sem_str;
#ifndef BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES
ipcdetail::add_leading_slash(semname, sem_str);
#else
ipcdetail::tmp_filename(semname, sem_str);
#endif
return 0 == sem_unlink(sem_str.c_str());
}
catch(...){
return false;
}
}
inline void semaphore_init(sem_t *handle, unsigned int initialCount)
{
int ret = sem_init(handle, 1, initialCount);
//According to SUSV3 version 2003 edition, the return value of a successful
//sem_init call is not defined, but -1 is returned on failure.
//In the future, a successful call might be required to return 0.
if(ret == -1){
throw interprocess_exception(system_error_code());
}
}
inline void semaphore_destroy(sem_t *handle)
{
int ret = sem_destroy(handle);
if(ret != 0){
BOOST_ASSERT(0);
}
}
inline void semaphore_post(sem_t *handle)
{
int ret = sem_post(handle);
if(ret != 0){
throw interprocess_exception(system_error_code());
}
}
inline void semaphore_wait(sem_t *handle)
{
int ret = sem_wait(handle);
if(ret != 0){
throw interprocess_exception(system_error_code());
}
}
inline bool semaphore_try_wait(sem_t *handle)
{
int res = sem_trywait(handle);
if(res == 0)
return true;
if(system_error_code() == EAGAIN){
return false;
}
throw interprocess_exception(system_error_code());
return false;
}
inline bool semaphore_timed_wait(sem_t *handle, const boost::posix_time::ptime &abs_time)
{
#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
timespec tspec = ipcdetail::ptime_to_timespec(abs_time);
for (;;){
int res = sem_timedwait(handle, &tspec);
if(res == 0)
return true;
if (res > 0){
//buggy glibc, copy the returned error code to errno
errno = res;
}
if(system_error_code() == ETIMEDOUT){
return false;
}
throw interprocess_exception(system_error_code());
}
return false;
#else //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
boost::posix_time::ptime now;
while((now = microsec_clock::universal_time()) < abs_time){
if(semaphore_try_wait(handle))
return true;
thread_yield();
}
return false;
#endif //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
}
class named_semaphore_wrapper
{
named_semaphore_wrapper();
named_semaphore_wrapper(const named_semaphore_wrapper&);
named_semaphore_wrapper &operator= (const named_semaphore_wrapper &);
public:
named_semaphore_wrapper
(ipcdetail::create_enum_t type, const char *name, unsigned int count, const permissions &perm = permissions())
{ semaphore_open(mp_sem, type, name, count, perm); }
~named_semaphore_wrapper()
{
if(mp_sem != BOOST_INTERPROCESS_POSIX_SEM_FAILED)
semaphore_close(mp_sem);
}
void post()
{ semaphore_post(mp_sem); }
void wait()
{ semaphore_wait(mp_sem); }
bool try_wait()
{ return semaphore_try_wait(mp_sem); }
bool timed_wait(const boost::posix_time::ptime &abs_time)
{ return semaphore_timed_wait(mp_sem, abs_time); }
static bool remove(const char *name)
{ return semaphore_unlink(name); }
private:
friend class ipcdetail::interprocess_tester;
void dont_close_on_destruction()
{ mp_sem = BOOST_INTERPROCESS_POSIX_SEM_FAILED; }
sem_t *mp_sem;
};
class semaphore_wrapper
{
semaphore_wrapper();
semaphore_wrapper(const semaphore_wrapper&);
semaphore_wrapper &operator= (const semaphore_wrapper &);
public:
semaphore_wrapper(unsigned int initialCount)
{ semaphore_init(&m_sem, initialCount); }
~semaphore_wrapper()
{ semaphore_destroy(&m_sem); }
void post()
{ semaphore_post(&m_sem); }
void wait()
{ semaphore_wait(&m_sem); }
bool try_wait()
{ return semaphore_try_wait(&m_sem); }
bool timed_wait(const boost::posix_time::ptime &abs_time)
{ return semaphore_timed_wait(&m_sem, abs_time); }
private:
sem_t m_sem;
};
} //namespace ipcdetail {
} //namespace interprocess {
} //namespace boost {
#undef BOOST_INTERPROCESS_POSIX_SEM_FAILED
#endif //#ifndef BOOST_INTERPROCESS_POSIX_SEMAPHORE_WRAPPER_HPP