Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add exception handling for mutex or condition variable failures #268

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
19 changes: 15 additions & 4 deletions config/check_depend.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,23 @@ OPTION(ORO_NO_EMIT_CORBA_IOR "Do not emit CORBA IORs if name service not used" O
find_package(Boost 1.38 COMPONENTS filesystem system unit_test_framework thread serialization)

# Look for boost
if (NOT Boost_SYSTEM_FOUND)
message(SEND_ERROR "Orocos RTT requires Boost System library, but it was not found.")
endif()
if (NOT Boost_THREAD_FOUND)
message(SEND_ERROR "Orocos RTT requires Boost Thread library, but it was not found.")
endif()
list(APPEND OROCOS-RTT_INCLUDE_DIRS ${Boost_SYSTEM_INCLUDE_DIRS})
list(APPEND OROCOS-RTT_LIBRARIES ${Boost_SYSTEM_LIBRARIES})
if ( PLUGINS_ENABLE )
if (NOT Boost_FILESYSTEM_FOUND OR NOT Boost_SYSTEM_FOUND)
message(SEND_ERROR "Plugins require Boost Filesystem and System libraries, but they were not found.")
if (NOT Boost_FILESYSTEM_FOUND)
message(SEND_ERROR "Plugins require Boost Filesystem library, but it was not found.")
endif()
if (NOT Boost_SERIALIZATION_FOUND)
message(SEND_ERROR "Plugins require Boost Serialization librariy, but it was not found.")
endif()
list(APPEND OROCOS-RTT_INCLUDE_DIRS ${Boost_FILESYSTEM_INCLUDE_DIRS} ${Boost_SYSTEM_INCLUDE_DIRS} ${Boost_SERIALIZATION_INCLUDE_DIRS})
list(APPEND OROCOS-RTT_LIBRARIES ${Boost_FILESYSTEM_LIBRARIES} ${Boost_SYSTEM_LIBRARIES} ${Boost_SERIALIZATION_LIBRARIES})
list(APPEND OROCOS-RTT_INCLUDE_DIRS ${Boost_FILESYSTEM_INCLUDE_DIRS} ${Boost_SERIALIZATION_INCLUDE_DIRS})
list(APPEND OROCOS-RTT_LIBRARIES ${Boost_FILESYSTEM_LIBRARIES} ${Boost_SERIALIZATION_LIBRARIES})
endif()

if(Boost_INCLUDE_DIR)
Expand Down
67 changes: 60 additions & 7 deletions rtt/os/Condition.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@
#include <boost/date_time/posix_time/posix_time_types.hpp>
#endif

/// @todo Replace boost::system::system_error by std::system_error for C++11 and newer.
#include <boost/system/system_error.hpp>
#include <cassert>

namespace RTT
{ namespace os {

Expand All @@ -68,7 +72,13 @@ namespace RTT
*/
Condition()
{
rtos_cond_init( &c);
int ret = rtos_cond_init( &c);
if ( ret == 0 )
return;
#ifndef ORO_EMBEDDED
throw boost::system::system_error(-ret, boost::system::system_category(),
"Failed to initialize an instance of RTT::os::Condition");
#endif
}

/**
Expand All @@ -78,7 +88,10 @@ namespace RTT
*/
~Condition()
{
rtos_cond_destroy( &c );
int ret = rtos_cond_destroy( &c );
if ( ret == 0 )
return;
assert(false && "Failed to destroy an instance of RTT::os::Condition");
}

/**
Expand All @@ -89,7 +102,18 @@ namespace RTT
*/
bool wait (Mutex& m)
{
return rtos_cond_wait( &c, &m.m ) == 0 ? true : false;
int ret = rtos_cond_wait( &c, &m.m );
if ( ret == 0 )
return true;
if ( ret == -EBUSY || ret == -EWOULDBLOCK || ret == -ETIMEDOUT || ret == -EINTR )
return false;
#ifndef ORO_EMBEDDED
throw boost::system::system_error(-ret, boost::system::system_category(),
"Failed to wait on an instance of RTT::os::Condition");
#else
assert(false && "Failed to wait on an instance of RTT::os::Condition");
return false;
#endif
}

/**
Expand All @@ -103,16 +127,36 @@ namespace RTT
template<class Predicate>
bool wait (Mutex& m, Predicate& p)
{
while( !p() )
if ( rtos_cond_wait( &c, &m.m ) != 0) return false;
while( !p() ) {
int ret = rtos_cond_wait( &c, &m.m );
if ( ret == 0 )
continue;
if ( ret == -EBUSY || ret == -EWOULDBLOCK || ret == -ETIMEDOUT || ret == -EINTR )
return false;
#ifndef ORO_EMBEDDED
throw boost::system::system_error(-ret, boost::system::system_category(),
"Failed to wait on an instance of RTT::os::Condition");
#else
assert(false && "Failed to wait on an instance of RTT::os::Condition");
return false;
#endif
}
return true;
}
/**
* Wake all threads that are blocking in wait() or wait_until().
*/
void broadcast()
{
rtos_cond_broadcast( &c );
int ret = rtos_cond_broadcast( &c );
if ( ret == 0 )
return;
#ifndef ORO_EMBEDDED
throw boost::system::system_error(-ret, boost::system::system_category(),
"Failed to broadcast an instance of RTT::os::Condition");
#else
assert(false && "Failed to broadcast an instance of RTT::os::Condition");
#endif
}

/**
Expand All @@ -128,9 +172,18 @@ namespace RTT
*/
bool wait_until(Mutex& m, nsecs abs_time)
{
if ( rtos_cond_timedwait( &c, &m.m, abs_time ) == 0 )
int ret = rtos_cond_timedwait( &c, &m.m, abs_time );
if ( ret == 0 )
return true;
if ( ret == -EBUSY || ret == -EWOULDBLOCK || ret == -ETIMEDOUT || ret == -EINTR )
return false;
#ifndef ORO_EMBEDDED
throw boost::system::system_error(-ret, boost::system::system_category(),
"Failed to wait on an instance of RTT::os::Condition");
#else
assert(false && "Failed to wait on an instance of RTT::os::Condition");
return false;
#endif
}
#else
protected:
Expand Down
118 changes: 104 additions & 14 deletions rtt/os/Mutex.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
#include "Semaphore.hpp"
#include "Time.hpp"

/// @todo Replace boost::system::system_error by std::system_error for C++11 and newer.
#include <boost/system/system_error.hpp>
#include <cassert>

#ifdef ORO_OS_USE_BOOST_THREAD
Expand Down Expand Up @@ -101,7 +103,13 @@ namespace RTT
*/
Mutex()
{
rtos_mutex_init( &m);
int ret = rtos_mutex_init( &m);
if ( ret == 0 )
return;
#ifndef ORO_EMBEDDED
throw boost::system::system_error(-ret, boost::system::system_category(),
"Failed to initialize an instance of RTT::os::Mutex");
#endif
}

/**
Expand All @@ -113,18 +121,37 @@ namespace RTT
{
if ( trylock() ) {
unlock();
rtos_mutex_destroy( &m );
int ret = rtos_mutex_destroy( &m );
if ( ret == 0 )
return;
assert(false && "Failed to destroy an instance of RTT::os::Mutex");
}
}

virtual void lock ()
{
rtos_mutex_lock( &m );
int ret = rtos_mutex_lock( &m );
if ( ret == 0 )
return;
#ifndef ORO_EMBEDDED
throw boost::system::system_error(-ret, boost::system::system_category(),
"Failed to lock an instance of RTT::os::Mutex");
#else
assert(false && "Failed to lock an instance of RTT::os::Mutex");
#endif
}

virtual void unlock()
{
rtos_mutex_unlock( &m );
int ret = rtos_mutex_unlock( &m );
if ( ret == 0 )
return;
#ifndef ORO_EMBEDDED
throw boost::system::system_error(-ret, boost::system::system_category(),
"Failed to unlock an instance of RTT::os::Mutex");
#else
assert(false && "Failed to unlock an instance of RTT::os::Mutex");
#endif
}

/**
Expand All @@ -134,9 +161,18 @@ namespace RTT
*/
virtual bool trylock()
{
if ( rtos_mutex_trylock( &m ) == 0 )
return true;
return false;
int ret = rtos_mutex_trylock( &m );
if ( ret == 0 )
return true;
if ( ret == -EBUSY || ret == -EWOULDBLOCK || ret == -ETIMEDOUT || ret == -EINTR )
return false;
#ifndef ORO_EMBEDDED
throw boost::system::system_error(-ret, boost::system::system_category(),
"Failed to lock an instance of RTT::os::Mutex");
#else
assert(false && "Failed to lock an instance of RTT::os::Mutex");
return false;
#endif
}

/**
Expand All @@ -148,9 +184,18 @@ namespace RTT
*/
virtual bool timedlock(Seconds s)
{
if ( rtos_mutex_trylock_for( &m, Seconds_to_nsecs(s) ) == 0 )
int ret = rtos_mutex_trylock_for( &m, Seconds_to_nsecs(s) );
if ( ret == 0 )
return true;
if ( ret == -EBUSY || ret == -EWOULDBLOCK || ret == -ETIMEDOUT || ret == -EINTR )
return false;
#ifndef ORO_EMBEDDED
throw boost::system::system_error(-ret, boost::system::system_category(),
"Failed to lock an instance of RTT::os::Mutex");
#else
assert(false && "Failed to lock an instance of RTT::os::Mutex");
return false;
#endif
}
#else
protected:
Expand Down Expand Up @@ -226,7 +271,13 @@ namespace RTT
*/
MutexRecursive()
{
rtos_mutex_rec_init( &recm );
int ret = rtos_mutex_rec_init( &recm );
if ( ret == 0 )
return;
#ifndef ORO_EMBEDDED
throw boost::system::system_error(-ret, boost::system::system_category(),
"Failed to initialize an instance of RTT::os::MutexRecursive");
#endif
}

/**
Expand All @@ -238,18 +289,39 @@ namespace RTT
{
if ( trylock() ) {
unlock();
rtos_mutex_rec_destroy( &recm );
// The calling thread might have locked the mutex more than once.
while(rtos_mutex_rec_unlock( &recm ) == 0);
int ret = rtos_mutex_rec_destroy( &recm );
if ( ret == 0 )
return;
assert(false && "Failed to destroy an instance of RTT::os::MutexRecursive");
}
}

void lock ()
{
rtos_mutex_rec_lock( &recm );
int ret = rtos_mutex_rec_lock( &recm );
if ( ret == 0 )
return;
#ifndef ORO_EMBEDDED
throw boost::system::system_error(-ret, boost::system::system_category(),
"Failed to lock an instance of RTT::os::MutexRecursive");
#else
assert(false && "Failed to lock an instance of RTT::os::MutexRecursive");
#endif
}

virtual void unlock()
{
rtos_mutex_rec_unlock( &recm );
int ret = rtos_mutex_rec_unlock( &recm );
if ( ret == 0 )
return;
#ifndef ORO_EMBEDDED
throw boost::system::system_error(-ret, boost::system::system_category(),
"Failed to unlock an instance of RTT::os::MutexRecursive");
#else
assert(false && "Failed to unlock an instance of RTT::os::MutexRecursive");
#endif
}

/**
Expand All @@ -259,9 +331,18 @@ namespace RTT
*/
virtual bool trylock()
{
if ( rtos_mutex_rec_trylock( &recm ) == 0 )
int ret = rtos_mutex_rec_trylock( &recm );
if ( ret == 0 )
return true;
if ( ret == -EBUSY || ret == -EWOULDBLOCK || ret == -ETIMEDOUT || ret == -EINTR )
return false;
#ifndef ORO_EMBEDDED
throw boost::system::system_error(-ret, boost::system::system_category(),
"Failed to lock an instance of RTT::os::MutexRecursive");
#else
assert(false && "Failed to lock an instance of RTT::os::MutexRecursive");
return false;
#endif
}

/**
Expand All @@ -273,9 +354,18 @@ namespace RTT
*/
virtual bool timedlock(Seconds s)
{
if ( rtos_mutex_rec_trylock_for( &recm, Seconds_to_nsecs(s) ) == 0 )
int ret = rtos_mutex_rec_trylock_for( &recm, Seconds_to_nsecs(s) );
if ( ret == 0 )
return true;
if ( ret == -EBUSY || ret == -EWOULDBLOCK || ret == -ETIMEDOUT || ret == -EINTR )
return false;
#ifndef ORO_EMBEDDED
throw boost::system::system_error(-ret, boost::system::system_category(),
"Failed to lock an instance of RTT::os::MutexRecursive");
#else
assert(false && "Failed to lock an instance of RTT::os::MutexRecursive");
return false;
#endif
}
#else
protected:
Expand Down
Loading