mirror of
https://github.com/boostorg/interprocess.git
synced 2026-01-19 04:12:13 +00:00
Remove boost/thread dependency in tests.
[SVN r85688]
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 ¶m2)
|
||||
: _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>
|
||||
|
||||
Reference in New Issue
Block a user