Last merge for 1.55 (Interprocess)

[SVN r85705]
This commit is contained in:
Ion Gaztañaga
2013-09-16 17:01:45 +00:00
parent 762aaea036
commit aa6dd59f3b
13 changed files with 356 additions and 243 deletions

View File

@@ -21,7 +21,7 @@ rule test_all
for local fileb in [ glob comp*.cpp ]
{
all_rules += [ link $(fileb) /boost/thread//boost_thread
all_rules += [ link $(fileb)
: # additional args
<toolset>acc:<linkflags>-lrt
<toolset>acc-pa_risc:<linkflags>-lrt
@@ -35,7 +35,7 @@ rule test_all
for local fileb in [ glob doc_*.cpp ]
{
all_rules += [ run $(fileb) /boost/thread//boost_thread
all_rules += [ run $(fileb)
: # additional args
: # test-files
: # requirements

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2013. 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)
//
@@ -8,6 +8,17 @@
//
//////////////////////////////////////////////////////////////////////////////
//Thread launching functions are adapted from boost/detail/lightweight_thread.hpp
//
// boost/detail/lightweight_thread.hpp
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
// Copyright (c) 2008 Peter Dimov
//
// 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
#ifndef BOOST_INTERPROCESS_DETAIL_OS_THREAD_FUNCTIONS_HPP
#define BOOST_INTERPROCESS_DETAIL_OS_THREAD_FUNCTIONS_HPP
@@ -16,9 +27,11 @@
#include <boost/interprocess/streams/bufferstream.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <cstddef>
#include <memory>
#if defined(BOOST_INTERPROCESS_WINDOWS)
# include <boost/interprocess/detail/win32_api.hpp>
# include <process.h>
#else
# include <pthread.h>
# include <unistd.h>
@@ -56,6 +69,7 @@ namespace ipcdetail{
typedef unsigned long OS_process_id_t;
typedef unsigned long OS_thread_id_t;
typedef void* OS_thread_t;
typedef OS_thread_id_t OS_systemwide_thread_id_t;
//process
@@ -198,6 +212,7 @@ inline unsigned int get_num_cores()
#else //#if (defined BOOST_INTERPROCESS_WINDOWS)
typedef pthread_t OS_thread_t;
typedef pthread_t OS_thread_id_t;
typedef pid_t OS_process_id_t;
@@ -446,6 +461,12 @@ inline unsigned int get_num_cores()
#endif
}
inline int thread_create(OS_thread_t * thread, void *(*start_routine)(void*), void* arg)
{ return pthread_create(thread, 0, start_routine, arg); }
inline void thread_join(OS_thread_t thread)
{ (void)pthread_join(thread, 0); }
#endif //#if (defined BOOST_INTERPROCESS_WINDOWS)
typedef char pid_str_t[sizeof(OS_process_id_t)*3+1];
@@ -459,6 +480,87 @@ inline void get_pid_str(pid_str_t &pid_str, OS_process_id_t pid)
inline void get_pid_str(pid_str_t &pid_str)
{ get_pid_str(pid_str, get_current_process_id()); }
#if defined(BOOST_INTERPROCESS_WINDOWS)
inline int thread_create( OS_thread_t * thread, unsigned (__stdcall * start_routine) (void*), void* arg )
{
void* h = (void*)_beginthreadex( 0, 0, start_routine, arg, 0, 0 );
if( h != 0 ){
*thread = h;
return 0;
}
else{
return EAGAIN;
}
}
inline void thread_join( OS_thread_t thread)
{
winapi::wait_for_single_object( thread, winapi::infinite_time );
winapi::close_handle( thread );
}
#endif
class abstract_thread
{
public:
virtual ~abstract_thread() {}
virtual void run() = 0;
};
#if defined(BOOST_INTERPROCESS_WINDOWS)
inline unsigned __stdcall launch_thread_routine( void * pv )
{
std::auto_ptr<abstract_thread> pt( static_cast<abstract_thread *>( pv ) );
pt->run();
return 0;
}
#else
extern "C" void * launch_thread_routine( void * pv );
inline void * launch_thread_routine( void * pv )
{
std::auto_ptr<abstract_thread> pt( static_cast<abstract_thread *>( pv ) );
pt->run();
return 0;
}
#endif
template<class F>
class launch_thread_impl
: public abstract_thread
{
public:
explicit launch_thread_impl( F f )
: f_( f )
{}
void run()
{ f_(); }
private:
F f_;
};
template<class F>
inline int thread_launch( OS_thread_t & pt, F f )
{
std::auto_ptr<abstract_thread> p( new launch_thread_impl<F>( f ) );
int r = thread_create(&pt, launch_thread_routine, p.get());
if( r == 0 ){
p.release();
}
return r;
}
} //namespace ipcdetail{
} //namespace interprocess {
} //namespace boost {

View File

@@ -24,8 +24,25 @@
#if defined(_POSIX_THREAD_PROCESS_SHARED) && ((_POSIX_THREAD_PROCESS_SHARED - 0) > 0)
//Cygwin defines _POSIX_THREAD_PROCESS_SHARED but does not implement it.
//Mac Os X >= Leopard defines _POSIX_THREAD_PROCESS_SHARED but does not seem to work.
#if !defined(__CYGWIN__) && !defined(__APPLE__)
#if defined(__CYGWIN__)
#define BOOST_INTERPROCESS_BUGGY_POSIX_PROCESS_SHARED
//Mac Os X < Lion (10.7) might define _POSIX_THREAD_PROCESS_SHARED but there is no real support.
#elif defined(__APPLE__)
#include "TargetConditionals.h"
//Check we're on Mac OS target
#if defined(TARGET_OS_MAC)
#include "AvailabilityMacros.h"
//If minimum target for this compilation is older than Mac Os Lion, then we are out of luck
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
#define BOOST_INTERPROCESS_BUGGY_POSIX_PROCESS_SHARED
#endif
#endif
#endif
//If buggy _POSIX_THREAD_PROCESS_SHARED is detected avoid using it
#if defined(BOOST_INTERPROCESS_BUGGY_POSIX_PROCESS_SHARED)
#undef BOOST_INTERPROCESS_BUGGY_POSIX_PROCESS_SHARED
#else
#define BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
#endif
#endif

View File

@@ -297,6 +297,9 @@
<File
RelativePath="..\..\..\..\boost\interprocess\sync\spin\semaphore.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\interprocess\sync\spin\wait.hpp">
</File>
</Filter>
<Filter
Name="xsi"

View File

@@ -21,7 +21,7 @@ rule test_all
for local fileb in [ glob *.cpp ]
{
all_rules += [ run $(fileb) /boost/thread//boost_thread
all_rules += [ run $(fileb)
: # additional args
: # test-files
: # requirements

View File

@@ -17,7 +17,7 @@
namespace boost { namespace interprocess { namespace test {
#define BOOST_INTERPROCES_CHECK( P ) \
#define BOOST_INTERPROCESS_CHECK( P ) \
if(!(P)) do{ assert(P); std::cout << "Failed: " << #P << " file: " << __FILE__ << " line : " << __LINE__ << std::endl; throw boost::interprocess::interprocess_exception(#P);}while(0)
}}} //namespace boost { namespace interprocess { namespace test {

View File

@@ -22,13 +22,10 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/detail/os_thread_functions.hpp>
#include "boost_interprocess_check.hpp"
#include <boost/thread/detail/config.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/thread/thread.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/thread/xtime.hpp>
#include <boost/version.hpp>
#include <iostream>
namespace boost{
@@ -41,31 +38,6 @@ boost::posix_time::ptime ptime_delay(int secs)
boost::posix_time::time_duration(0, 0, secs);
}
inline boost::xtime delay(int secs, int msecs=0, int nsecs=0)
{
const int MILLISECONDS_PER_SECOND = 1000;
const int NANOSECONDS_PER_SECOND = 1000000000;
const int NANOSECONDS_PER_MILLISECOND = 1000000;
boost::xtime xt;
#if BOOST_VERSION >= 105100 //TIME_UTC is a macro in C11, breaking change in Boost.Thread
int ret = boost::xtime_get(&xt, boost::TIME_UTC_);
BOOST_INTERPROCES_CHECK(ret == static_cast<int>(boost::TIME_UTC_));(void)ret;
#else
int ret = boost::xtime_get(&xt, boost::TIME_UTC);
BOOST_INTERPROCES_CHECK(ret == static_cast<int>(boost::TIME_UTC));(void)ret;
#endif
nsecs += xt.nsec;
msecs += nsecs / NANOSECONDS_PER_MILLISECOND;
secs += msecs / MILLISECONDS_PER_SECOND;
nsecs += (msecs % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
xt.nsec = nsecs % NANOSECONDS_PER_SECOND;
xt.sec += secs + (nsecs / NANOSECONDS_PER_SECOND);
return xt;
}
template <typename F, typename T>
class binder
{
@@ -104,10 +76,10 @@ void condition_test_thread(condition_test_data<Condition, Mutex>* data)
{
boost::interprocess::scoped_lock<Mutex>
lock(data->mutex);
BOOST_INTERPROCES_CHECK(lock ? true : false);
BOOST_INTERPROCESS_CHECK(lock ? true : false);
while (!(data->notified > 0))
data->condition.wait(lock);
BOOST_INTERPROCES_CHECK(lock ? true : false);
BOOST_INTERPROCESS_CHECK(lock ? true : false);
data->awoken++;
}
@@ -126,38 +98,38 @@ void condition_test_waits(condition_test_data<Condition, Mutex>* data)
{
boost::interprocess::scoped_lock<Mutex>
lock(data->mutex);
BOOST_INTERPROCES_CHECK(lock ? true : false);
BOOST_INTERPROCESS_CHECK(lock ? true : false);
// Test wait.
while (data->notified != 1)
data->condition.wait(lock);
BOOST_INTERPROCES_CHECK(lock ? true : false);
BOOST_INTERPROCES_CHECK(data->notified == 1);
BOOST_INTERPROCESS_CHECK(lock ? true : false);
BOOST_INTERPROCESS_CHECK(data->notified == 1);
data->awoken++;
data->condition.notify_one();
// Test predicate wait.
data->condition.wait(lock, cond_predicate(data->notified, 2));
BOOST_INTERPROCES_CHECK(lock ? true : false);
BOOST_INTERPROCES_CHECK(data->notified == 2);
BOOST_INTERPROCESS_CHECK(lock ? true : false);
BOOST_INTERPROCESS_CHECK(data->notified == 2);
data->awoken++;
data->condition.notify_one();
// Test timed_wait.
while (data->notified != 3)
data->condition.timed_wait(lock, ptime_delay(5));
BOOST_INTERPROCES_CHECK(lock ? true : false);
BOOST_INTERPROCES_CHECK(data->notified == 3);
BOOST_INTERPROCESS_CHECK(lock ? true : false);
BOOST_INTERPROCESS_CHECK(data->notified == 3);
data->awoken++;
data->condition.notify_one();
// Test predicate timed_wait.
cond_predicate pred(data->notified, 4);
bool ret = data->condition.timed_wait(lock, ptime_delay(5), pred);
BOOST_INTERPROCES_CHECK(ret);(void)ret;
BOOST_INTERPROCES_CHECK(lock ? true : false);
BOOST_INTERPROCES_CHECK(pred());
BOOST_INTERPROCES_CHECK(data->notified == 4);
BOOST_INTERPROCESS_CHECK(ret);(void)ret;
BOOST_INTERPROCESS_CHECK(lock ? true : false);
BOOST_INTERPROCESS_CHECK(pred());
BOOST_INTERPROCESS_CHECK(data->notified == 4);
data->awoken++;
data->condition.notify_one();
}
@@ -167,92 +139,97 @@ void do_test_condition_notify_one()
{
condition_test_data<Condition, Mutex> data;
boost::thread thread(bind_function(&condition_test_thread<Condition, Mutex>, &data));
boost::interprocess::ipcdetail::OS_thread_t thread;
boost::interprocess::ipcdetail::thread_launch(thread, bind_function(&condition_test_thread<Condition, Mutex>, &data));
//Make sure thread is blocked
boost::thread::sleep(delay(1));
boost::interprocess::ipcdetail::thread_sleep(1000);
{
boost::interprocess::scoped_lock<Mutex>
lock(data.mutex);
BOOST_INTERPROCES_CHECK(lock ? true : false);
BOOST_INTERPROCESS_CHECK(lock ? true : false);
data.notified++;
data.condition.notify_one();
}
thread.join();
BOOST_INTERPROCES_CHECK(data.awoken == 1);
boost::interprocess::ipcdetail::thread_join(thread);
BOOST_INTERPROCESS_CHECK(data.awoken == 1);
}
template <class Condition, class Mutex>
void do_test_condition_notify_all()
{
const int NUMTHREADS = 3;
boost::thread_group threads;
boost::interprocess::ipcdetail::OS_thread_t thgroup[NUMTHREADS];
condition_test_data<Condition, Mutex> data;
for (int i = 0; i < NUMTHREADS; ++i){
threads.create_thread(bind_function(&condition_test_thread<Condition, Mutex>, &data));
for(int i = 0; i< NUMTHREADS; ++i){
boost::interprocess::ipcdetail::thread_launch(thgroup[i], bind_function(&condition_test_thread<Condition, Mutex>, &data));
}
//Make sure all threads are blocked
boost::thread::sleep(delay(1));
boost::interprocess::ipcdetail::thread_sleep(1000);
{
boost::interprocess::scoped_lock<Mutex>
lock(data.mutex);
BOOST_INTERPROCES_CHECK(lock ? true : false);
BOOST_INTERPROCESS_CHECK(lock ? true : false);
data.notified++;
}
data.condition.notify_all();
threads.join_all();
BOOST_INTERPROCES_CHECK(data.awoken == NUMTHREADS);
for(int i = 0; i< NUMTHREADS; ++i){
boost::interprocess::ipcdetail::thread_join(thgroup[i]);
}
BOOST_INTERPROCESS_CHECK(data.awoken == NUMTHREADS);
}
template <class Condition, class Mutex>
void do_test_condition_waits()
{
condition_test_data<Condition, Mutex> data;
boost::thread thread(bind_function(&condition_test_waits<Condition, Mutex>, &data));
boost::interprocess::ipcdetail::OS_thread_t thread;
boost::interprocess::ipcdetail::thread_launch(thread, bind_function(&condition_test_waits<Condition, Mutex>, &data));
{
boost::interprocess::scoped_lock<Mutex>
lock(data.mutex);
BOOST_INTERPROCES_CHECK(lock ? true : false);
BOOST_INTERPROCESS_CHECK(lock ? true : false);
boost::thread::sleep(delay(1));
boost::interprocess::ipcdetail::thread_sleep(1000);
data.notified++;
data.condition.notify_one();
while (data.awoken != 1)
data.condition.wait(lock);
BOOST_INTERPROCES_CHECK(lock ? true : false);
BOOST_INTERPROCES_CHECK(data.awoken == 1);
BOOST_INTERPROCESS_CHECK(lock ? true : false);
BOOST_INTERPROCESS_CHECK(data.awoken == 1);
boost::thread::sleep(delay(1));
boost::interprocess::ipcdetail::thread_sleep(1000);
data.notified++;
data.condition.notify_one();
while (data.awoken != 2)
data.condition.wait(lock);
BOOST_INTERPROCES_CHECK(lock ? true : false);
BOOST_INTERPROCES_CHECK(data.awoken == 2);
BOOST_INTERPROCESS_CHECK(lock ? true : false);
BOOST_INTERPROCESS_CHECK(data.awoken == 2);
boost::thread::sleep(delay(1));
boost::interprocess::ipcdetail::thread_sleep(1000);
data.notified++;
data.condition.notify_one();
while (data.awoken != 3)
data.condition.wait(lock);
BOOST_INTERPROCES_CHECK(lock ? true : false);
BOOST_INTERPROCES_CHECK(data.awoken == 3);
BOOST_INTERPROCESS_CHECK(lock ? true : false);
BOOST_INTERPROCESS_CHECK(data.awoken == 3);
boost::thread::sleep(delay(1));
boost::interprocess::ipcdetail::thread_sleep(1000);
data.notified++;
data.condition.notify_one();
while (data.awoken != 4)
data.condition.wait(lock);
BOOST_INTERPROCES_CHECK(lock ? true : false);
BOOST_INTERPROCES_CHECK(data.awoken == 4);
BOOST_INTERPROCESS_CHECK(lock ? true : false);
BOOST_INTERPROCESS_CHECK(data.awoken == 4);
}
thread.join();
BOOST_INTERPROCES_CHECK(data.awoken == 4);
boost::interprocess::ipcdetail::thread_join(thread);
BOOST_INTERPROCESS_CHECK(data.awoken == 4);
}
/*
//Message queue simulation test
@@ -326,16 +303,15 @@ void do_test_condition_queue_notify_one(void)
waiting_readers = 0;
waiting_writer = 0;
boost::thread_group thgroup;
int i;
for(i = 0; i< NumThreads; ++i){
boost::interprocess::ipcdetail::OS_thread_t thgroup[NumThreads];
for(int i = 0; i< NumThreads; ++i){
condition_func<Condition, Mutex> func(cond_full, cond_empty, mutex);
thgroup.create_thread(func);
boost::interprocess::ipcdetail::thread_launch(thgroup[i], func);
}
//Add 20 elements one by one in the queue simulation
//The sender will block if it fills the queue
for(i = 0; i < NumThreads; ++i){
for(int i = 0; i < NumThreads; ++i){
boost::interprocess::scoped_lock<Mutex> lock(mutex);
while(count == queue_size){
++waiting_writer;
@@ -347,10 +323,12 @@ void do_test_condition_queue_notify_one(void)
if(waiting_readers)
cond_empty.notify_one();
}
thgroup.join_all();
BOOST_INTERPROCES_CHECK(count == 0);
BOOST_INTERPROCES_CHECK(waiting_readers == 0);
BOOST_INTERPROCES_CHECK(waiting_writer == 0);
for(int i = 0; i< NumThreads; ++i){
boost::interprocess::ipcdetail::thread_join(thgroup[i]);
}
BOOST_INTERPROCESS_CHECK(count == 0);
BOOST_INTERPROCESS_CHECK(waiting_readers == 0);
BOOST_INTERPROCESS_CHECK(waiting_writer == 0);
}
}
@@ -370,15 +348,14 @@ void do_test_condition_queue_notify_all(void)
waiting_readers = 0;
waiting_writer = 0;
boost::thread_group thgroup;
int i;
for(i = 0; i< NumThreads; ++i){
boost::interprocess::ipcdetail::OS_thread_t thgroup[NumThreads];
for(int i = 0; i< NumThreads; ++i){
condition_func<Condition, Mutex> func(cond_full, cond_empty, mutex);
thgroup.create_thread(func);
boost::interprocess::ipcdetail::thread_launch(thgroup[i], func);
}
//Fill queue to the max size and notify all several times
for(i = 0; i < NumThreads; ++i){
for(int i = 0; i < NumThreads; ++i){
boost::interprocess::scoped_lock<Mutex>lock(mutex);
while(count == queue_size){
++waiting_writer;
@@ -390,10 +367,12 @@ void do_test_condition_queue_notify_all(void)
if(waiting_readers)
cond_empty.notify_all();
}
thgroup.join_all();
BOOST_INTERPROCES_CHECK(count == 0);
BOOST_INTERPROCES_CHECK(waiting_readers == 0);
BOOST_INTERPROCES_CHECK(waiting_writer == 0);
for(int i = 0; i< NumThreads; ++i){
boost::interprocess::ipcdetail::thread_join(thgroup[i]);
}
BOOST_INTERPROCESS_CHECK(count == 0);
BOOST_INTERPROCESS_CHECK(waiting_readers == 0);
BOOST_INTERPROCESS_CHECK(waiting_writer == 0);
}
}

View File

@@ -15,10 +15,10 @@
#include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/containers/set.hpp>
#include <boost/interprocess/allocators/node_allocator.hpp>
#include <boost/interprocess/detail/os_thread_functions.hpp>
#include <vector>
#include <cstddef>
#include <limits>
#include <boost/thread.hpp>
#include <memory>
#include <string>
#include "get_process_id_name.hpp"
@@ -251,8 +251,9 @@ bool test_buffer_overflow()
pmessage_queue = ptr.get();
//Launch the receiver thread
boost::thread thread(&receiver);
boost::thread::yield();
boost::interprocess::ipcdetail::OS_thread_t thread;
boost::interprocess::ipcdetail::thread_launch(thread, &receiver);
boost::interprocess::ipcdetail::thread_yield();
int nummsg = NumMsg;
@@ -260,7 +261,7 @@ bool test_buffer_overflow()
pmessage_queue->send(msgsend, MsgSize, 0);
}
thread.join();
boost::interprocess::ipcdetail::thread_join(thread);
}
boost::interprocess::message_queue::remove(test::get_process_id_name());
return true;

View File

@@ -25,7 +25,7 @@
#include <boost/interprocess/exceptions.hpp>
#include "boost_interprocess_check.hpp"
#include "util.hpp"
#include <boost/thread/thread.hpp>
#include <boost/interprocess/detail/os_thread_functions.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <iostream>
@@ -46,16 +46,16 @@ struct test_lock
// Test the lock's constructors.
{
lock_type lock(interprocess_mutex, boost::interprocess::defer_lock);
BOOST_INTERPROCES_CHECK(!lock);
BOOST_INTERPROCESS_CHECK(!lock);
}
lock_type lock(interprocess_mutex);
BOOST_INTERPROCES_CHECK(lock ? true : false);
BOOST_INTERPROCESS_CHECK(lock ? true : false);
// Test the lock and unlock methods.
lock.unlock();
BOOST_INTERPROCES_CHECK(!lock);
BOOST_INTERPROCESS_CHECK(!lock);
lock.lock();
BOOST_INTERPROCES_CHECK(lock ? true : false);
BOOST_INTERPROCESS_CHECK(lock ? true : false);
}
};
@@ -72,24 +72,24 @@ struct test_trylock
// Test the lock's constructors.
{
try_to_lock_type lock(interprocess_mutex, boost::interprocess::try_to_lock);
BOOST_INTERPROCES_CHECK(lock ? true : false);
BOOST_INTERPROCESS_CHECK(lock ? true : false);
}
{
try_to_lock_type lock(interprocess_mutex, boost::interprocess::defer_lock);
BOOST_INTERPROCES_CHECK(!lock);
BOOST_INTERPROCESS_CHECK(!lock);
}
try_to_lock_type lock(interprocess_mutex);
BOOST_INTERPROCES_CHECK(lock ? true : false);
BOOST_INTERPROCESS_CHECK(lock ? true : false);
// Test the lock, unlock and trylock methods.
lock.unlock();
BOOST_INTERPROCES_CHECK(!lock);
BOOST_INTERPROCESS_CHECK(!lock);
lock.lock();
BOOST_INTERPROCES_CHECK(lock ? true : false);
BOOST_INTERPROCESS_CHECK(lock ? true : false);
lock.unlock();
BOOST_INTERPROCES_CHECK(!lock);
BOOST_INTERPROCES_CHECK(lock.try_lock());
BOOST_INTERPROCES_CHECK(lock ? true : false);
BOOST_INTERPROCESS_CHECK(!lock);
BOOST_INTERPROCESS_CHECK(lock.try_lock());
BOOST_INTERPROCESS_CHECK(lock ? true : false);
}
};
@@ -109,25 +109,25 @@ struct test_timedlock
boost::posix_time::ptime pt = delay(1*BaseSeconds, 0);
timed_lock_type lock(interprocess_mutex, pt);
BOOST_INTERPROCES_CHECK(lock ? true : false);
BOOST_INTERPROCESS_CHECK(lock ? true : false);
}
{
timed_lock_type lock(interprocess_mutex, boost::interprocess::defer_lock);
BOOST_INTERPROCES_CHECK(!lock);
BOOST_INTERPROCESS_CHECK(!lock);
}
timed_lock_type lock(interprocess_mutex);
BOOST_INTERPROCES_CHECK(lock ? true : false);
BOOST_INTERPROCESS_CHECK(lock ? true : false);
// Test the lock, unlock and timedlock methods.
lock.unlock();
BOOST_INTERPROCES_CHECK(!lock);
BOOST_INTERPROCESS_CHECK(!lock);
lock.lock();
BOOST_INTERPROCES_CHECK(lock ? true : false);
BOOST_INTERPROCESS_CHECK(lock ? true : false);
lock.unlock();
BOOST_INTERPROCES_CHECK(!lock);
BOOST_INTERPROCESS_CHECK(!lock);
boost::posix_time::ptime pt = delay(3*BaseSeconds, 0);
BOOST_INTERPROCES_CHECK(lock.timed_lock(pt));
BOOST_INTERPROCES_CHECK(lock ? true : false);
BOOST_INTERPROCESS_CHECK(lock.timed_lock(pt));
BOOST_INTERPROCESS_CHECK(lock ? true : false);
}
};
@@ -170,10 +170,10 @@ void lock_and_sleep(void *arg, M &sm)
data<M> *pdata = static_cast<data<M>*>(arg);
boost::interprocess::scoped_lock<M> l(sm);
if(pdata->m_secs){
boost::thread::sleep(xsecs(pdata->m_secs));
boost::interprocess::ipcdetail::thread_sleep((1000*pdata->m_secs));
}
else{
boost::thread::sleep(xsecs(2*BaseSeconds));
boost::interprocess::ipcdetail::thread_sleep((1000*2*BaseSeconds));
}
++shared_val;
@@ -188,10 +188,10 @@ void lock_and_catch_errors(void *arg, M &sm)
{
boost::interprocess::scoped_lock<M> l(sm);
if(pdata->m_secs){
boost::thread::sleep(xsecs(pdata->m_secs));
boost::interprocess::ipcdetail::thread_sleep((1000*pdata->m_secs));
}
else{
boost::thread::sleep(xsecs(2*BaseSeconds));
boost::interprocess::ipcdetail::thread_sleep((1000*2*BaseSeconds));
}
++shared_val;
pdata->m_value = shared_val;
@@ -208,7 +208,7 @@ void try_lock_and_sleep(void *arg, M &sm)
data<M> *pdata = static_cast<data<M>*>(arg);
boost::interprocess::scoped_lock<M> l(sm, boost::interprocess::defer_lock);
if (l.try_lock()){
boost::thread::sleep(xsecs(2*BaseSeconds));
boost::interprocess::ipcdetail::thread_sleep((1000*2*BaseSeconds));
++shared_val;
pdata->m_value = shared_val;
}
@@ -222,7 +222,7 @@ void timed_lock_and_sleep(void *arg, M &sm)
boost::interprocess::scoped_lock<M>
l (sm, boost::interprocess::defer_lock);
if (l.timed_lock(pt)){
boost::thread::sleep(xsecs(2*BaseSeconds));
boost::interprocess::ipcdetail::thread_sleep((1000*2*BaseSeconds));
++shared_val;
pdata->m_value = shared_val;
}
@@ -239,21 +239,24 @@ void test_mutex_lock()
data<M> d2(2);
// Locker one launches, holds the lock for 2*BaseSeconds seconds.
boost::thread tm1(thread_adapter<M>(&lock_and_sleep, &d1, mtx));
boost::interprocess::ipcdetail::OS_thread_t tm1;
boost::interprocess::ipcdetail::thread_launch(tm1, thread_adapter<M>(&lock_and_sleep, &d1, mtx));
//Wait 1*BaseSeconds
boost::thread::sleep(xsecs(1*BaseSeconds));
boost::interprocess::ipcdetail::thread_sleep((1000*1*BaseSeconds));
// Locker two launches, but it won't hold the lock for 2*BaseSeconds seconds.
boost::thread tm2(thread_adapter<M>(&lock_and_sleep, &d2, mtx));
boost::interprocess::ipcdetail::OS_thread_t tm2;
boost::interprocess::ipcdetail::thread_launch(tm2, thread_adapter<M>(&lock_and_sleep, &d2, mtx));
//Wait completion
tm1.join();
boost::thread::sleep(xsecs(1*BaseSeconds));
tm2.join();
boost::interprocess::ipcdetail::thread_join(tm1);
boost::interprocess::ipcdetail::thread_sleep((1000*1*BaseSeconds));
boost::interprocess::ipcdetail::thread_join(tm2);
BOOST_INTERPROCES_CHECK(d1.m_value == 1);
BOOST_INTERPROCES_CHECK(d2.m_value == 2);
BOOST_INTERPROCESS_CHECK(d1.m_value == 1);
BOOST_INTERPROCESS_CHECK(d2.m_value == 2);
}
template<typename M>
@@ -271,23 +274,25 @@ void test_mutex_lock_timeout()
data<M> d2(2, wait_time_s * 2);
// Locker one launches, and holds the lock for wait_time_s * 2 seconds.
boost::thread tm1(thread_adapter<M>(&lock_and_sleep, &d1, mtx));
boost::interprocess::ipcdetail::OS_thread_t tm1;
boost::interprocess::ipcdetail::thread_launch(tm1, thread_adapter<M>(&lock_and_sleep, &d1, mtx));
//Wait 1*BaseSeconds
boost::thread::sleep(xsecs(wait_time_s));
boost::interprocess::ipcdetail::thread_sleep((1000*wait_time_s));
// Locker two launches, and attempts to hold the lock for wait_time_s * 2 seconds.
boost::thread tm2(thread_adapter<M>(&lock_and_catch_errors, &d2, mtx));
boost::interprocess::ipcdetail::OS_thread_t tm2;
boost::interprocess::ipcdetail::thread_launch(tm2, thread_adapter<M>(&lock_and_catch_errors, &d2, mtx));
//Wait completion
tm1.join();
boost::thread::sleep(xsecs(1*BaseSeconds));
tm2.join();
boost::interprocess::ipcdetail::thread_join(tm1);
boost::interprocess::ipcdetail::thread_sleep((1000*1*BaseSeconds));
boost::interprocess::ipcdetail::thread_join(tm2);
BOOST_INTERPROCES_CHECK(d1.m_value == 1);
BOOST_INTERPROCES_CHECK(d2.m_value == -1);
BOOST_INTERPROCES_CHECK(d1.m_error == no_error);
BOOST_INTERPROCES_CHECK(d2.m_error == boost::interprocess::timeout_when_locking_error);
BOOST_INTERPROCESS_CHECK(d1.m_value == 1);
BOOST_INTERPROCESS_CHECK(d2.m_value == -1);
BOOST_INTERPROCESS_CHECK(d1.m_error == no_error);
BOOST_INTERPROCESS_CHECK(d2.m_error == boost::interprocess::timeout_when_locking_error);
}
template<typename M>
@@ -301,20 +306,23 @@ void test_mutex_try_lock()
data<M> d2(2);
// Locker one launches, holds the lock for 2*BaseSeconds seconds.
boost::thread tm1(thread_adapter<M>(&try_lock_and_sleep, &d1, mtx));
boost::interprocess::ipcdetail::OS_thread_t tm1;
boost::interprocess::ipcdetail::thread_launch(tm1, thread_adapter<M>(&try_lock_and_sleep, &d1, mtx));
//Wait 1*BaseSeconds
boost::thread::sleep(xsecs(1*BaseSeconds));
boost::interprocess::ipcdetail::thread_sleep((1000*1*BaseSeconds));
// Locker two launches, but it should fail acquiring the lock
boost::thread tm2(thread_adapter<M>(&try_lock_and_sleep, &d2, mtx));
boost::interprocess::ipcdetail::OS_thread_t tm2;
boost::interprocess::ipcdetail::thread_launch(tm2, thread_adapter<M>(&try_lock_and_sleep, &d2, mtx));
//Wait completion
tm1.join();
tm2.join();
boost::interprocess::ipcdetail::thread_join(tm1);
boost::interprocess::ipcdetail::thread_join(tm2);
//Only the first should succeed locking
BOOST_INTERPROCES_CHECK(d1.m_value == 1);
BOOST_INTERPROCES_CHECK(d2.m_value == -1);
BOOST_INTERPROCESS_CHECK(d1.m_value == 1);
BOOST_INTERPROCESS_CHECK(d2.m_value == -1);
}
template<typename M>
@@ -329,21 +337,23 @@ void test_mutex_timed_lock()
data<M> d2(2, 2*BaseSeconds);
// Locker one launches, holds the lock for 2*BaseSeconds seconds.
boost::thread tm1(thread_adapter<M>(&timed_lock_and_sleep, &d1, mtx));
boost::interprocess::ipcdetail::OS_thread_t tm1;
boost::interprocess::ipcdetail::thread_launch(tm1, thread_adapter<M>(&timed_lock_and_sleep, &d1, mtx));
//Wait 1*BaseSeconds
boost::thread::sleep(xsecs(1*BaseSeconds));
boost::interprocess::ipcdetail::thread_sleep((1000*1*BaseSeconds));
// Locker two launches, holds the lock for 2*BaseSeconds seconds.
boost::thread tm2(thread_adapter<M>(&timed_lock_and_sleep, &d2, mtx));
boost::interprocess::ipcdetail::OS_thread_t tm2;
boost::interprocess::ipcdetail::thread_launch(tm2, thread_adapter<M>(&timed_lock_and_sleep, &d2, mtx));
//Wait completion
tm1.join();
tm2.join();
boost::interprocess::ipcdetail::thread_join(tm1);
boost::interprocess::ipcdetail::thread_join(tm2);
//Both should succeed locking
BOOST_INTERPROCES_CHECK(d1.m_value == 1);
BOOST_INTERPROCES_CHECK(d2.m_value == 2);
BOOST_INTERPROCESS_CHECK(d1.m_value == 1);
BOOST_INTERPROCESS_CHECK(d2.m_value == 2);
}
template <typename M>

View File

@@ -32,7 +32,7 @@ inline void create_then_open_then_open_or_create()
}
catch(...){
//This shouldn't throw so show the error
BOOST_INTERPROCES_CHECK( false );
BOOST_INTERPROCESS_CHECK( false );
}
}
@@ -45,7 +45,7 @@ inline void open_or_create_then_create()
NamedResource nresource2(create_only);
}
catch(interprocess_exception &err){
BOOST_INTERPROCES_CHECK(err.get_error_code() == already_exists_error);
BOOST_INTERPROCESS_CHECK(err.get_error_code() == already_exists_error);
}
}
@@ -57,11 +57,11 @@ inline void dont_create_and_open()
NamedResource nresource1(open_only);
}
catch(interprocess_exception &err){
BOOST_INTERPROCES_CHECK(err.get_error_code() == not_found_error);
BOOST_INTERPROCESS_CHECK(err.get_error_code() == not_found_error);
return;
}
//The mutex should not exist
BOOST_INTERPROCES_CHECK(false);
BOOST_INTERPROCESS_CHECK(false);
}
template <class NamedResource>

View File

@@ -86,16 +86,16 @@ bool test_named_semaphore_specific()
}
{
named_semaphore sem(open_only, SemName);
BOOST_INTERPROCES_CHECK(sem.try_wait() == true);
BOOST_INTERPROCES_CHECK(sem.try_wait() == true);
BOOST_INTERPROCES_CHECK(sem.try_wait() == true);
BOOST_INTERPROCES_CHECK(sem.try_wait() == false);
BOOST_INTERPROCESS_CHECK(sem.try_wait() == true);
BOOST_INTERPROCESS_CHECK(sem.try_wait() == true);
BOOST_INTERPROCESS_CHECK(sem.try_wait() == true);
BOOST_INTERPROCESS_CHECK(sem.try_wait() == false);
sem.post();
}
{
named_semaphore sem(open_only, SemName);
BOOST_INTERPROCES_CHECK(sem.try_wait() == true);
BOOST_INTERPROCES_CHECK(sem.try_wait() == false);
BOOST_INTERPROCESS_CHECK(sem.try_wait() == true);
BOOST_INTERPROCESS_CHECK(sem.try_wait() == false);
}
named_semaphore::remove(SemName);

View File

@@ -24,8 +24,7 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp>
#include <boost/interprocess/detail/os_thread_functions.hpp>
#include "boost_interprocess_check.hpp"
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/interprocess/sync/sharable_lock.hpp>
@@ -41,7 +40,7 @@ void plain_exclusive(void *arg, SM &sm)
{
data<SM> *pdata = static_cast<data<SM>*>(arg);
boost::interprocess::scoped_lock<SM> l(sm);
boost::thread::sleep(xsecs(3*BaseSeconds));
boost::interprocess::ipcdetail::thread_sleep((1000*3*BaseSeconds));
shared_val += 10;
pdata->m_value = shared_val;
}
@@ -52,7 +51,7 @@ void plain_shared(void *arg, SM &sm)
data<SM> *pdata = static_cast<data<SM>*>(arg);
boost::interprocess::sharable_lock<SM> l(sm);
if(pdata->m_secs){
boost::thread::sleep(xsecs(pdata->m_secs*BaseSeconds));
boost::interprocess::ipcdetail::thread_sleep((1000*pdata->m_secs*BaseSeconds));
}
pdata->m_value = shared_val;
}
@@ -63,7 +62,7 @@ void try_exclusive(void *arg, SM &sm)
data<SM> *pdata = static_cast<data<SM>*>(arg);
boost::interprocess::scoped_lock<SM> l(sm, boost::interprocess::defer_lock);
if (l.try_lock()){
boost::thread::sleep(xsecs(3*BaseSeconds));
boost::interprocess::ipcdetail::thread_sleep((1000*3*BaseSeconds));
shared_val += 10;
pdata->m_value = shared_val;
}
@@ -76,7 +75,7 @@ void try_shared(void *arg, SM &sm)
boost::interprocess::sharable_lock<SM> l(sm, boost::interprocess::defer_lock);
if (l.try_lock()){
if(pdata->m_secs){
boost::thread::sleep(xsecs(pdata->m_secs*BaseSeconds));
boost::interprocess::ipcdetail::thread_sleep((1000*pdata->m_secs*BaseSeconds));
}
pdata->m_value = shared_val;
}
@@ -90,7 +89,7 @@ void timed_exclusive(void *arg, SM &sm)
boost::interprocess::scoped_lock<SM>
l (sm, boost::interprocess::defer_lock);
if (l.timed_lock(pt)){
boost::thread::sleep(xsecs(3*BaseSeconds));
boost::interprocess::ipcdetail::thread_sleep((1000*3*BaseSeconds));
shared_val += 10;
pdata->m_value = shared_val;
}
@@ -105,7 +104,7 @@ void timed_shared(void *arg, SM &sm)
l(sm, boost::interprocess::defer_lock);
if (l.timed_lock(pt)){
if(pdata->m_secs){
boost::thread::sleep(xsecs(pdata->m_secs*BaseSeconds));
boost::interprocess::ipcdetail::thread_sleep((1000*pdata->m_secs*BaseSeconds));
}
pdata->m_value = shared_val;
}
@@ -123,28 +122,32 @@ void test_plain_sharable_mutex()
data<SM> e2(2);
// Writer one launches, holds the lock for 3*BaseSeconds seconds.
boost::thread tw1(thread_adapter<SM>(plain_exclusive, &e1, mtx));
boost::interprocess::ipcdetail::OS_thread_t tw1;
boost::interprocess::ipcdetail::thread_launch(tw1, thread_adapter<SM>(plain_exclusive, &e1, mtx));
// Writer two launches, tries to grab the lock, "clearly"
// after Writer one will already be holding it.
boost::thread::sleep(xsecs(1*BaseSeconds));
boost::thread tw2(thread_adapter<SM>(plain_exclusive, &e2, mtx));
boost::interprocess::ipcdetail::thread_sleep((1000*1*BaseSeconds));
boost::interprocess::ipcdetail::OS_thread_t tw2;
boost::interprocess::ipcdetail::thread_launch(tw2, thread_adapter<SM>(plain_exclusive, &e2, mtx));
// Reader one launches, "clearly" after writer two, and "clearly"
// while writer 1 still holds the lock
boost::thread::sleep(xsecs(1*BaseSeconds));
boost::thread thr1(thread_adapter<SM>(plain_shared,&s1, mtx));
boost::thread thr2(thread_adapter<SM>(plain_shared,&s2, mtx));
boost::interprocess::ipcdetail::thread_sleep((1000*1*BaseSeconds));
boost::interprocess::ipcdetail::OS_thread_t thr1;
boost::interprocess::ipcdetail::thread_launch(thr1, thread_adapter<SM>(plain_shared,&s1, mtx));
boost::interprocess::ipcdetail::OS_thread_t thr2;
boost::interprocess::ipcdetail::thread_launch(thr2, thread_adapter<SM>(plain_shared,&s2, mtx));
thr2.join();
thr1.join();
tw2.join();
tw1.join();
boost::interprocess::ipcdetail::thread_join(thr2);
boost::interprocess::ipcdetail::thread_join(thr1);
boost::interprocess::ipcdetail::thread_join(tw2);
boost::interprocess::ipcdetail::thread_join(tw1);
//We can only assure that the writer will be first
BOOST_INTERPROCES_CHECK(e1.m_value == 10);
BOOST_INTERPROCESS_CHECK(e1.m_value == 10);
//A that we will execute all
BOOST_INTERPROCES_CHECK(s1.m_value == 20 || s2.m_value == 20 || e2.m_value == 20);
BOOST_INTERPROCESS_CHECK(s1.m_value == 20 || s2.m_value == 20 || e2.m_value == 20);
}
{
@@ -157,25 +160,30 @@ void test_plain_sharable_mutex()
data<SM> e2(2);
//We launch 2 readers, that will block for 3*BaseTime seconds
boost::thread thr1(thread_adapter<SM>(plain_shared,&s1, mtx));
boost::thread thr2(thread_adapter<SM>(plain_shared,&s2, mtx));
boost::interprocess::ipcdetail::OS_thread_t thr1;
boost::interprocess::ipcdetail::thread_launch(thr1, thread_adapter<SM>(plain_shared,&s1, mtx));
boost::interprocess::ipcdetail::OS_thread_t thr2;
boost::interprocess::ipcdetail::thread_launch(thr2, thread_adapter<SM>(plain_shared,&s2, mtx));
//Make sure they try to hold the sharable lock
boost::thread::sleep(xsecs(1*BaseSeconds));
boost::interprocess::ipcdetail::thread_sleep((1000*1*BaseSeconds));
// We launch two writers, that should block until the readers end
boost::thread tw1(thread_adapter<SM>(plain_exclusive,&e1, mtx));
boost::thread tw2(thread_adapter<SM>(plain_exclusive,&e2, mtx));
boost::interprocess::ipcdetail::OS_thread_t tw1;
boost::interprocess::ipcdetail::thread_launch(tw1, thread_adapter<SM>(plain_exclusive,&e1, mtx));
thr2.join();
thr1.join();
tw2.join();
tw1.join();
boost::interprocess::ipcdetail::OS_thread_t tw2;
boost::interprocess::ipcdetail::thread_launch(tw2, thread_adapter<SM>(plain_exclusive,&e2, mtx));
boost::interprocess::ipcdetail::thread_join(thr2);
boost::interprocess::ipcdetail::thread_join(thr1);
boost::interprocess::ipcdetail::thread_join(tw2);
boost::interprocess::ipcdetail::thread_join(tw1);
//We can only assure that the shared will finish first...
BOOST_INTERPROCES_CHECK(s1.m_value == 0 || s2.m_value == 0);
BOOST_INTERPROCESS_CHECK(s1.m_value == 0 || s2.m_value == 0);
//...and writers will be mutually excluded after readers
BOOST_INTERPROCES_CHECK((e1.m_value == 10 && e2.m_value == 20) ||
BOOST_INTERPROCESS_CHECK((e1.m_value == 10 && e2.m_value == 20) ||
(e1.m_value == 20 && e2.m_value == 10) );
}
}
@@ -194,24 +202,26 @@ void test_try_sharable_mutex()
shared_val = 0;
// Writer one launches, holds the lock for 3*BaseSeconds seconds.
boost::thread tw1(thread_adapter<SM>(try_exclusive,&e1,mtx));
boost::interprocess::ipcdetail::OS_thread_t tw1;
boost::interprocess::ipcdetail::thread_launch(tw1, thread_adapter<SM>(try_exclusive,&e1,mtx));
// Reader one launches, "clearly" after writer #1 holds the lock
// and before it releases the lock.
boost::thread::sleep(xsecs(1*BaseSeconds));
boost::thread thr1(thread_adapter<SM>(try_shared,&s1,mtx));
boost::interprocess::ipcdetail::thread_sleep((1000*1*BaseSeconds));
boost::interprocess::ipcdetail::OS_thread_t thr1;
boost::interprocess::ipcdetail::thread_launch(thr1, thread_adapter<SM>(try_shared,&s1,mtx));
// Writer two launches in the same timeframe.
boost::thread tw2(thread_adapter<SM>(try_exclusive,&e2,mtx));
boost::interprocess::ipcdetail::OS_thread_t tw2;
boost::interprocess::ipcdetail::thread_launch(tw2, thread_adapter<SM>(try_exclusive,&e2,mtx));
tw2.join();
thr1.join();
tw1.join();
boost::interprocess::ipcdetail::thread_join(tw2);
boost::interprocess::ipcdetail::thread_join(thr1);
boost::interprocess::ipcdetail::thread_join(tw1);
BOOST_INTERPROCES_CHECK(e1.m_value == 10);
BOOST_INTERPROCES_CHECK(s1.m_value == -1); // Try would return w/o waiting
BOOST_INTERPROCES_CHECK(e2.m_value == -1); // Try would return w/o waiting
BOOST_INTERPROCESS_CHECK(e1.m_value == 10);
BOOST_INTERPROCESS_CHECK(s1.m_value == -1); // Try would return w/o waiting
BOOST_INTERPROCESS_CHECK(e2.m_value == -1); // Try would return w/o waiting
}
template<typename SM>
@@ -228,31 +238,36 @@ void test_timed_sharable_mutex()
shared_val = 0;
// Writer one will hold the lock for 3*BaseSeconds seconds.
boost::thread tw1(thread_adapter<SM>(timed_exclusive,&e1,mtx));
boost::interprocess::ipcdetail::OS_thread_t tw1;
boost::interprocess::ipcdetail::thread_launch(tw1, thread_adapter<SM>(timed_exclusive,&e1,mtx));
boost::thread::sleep(xsecs(1*BaseSeconds));
boost::interprocess::ipcdetail::thread_sleep((1000*1*BaseSeconds));
// Writer two will "clearly" try for the lock after the readers
// have tried for it. Writer will wait up 1*BaseSeconds seconds for the lock.
// This write will fail.
boost::thread tw2(thread_adapter<SM>(timed_exclusive,&e2,mtx));
boost::interprocess::ipcdetail::OS_thread_t tw2;
boost::interprocess::ipcdetail::thread_launch(tw2, thread_adapter<SM>(timed_exclusive,&e2,mtx));
// Readers one and two will "clearly" try for the lock after writer
// one already holds it. 1st reader will wait 1*BaseSeconds seconds, and will fail
// to get the lock. 2nd reader will wait 3*BaseSeconds seconds, and will get
// the lock.
boost::thread thr1(thread_adapter<SM>(timed_shared,&s1,mtx));
boost::thread thr2(thread_adapter<SM>(timed_shared,&s2,mtx));
boost::interprocess::ipcdetail::OS_thread_t thr1;
boost::interprocess::ipcdetail::thread_launch(thr1, thread_adapter<SM>(timed_shared,&s1,mtx));
tw1.join();
thr1.join();
thr2.join();
tw2.join();
boost::interprocess::ipcdetail::OS_thread_t thr2;
boost::interprocess::ipcdetail::thread_launch(thr2, thread_adapter<SM>(timed_shared,&s2,mtx));
BOOST_INTERPROCES_CHECK(e1.m_value == 10);
BOOST_INTERPROCES_CHECK(s1.m_value == -1);
BOOST_INTERPROCES_CHECK(s2.m_value == 10);
BOOST_INTERPROCES_CHECK(e2.m_value == -1);
boost::interprocess::ipcdetail::thread_join(tw1);
boost::interprocess::ipcdetail::thread_join(thr1);
boost::interprocess::ipcdetail::thread_join(thr2);
boost::interprocess::ipcdetail::thread_join(tw2);
BOOST_INTERPROCESS_CHECK(e1.m_value == 10);
BOOST_INTERPROCESS_CHECK(s1.m_value == -1);
BOOST_INTERPROCESS_CHECK(s2.m_value == 10);
BOOST_INTERPROCESS_CHECK(e2.m_value == -1);
}
template<typename SM>

View File

@@ -24,8 +24,6 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/detail/os_thread_functions.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <algorithm>
@@ -61,30 +59,18 @@ inline bool in_range(const boost::posix_time::ptime& xt, int secs=1)
return (xt > min) && (max > xt);
}
boost::xtime xsecs(int secs)
{
boost::xtime ret;
#if BOOST_VERSION >= 105100 //TIME_UTC is a macro in C11, breaking change in Boost.Thread
boost::xtime_get(&ret, boost::TIME_UTC_);
#else
boost::xtime_get(&ret, boost::TIME_UTC);
#endif
ret.sec += secs;
return ret;
}
template <typename P>
class thread_adapter
{
public:
thread_adapter(void (*func)(void*, P &), void* param1, P &param2)
: _func(func), _param1(param1) ,_param2(param2){ }
void operator()() const { _func(_param1, _param2); }
: func_(func), param1_(param1) ,param2_(param2){ }
void operator()() const { func_(param1_, param2_); }
private:
void (*_func)(void*, P &);
void* _param1;
P& _param2;
void (*func_)(void*, P &);
void* param1_;
P& param2_;
};
template <typename P>