stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork

This commit is contained in:
2026-02-24 18:38:47 +00:00
parent da8c28aaeb
commit 65cb2619a7
13106 changed files with 2484322 additions and 1804 deletions
@@ -0,0 +1,196 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. 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_CONDITION_HPP
#define BOOST_INTERPROCESS_POSIX_CONDITION_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#
#if defined(BOOST_HAS_PRAGMA_ONCE)
# 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/sync/posix/pthread_helpers.hpp>
#include <boost/interprocess/sync/posix/ptime_to_timespec.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/sync/posix/mutex.hpp>
#include <boost/assert.hpp>
namespace boost {
namespace interprocess {
namespace ipcdetail {
class posix_condition
{
//Non-copyable
posix_condition(const posix_condition &);
posix_condition &operator=(const posix_condition &);
public:
//!Constructs a posix_condition. On error throws interprocess_exception.
posix_condition();
//!Destroys *this
//!liberating system resources.
~posix_condition();
//!If there is a thread waiting on *this, change that
//!thread's state to ready. Otherwise there is no effect.
void notify_one();
//!Change the state of all threads waiting on *this to ready.
//!If there are no waiting threads, notify_all() has no effect.
void notify_all();
//!Releases the lock on the posix_mutex object associated with lock, blocks
//!the current thread of execution until readied by a call to
//!this->notify_one() or this->notify_all(), and then reacquires the lock.
template <typename L>
void wait(L& lock)
{
if (!lock)
throw lock_exception();
this->do_wait(*lock.mutex());
}
//!The same as:
//!while (!pred()) wait(lock)
template <typename L, typename Pr>
void wait(L& lock, Pr pred)
{
if (!lock)
throw lock_exception();
while (!pred())
this->do_wait(*lock.mutex());
}
//!Releases the lock on the posix_mutex object associated with lock, blocks
//!the current thread of execution until readied by a call to
//!this->notify_one() or this->notify_all(), or until time abs_time is reached,
//!and then reacquires the lock.
//!Returns: false if time abs_time is reached, otherwise true.
template <typename L>
bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time)
{
if (!lock)
throw lock_exception();
//Posix does not support infinity absolute time so handle it here
if(abs_time == boost::posix_time::pos_infin){
this->wait(lock);
return true;
}
return this->do_timed_wait(abs_time, *lock.mutex());
}
//!The same as: while (!pred()) {
//! if (!timed_wait(lock, abs_time)) return pred();
//! } return true;
template <typename L, typename Pr>
bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
{
if (!lock)
throw lock_exception();
//Posix does not support infinity absolute time so handle it here
if(abs_time == boost::posix_time::pos_infin){
this->wait(lock, pred);
return true;
}
while (!pred()){
if (!this->do_timed_wait(abs_time, *lock.mutex()))
return pred();
}
return true;
}
void do_wait(posix_mutex &mut);
bool do_timed_wait(const boost::posix_time::ptime &abs_time, posix_mutex &mut);
private:
pthread_cond_t m_condition;
};
inline posix_condition::posix_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 posix_condition::~posix_condition()
{
int res = 0;
res = pthread_cond_destroy(&m_condition);
BOOST_ASSERT(res == 0); (void)res;
}
inline void posix_condition::notify_one()
{
int res = 0;
res = pthread_cond_signal(&m_condition);
BOOST_ASSERT(res == 0); (void)res;
}
inline void posix_condition::notify_all()
{
int res = 0;
res = pthread_cond_broadcast(&m_condition);
BOOST_ASSERT(res == 0); (void)res;
}
inline void posix_condition::do_wait(posix_mutex &mut)
{
pthread_mutex_t* pmutex = &mut.m_mut;
int res = 0;
res = pthread_cond_wait(&m_condition, pmutex);
BOOST_ASSERT(res == 0); (void)res;
}
inline bool posix_condition::do_timed_wait
(const boost::posix_time::ptime &abs_time, posix_mutex &mut)
{
timespec ts = 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 ipcdetail
} //namespace interprocess
} //namespace boost
#include <boost/interprocess/detail/config_end.hpp>
#endif //#ifndef BOOST_INTERPROCESS_POSIX_CONDITION_HPP
@@ -0,0 +1,143 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. 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.
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTERPROCESS_DETAIL_POSIX_MUTEX_HPP
#define BOOST_INTERPROCESS_DETAIL_POSIX_MUTEX_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#
#if defined(BOOST_HAS_PRAGMA_ONCE)
# 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>
#include <boost/interprocess/sync/posix/ptime_to_timespec.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/sync/posix/pthread_helpers.hpp>
#ifndef BOOST_INTERPROCESS_POSIX_TIMEOUTS
# include <boost/interprocess/detail/os_thread_functions.hpp>
# include <boost/interprocess/sync/detail/common_algorithms.hpp>
#endif
#include <boost/assert.hpp>
namespace boost {
namespace interprocess {
namespace ipcdetail {
class posix_condition;
class posix_mutex
{
posix_mutex(const posix_mutex &);
posix_mutex &operator=(const posix_mutex &);
public:
posix_mutex();
~posix_mutex();
void lock();
bool try_lock();
bool timed_lock(const boost::posix_time::ptime &abs_time);
void unlock();
friend class posix_condition;
private:
pthread_mutex_t m_mut;
};
inline posix_mutex::posix_mutex()
{
mutexattr_wrapper mut_attr;
mutex_initializer mut(m_mut, mut_attr);
mut.release();
}
inline posix_mutex::~posix_mutex()
{
int res = pthread_mutex_destroy(&m_mut);
BOOST_ASSERT(res == 0);(void)res;
}
inline void posix_mutex::lock()
{
if (pthread_mutex_lock(&m_mut) != 0)
throw lock_exception();
}
inline bool posix_mutex::try_lock()
{
int res = pthread_mutex_trylock(&m_mut);
if (!(res == 0 || res == EBUSY))
throw lock_exception();
return res == 0;
}
inline bool posix_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
{
#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
//Posix does not support infinity absolute time so handle it here
if(abs_time == boost::posix_time::pos_infin){
this->lock();
return true;
}
timespec ts = 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
return ipcdetail::try_based_timed_lock(*this, abs_time);
#endif //BOOST_INTERPROCESS_POSIX_TIMEOUTS
}
inline void posix_mutex::unlock()
{
int res = 0;
res = pthread_mutex_unlock(&m_mut);
(void)res;
BOOST_ASSERT(res == 0);
}
} //namespace ipcdetail {
} //namespace interprocess {
} //namespace boost {
#include <boost/interprocess/detail/config_end.hpp>
#endif //#ifndef BOOST_INTERPROCESS_DETAIL_POSIX_MUTEX_HPP
@@ -0,0 +1,114 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. 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_NAMED_MUTEX_HPP
#define BOOST_INTERPROCESS_POSIX_NAMED_MUTEX_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/creation_tags.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/detail/interprocess_tester.hpp>
#include <boost/interprocess/permissions.hpp>
#include <boost/interprocess/sync/posix/named_semaphore.hpp>
namespace boost {
namespace interprocess {
namespace ipcdetail {
class named_condition;
class posix_named_mutex
{
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
posix_named_mutex();
posix_named_mutex(const posix_named_mutex &);
posix_named_mutex &operator=(const posix_named_mutex &);
friend class named_condition;
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
posix_named_mutex(create_only_t create_only, const char *name, const permissions &perm = permissions());
posix_named_mutex(open_or_create_t open_or_create, const char *name, const permissions &perm = permissions());
posix_named_mutex(open_only_t open_only, const char *name);
~posix_named_mutex();
void unlock();
void lock();
bool try_lock();
bool timed_lock(const boost::posix_time::ptime &abs_time);
static bool remove(const char *name);
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
friend class interprocess_tester;
void dont_close_on_destruction();
posix_named_semaphore m_sem;
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
inline posix_named_mutex::posix_named_mutex(create_only_t, const char *name, const permissions &perm)
: m_sem(create_only, name, 1, perm)
{}
inline posix_named_mutex::posix_named_mutex(open_or_create_t, const char *name, const permissions &perm)
: m_sem(open_or_create, name, 1, perm)
{}
inline posix_named_mutex::posix_named_mutex(open_only_t, const char *name)
: m_sem(open_only, name)
{}
inline void posix_named_mutex::dont_close_on_destruction()
{ interprocess_tester::dont_close_on_destruction(m_sem); }
inline posix_named_mutex::~posix_named_mutex()
{}
inline void posix_named_mutex::lock()
{ m_sem.wait(); }
inline void posix_named_mutex::unlock()
{ m_sem.post(); }
inline bool posix_named_mutex::try_lock()
{ return m_sem.try_wait(); }
inline bool posix_named_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
{ return m_sem.timed_wait(abs_time); }
inline bool posix_named_mutex::remove(const char *name)
{ return posix_named_semaphore::remove(name); }
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
} //namespace ipcdetail {
} //namespace interprocess {
} //namespace boost {
#include <boost/interprocess/detail/config_end.hpp>
#endif //BOOST_INTERPROCESS_POSIX_NAMED_MUTEX_HPP
@@ -0,0 +1,88 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. 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_NAMED_CONDITION_HPP
#define BOOST_INTERPROCESS_POSIX_NAMED_CONDITION_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/sync/posix/semaphore_wrapper.hpp>
namespace boost {
namespace interprocess {
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
namespace ipcdetail{ class interprocess_tester; }
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
namespace ipcdetail {
class posix_named_semaphore
{
posix_named_semaphore();
posix_named_semaphore(const posix_named_semaphore&);
posix_named_semaphore &operator= (const posix_named_semaphore &);
public:
posix_named_semaphore
(create_only_t, const char *name, unsigned int initialCount, const permissions &perm = permissions())
{ semaphore_open(mp_sem, DoCreate, name, initialCount, perm); }
posix_named_semaphore(open_or_create_t, const char *name, unsigned int initialCount, const permissions &perm = permissions())
{ semaphore_open(mp_sem, DoOpenOrCreate, name, initialCount, perm); }
posix_named_semaphore(open_only_t, const char *name)
{ semaphore_open(mp_sem, DoOpen, name); }
~posix_named_semaphore()
{
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;
};
} //namespace ipcdetail {
} //namespace interprocess {
} //namespace boost {
#include <boost/interprocess/detail/config_end.hpp>
#endif //#ifndef BOOST_INTERPROCESS_POSIX_NAMED_CONDITION_HPP
@@ -0,0 +1,172 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. 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
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#
#if defined(BOOST_HAS_PRAGMA_ONCE)
# 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
@@ -0,0 +1,48 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. 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
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#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));
//Avoid negative absolute times
boost::posix_time::time_duration duration = (tm <= epoch) ? boost::posix_time::time_duration(epoch - epoch)
: boost::posix_time::time_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
@@ -0,0 +1,137 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. 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.
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTERPROCESS_DETAIL_POSIX_RECURSIVE_MUTEX_HPP
#define BOOST_INTERPROCESS_DETAIL_POSIX_RECURSIVE_MUTEX_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#
#if defined(BOOST_HAS_PRAGMA_ONCE)
# 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/sync/posix/pthread_helpers.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>
# include <boost/interprocess/sync/detail/common_algorithms.hpp>
#endif
#include <boost/assert.hpp>
namespace boost {
namespace interprocess {
namespace ipcdetail {
class posix_recursive_mutex
{
posix_recursive_mutex(const posix_recursive_mutex &);
posix_recursive_mutex &operator=(const posix_recursive_mutex &);
public:
posix_recursive_mutex();
~posix_recursive_mutex();
void lock();
bool try_lock();
bool timed_lock(const boost::posix_time::ptime &abs_time);
void unlock();
private:
pthread_mutex_t m_mut;
};
inline posix_recursive_mutex::posix_recursive_mutex()
{
mutexattr_wrapper mut_attr(true);
mutex_initializer mut(m_mut, mut_attr);
mut.release();
}
inline posix_recursive_mutex::~posix_recursive_mutex()
{
int res = pthread_mutex_destroy(&m_mut);
BOOST_ASSERT(res == 0);(void)res;
}
inline void posix_recursive_mutex::lock()
{
if (pthread_mutex_lock(&m_mut) != 0)
throw lock_exception();
}
inline bool posix_recursive_mutex::try_lock()
{
int res = pthread_mutex_trylock(&m_mut);
if (!(res == 0 || res == EBUSY))
throw lock_exception();
return res == 0;
}
inline bool posix_recursive_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
{
#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
//Posix does not support infinity absolute time so handle it here
if(abs_time == boost::posix_time::pos_infin){
this->lock();
return true;
}
timespec ts = 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
return ipcdetail::try_based_timed_lock(*this, abs_time);
#endif //BOOST_INTERPROCESS_POSIX_TIMEOUTS
}
inline void posix_recursive_mutex::unlock()
{
int res = 0;
res = pthread_mutex_unlock(&m_mut);
BOOST_ASSERT(res == 0); (void)res;
}
} //namespace ipcdetail {
} //namespace interprocess {
} //namespace boost {
#include <boost/interprocess/detail/config_end.hpp>
#endif //#ifndef BOOST_INTERPROCESS_DETAIL_POSIX_RECURSIVE_MUTEX_HPP
@@ -0,0 +1,67 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. 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_HPP
#define BOOST_INTERPROCESS_POSIX_SEMAPHORE_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/sync/posix/semaphore_wrapper.hpp>
namespace boost {
namespace interprocess {
namespace ipcdetail {
class posix_semaphore
{
posix_semaphore();
posix_semaphore(const posix_semaphore&);
posix_semaphore &operator= (const posix_semaphore &);
public:
posix_semaphore(unsigned int initialCount)
{ semaphore_init(&m_sem, initialCount); }
~posix_semaphore()
{ 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 {
#include <boost/interprocess/detail/config_end.hpp>
#endif //#ifndef BOOST_INTERPROCESS_POSIX_SEMAPHORE_HPP
@@ -0,0 +1,253 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. 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
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#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/shared_dir_helpers.hpp>
#include <boost/interprocess/permissions.hpp>
#include <fcntl.h> //O_CREAT, O_*...
#include <unistd.h> //close
#include <string> //std::string
#include <semaphore.h> //sem_* family, SEM_VALUE_MAX
#include <sys/stat.h> //mode_t, S_IRWXG, S_IRWXO, S_IRWXU,
#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>
#include <boost/interprocess/sync/detail/locks.hpp>
#include <boost/interprocess/sync/detail/common_algorithms.hpp>
#endif
namespace boost {
namespace interprocess {
namespace ipcdetail {
#ifdef BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES
inline bool semaphore_open
(sem_t *&handle, create_enum_t type, const char *origname,
unsigned int count = 0, const permissions &perm = permissions())
{
std::string name;
#ifndef BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES
add_leading_slash(origname, name);
#else
create_shared_dir_cleaning_old_and_get_filepath(origname, name);
#endif
//Create new mapping
int oflag = 0;
switch(type){
case DoOpen:
{
//No addition
handle = ::sem_open(name.c_str(), oflag);
}
break;
case DoOpenOrCreate:
case DoCreate:
{
while(1){
oflag = (O_CREAT | O_EXCL);
handle = ::sem_open(name.c_str(), oflag, perm.get_permissions(), count);
if(handle != BOOST_INTERPROCESS_POSIX_SEM_FAILED){
//We can't change semaphore permissions!
//::fchmod(handle, perm.get_permissions());
break;
}
else if(errno == EEXIST && type == DoOpenOrCreate){
oflag = 0;
if( (handle = ::sem_open(name.c_str(), oflag)) != BOOST_INTERPROCESS_POSIX_SEM_FAILED
|| (errno != ENOENT) ){
break;
}
}
else{
break;
}
}
}
break;
default:
{
error_info err(other_error);
throw interprocess_exception(err);
}
}
//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
add_leading_slash(semname, sem_str);
#else
shared_filepath(semname, sem_str);
#endif
return 0 == sem_unlink(sem_str.c_str());
}
catch(...){
return false;
}
}
#endif //BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES
#ifdef BOOST_INTERPROCESS_POSIX_UNNAMED_SEMAPHORES
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){
error_info err = system_error_code();
throw interprocess_exception(err);
}
}
inline void semaphore_destroy(sem_t *handle)
{
int ret = sem_destroy(handle);
if(ret != 0){
BOOST_ASSERT(0);
}
}
#endif //BOOST_INTERPROCESS_POSIX_UNNAMED_SEMAPHORES
inline void semaphore_post(sem_t *handle)
{
int ret = sem_post(handle);
if(ret != 0){
error_info err = system_error_code();
throw interprocess_exception(err);
}
}
inline void semaphore_wait(sem_t *handle)
{
int ret = sem_wait(handle);
if(ret != 0){
error_info err = system_error_code();
throw interprocess_exception(err);
}
}
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;
}
error_info err = system_error_code();
throw interprocess_exception(err);
}
#ifndef BOOST_INTERPROCESS_POSIX_TIMEOUTS
struct semaphore_wrapper_try_wrapper
{
explicit semaphore_wrapper_try_wrapper(sem_t *handle)
: m_handle(handle)
{}
void wait()
{ semaphore_wait(m_handle); }
bool try_wait()
{ return semaphore_try_wait(m_handle); }
private:
sem_t *m_handle;
};
#endif
inline bool semaphore_timed_wait(sem_t *handle, const boost::posix_time::ptime &abs_time)
{
#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
//Posix does not support infinity absolute time so handle it here
if(abs_time == boost::posix_time::pos_infin){
semaphore_wait(handle);
return true;
}
timespec tspec = 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;
}
error_info err = system_error_code();
throw interprocess_exception(err);
}
return false;
#else //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
semaphore_wrapper_try_wrapper swtw(handle);
ipcdetail::lock_to_wait<semaphore_wrapper_try_wrapper> lw(swtw);
return ipcdetail::try_based_timed_lock(lw, abs_time);
#endif //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
}
} //namespace ipcdetail {
} //namespace interprocess {
} //namespace boost {
#endif //#ifndef BOOST_INTERPROCESS_POSIX_SEMAPHORE_WRAPPER_HPP