mirror of
https://github.com/boostorg/interprocess.git
synced 2026-01-19 04:12:13 +00:00
152 lines
3.7 KiB
C++
152 lines
3.7 KiB
C++
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// (C) Copyright Ion Gaztanaga 2004-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.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include <boost/interprocess/detail/workaround.hpp>
|
|
|
|
//Robust mutex handling is only supported in conforming POSIX systems
|
|
#if !defined(BOOST_INTERPROCESS_POSIX_PROCESS_SHARED) || !defined(BOOST_INTERPROCESS_POSIX_ROBUST_MUTEXES)
|
|
|
|
int main()
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
#else
|
|
|
|
#include <boost/interprocess/detail/os_thread_functions.hpp>
|
|
|
|
#include <boost/interprocess/sync/interprocess_mutex.hpp>
|
|
#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
|
|
#include "mutex_test_template.hpp"
|
|
#include <iostream>
|
|
|
|
|
|
namespace boost {
|
|
namespace interprocess {
|
|
namespace test {
|
|
|
|
template<typename M>
|
|
void lock_and_exit(void *, M &sm)
|
|
{
|
|
sm.lock();
|
|
}
|
|
|
|
enum EOwnerDeadLockType
|
|
{
|
|
OwnerDeadLock,
|
|
OwnerDeadTryLock,
|
|
OwnerDeadTimedLock
|
|
};
|
|
|
|
template<class M>
|
|
void test_owner_dead_mutex_do_lock(M &mtx, EOwnerDeadLockType lock_type)
|
|
{
|
|
switch (lock_type)
|
|
{
|
|
case OwnerDeadLock:
|
|
mtx.lock();
|
|
break;
|
|
|
|
case OwnerDeadTryLock:
|
|
mtx.try_lock();
|
|
break;
|
|
|
|
case OwnerDeadTimedLock:
|
|
mtx.timed_lock(boost_systemclock_delay_ms(10));
|
|
break;
|
|
}
|
|
}
|
|
|
|
template<class M>
|
|
int test_owner_dead_mutex_impl(EOwnerDeadLockType lock_type)
|
|
{
|
|
using namespace boost::interprocess;
|
|
M mtx;
|
|
|
|
// Locker thread launches and exits without releasing the mutex
|
|
ipcdetail::OS_thread_t tm1;
|
|
ipcdetail::thread_launch(tm1, thread_adapter<M>(&lock_and_exit, 0, mtx));
|
|
ipcdetail::thread_join(tm1);
|
|
BOOST_TRY {
|
|
test_owner_dead_mutex_do_lock(mtx, lock_type);
|
|
}
|
|
BOOST_CATCH(lock_exception& e) {
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
if (e.get_error_code() == not_recoverable){
|
|
//Now try once again to lock it, to make sure it's not recoverable
|
|
BOOST_TRY {
|
|
test_owner_dead_mutex_do_lock(mtx, lock_type);
|
|
}
|
|
BOOST_CATCH(lock_exception& e) {
|
|
if (e.get_error_code() == not_recoverable)
|
|
return 0;
|
|
else{
|
|
std::cerr << "e.get_error_code() != not_recoverable! (2)";
|
|
return 3;
|
|
}
|
|
}
|
|
BOOST_CATCH(...) {
|
|
std::cerr << "lock_exception not thrown! (2)";
|
|
return 4;
|
|
} BOOST_CATCH_END
|
|
std::cerr << "Exception not thrown (2)!";
|
|
return 5;
|
|
}
|
|
else{
|
|
std::cerr << "e.get_error_code() != not_recoverable!";
|
|
return 1;
|
|
}
|
|
#endif //BOOST_NO_EXCEPTIONS
|
|
}
|
|
BOOST_CATCH(...) {
|
|
std::cerr << "lock_exception not thrown!";
|
|
return 2;
|
|
} BOOST_CATCH_END
|
|
std::cerr << "Exception not thrown!";
|
|
return 3;
|
|
}
|
|
|
|
template<class M>
|
|
int test_owner_dead_mutex()
|
|
{
|
|
int ret;
|
|
ret = test_owner_dead_mutex_impl<M>(OwnerDeadLock);
|
|
if (ret) return ret;
|
|
ret = test_owner_dead_mutex_impl<M>(OwnerDeadTryLock);
|
|
if (ret) return ret;
|
|
ret = test_owner_dead_mutex_impl<M>(OwnerDeadTimedLock);
|
|
return ret;
|
|
}
|
|
|
|
}}} //boost::interprocess::test
|
|
|
|
|
|
int main ()
|
|
{
|
|
using namespace boost::interprocess;
|
|
int ret;
|
|
std::cerr << "Testing interprocess_mutex";
|
|
ret = test::test_owner_dead_mutex<interprocess_mutex>();
|
|
if (ret)
|
|
return ret;
|
|
|
|
#ifdef BOOST_INTERPROCESS_POSIX_RECURSIVE_MUTEXES
|
|
std::cerr << "Testing interprocess_recursive_mutex";
|
|
ret = test::test_owner_dead_mutex<interprocess_recursive_mutex>();
|
|
if (ret)
|
|
return ret;
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
#endif
|
|
|