Boost logo

Boost :

From: Rodolfo Schulz de Lima (rodolfo_at_[hidden])
Date: 2004-10-02 19:18:08


Hi, I've been using boost::threads for some time now and found it to be
very useful and elegant in design. The only problem I see is when it
throws an exception. No information about the error is fed to the
exception constructor, and all we have is a
'boost::thread_resource_error' or a 'boost::lock_error' in
std::exception::what, not very helpful. Since boost::thread_exception
has a constructor that accepts an error code, I've managed to patch some
files and fed (where appropriate) the error code to the exception
constructor so that we can have an idea of what is the cause of the
exception when we catch it.

Not being fully satisfied with the results (we never are), I went a little
further and decided to make thread_exception inherit from
std::runtime_error, and pass to its constructor an informative message
about the exception. This way std::exception::what will show not only
the exception class name, but also the reason of the error (if we have
an error core). I've modified the other exception classes accordingly.

The last thing I did was to remove thread_argument_error since we could
use std::argument_error instead. In fact, this class is never used, and
in the only place that it would be used, std::argument_error is used.

I'd appreciate any comments about those changes...

Regards,
rod

IMPORTANT NOTE: I've just changed the PTHREADS implementation... I
do not have good background on winthreads and mptasks, so I count on
anyone who knows those systems to update their implementation...

// Patch follows

Index: boost/thread/exceptions.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/thread/exceptions.hpp,v
retrieving revision 1.14
diff -u -r1.14 exceptions.hpp
--- boost/thread/exceptions.hpp 8 Sep 2004 15:57:03 -0000 1.14
+++ boost/thread/exceptions.hpp 2 Oct 2004 23:51:50 -0000
@@ -25,11 +25,11 @@
 
 namespace boost {
 
-class BOOST_THREAD_DECL thread_exception : public std::exception
+class BOOST_THREAD_DECL thread_exception : public std::runtime_error
 {
 protected:
     thread_exception();
- thread_exception(int sys_err_code);
+ thread_exception(std::string message, int sys_err_code=0);
 
 public:
     ~thread_exception() throw();
@@ -48,8 +48,6 @@
     lock_error();
     lock_error(int sys_err_code);
     ~lock_error() throw();
-
- virtual const char* what() const throw();
 };
 
 class BOOST_THREAD_DECL thread_resource_error : public thread_exception
@@ -58,8 +56,6 @@
     thread_resource_error();
     thread_resource_error(int sys_err_code);
     ~thread_resource_error() throw();
-
- virtual const char* what() const throw();
 };
 
 class BOOST_THREAD_DECL unsupported_thread_option : public thread_exception
@@ -68,18 +64,6 @@
     unsupported_thread_option();
     unsupported_thread_option(int sys_err_code);
     ~unsupported_thread_option() throw();
-
- virtual const char* what() const throw();
-};
-
-class BOOST_THREAD_DECL invalid_thread_argument : public thread_exception
-{
-public:
- invalid_thread_argument();
- invalid_thread_argument(int sys_err_code);
- ~invalid_thread_argument() throw();
-
- virtual const char* what() const throw();
 };
 
 class BOOST_THREAD_DECL thread_permission_error : public thread_exception
@@ -88,8 +72,6 @@
     thread_permission_error();
     thread_permission_error(int sys_err_code);
     ~thread_permission_error() throw();
-
- virtual const char* what() const throw();
 };
 
 } // namespace boost
Index: libs/thread/src/condition.cpp
===================================================================
RCS file: /cvsroot/boost/boost/libs/thread/src/condition.cpp,v
retrieving revision 1.20
diff -u -r1.20 condition.cpp
--- libs/thread/src/condition.cpp 17 Jul 2004 04:33:59 -0000 1.20
+++ libs/thread/src/condition.cpp 2 Oct 2004 23:51:58 -0000
@@ -340,7 +340,7 @@
     int res = 0;
     res = pthread_cond_init(&m_condition, 0);
     if (res != 0)
- throw thread_resource_error();
+ throw thread_resource_error(res);
 }
 
 condition_impl::~condition_impl()
Index: libs/thread/src/exceptions.cpp
===================================================================
RCS file: /cvsroot/boost/boost/libs/thread/src/exceptions.cpp,v
retrieving revision 1.10
diff -u -r1.10 exceptions.cpp
--- libs/thread/src/exceptions.cpp 8 Sep 2004 15:56:33 -0000 1.10
+++ libs/thread/src/exceptions.cpp 2 Oct 2004 23:51:58 -0000
@@ -69,12 +69,15 @@
 namespace boost {
 
 thread_exception::thread_exception()
- : m_sys_err(0)
+ : runtime_error("boost;:thread_exception")
+ , m_sys_err(0)
 {
 }
 
-thread_exception::thread_exception(int sys_err_code)
- : m_sys_err(sys_err_code)
+thread_exception::thread_exception(std::string message, int sys_err_code)
+ : std::runtime_error(message+(sys_err_code==0
+ ? "" : (": "+system_message(m_sys_err)).c_str()))
+ , m_sys_err(sys_err_code)
 {
 }
 
@@ -89,17 +92,16 @@
 
 const char* thread_exception::message() const
 {
- if (m_sys_err != 0)
- return system_message(m_sys_err).c_str();
     return what();
 }
 
 lock_error::lock_error()
+ : thread_exception("boost::lock_error")
 {
 }
 
 lock_error::lock_error(int sys_err_code)
- : thread_exception(sys_err_code)
+ : thread_exception("boost::lock_error",sys_err_code)
 {
 }
 
@@ -107,17 +109,13 @@
 {
 }
 
-const char* lock_error::what() const throw()
-{
- return "boost::lock_error";
-}
-
-thread_resource_error::thread_resource_error()
+thread_resource_error::thread_resource_error()
+ : thread_exception("boost::thread_resource_error")
 {
 }
 
 thread_resource_error::thread_resource_error(int sys_err_code)
- : thread_exception(sys_err_code)
+ : thread_exception("boost::thread_resource_error",sys_err_code)
 {
 }
 
@@ -125,17 +123,13 @@
 {
 }
 
-const char* thread_resource_error::what() const throw()
-{
- return "boost::thread_resource_error";
-}
-
 unsupported_thread_option::unsupported_thread_option()
+ : thread_exception("boost::unsupported_thread_option")
 {
 }
 
 unsupported_thread_option::unsupported_thread_option(int sys_err_code)
- : thread_exception(sys_err_code)
+ : thread_exception("boost::unsupported_thread_option",sys_err_code)
 {
 }
 
@@ -143,35 +137,13 @@
 {
 }
 
-const char* unsupported_thread_option::what() const throw()
-{
- return "boost::unsupported_thread_option";
-}
-
-invalid_thread_argument::invalid_thread_argument()
-{
-}
-
-invalid_thread_argument::invalid_thread_argument(int sys_err_code)
- : thread_exception(sys_err_code)
-{
-}
-
-invalid_thread_argument::~invalid_thread_argument() throw()
-{
-}
-
-const char* invalid_thread_argument::what() const throw()
-{
- return "boost::invalid_thread_argument";
-}
-
 thread_permission_error::thread_permission_error()
+ : thread_exception("boost::thread_permission_error")
 {
 }
 
 thread_permission_error::thread_permission_error(int sys_err_code)
- : thread_exception(sys_err_code)
+ : thread_exception("boost::thread_permission_error",sys_err_code)
 {
 }
 
@@ -179,9 +151,4 @@
 {
 }
 
-const char* thread_permission_error::what() const throw()
-{
- return "boost::thread_permission_error";
-}
-
 } // namespace boost
Index: libs/thread/src/mutex.cpp
===================================================================
RCS file: /cvsroot/boost/boost/libs/thread/src/mutex.cpp,v
retrieving revision 1.19
diff -u -r1.19 mutex.cpp
--- libs/thread/src/mutex.cpp 29 Jul 2004 14:25:30 -0000 1.19
+++ libs/thread/src/mutex.cpp 2 Oct 2004 23:51:58 -0000
@@ -201,7 +201,7 @@
     int res = 0;
     res = pthread_mutex_init(&m_mutex, 0);
     if (res != 0)
- throw thread_resource_error();
+ throw thread_resource_error(res);
 }
 
 mutex::~mutex()
@@ -215,7 +215,7 @@
 {
     int res = 0;
     res = pthread_mutex_lock(&m_mutex);
- if (res == EDEADLK) throw lock_error();
+ if (res == EDEADLK) throw lock_error(res);
     assert(res == 0);
 }
 
@@ -223,7 +223,7 @@
 {
     int res = 0;
     res = pthread_mutex_unlock(&m_mutex);
- if (res == EPERM) throw lock_error();
+ if (res == EPERM) throw lock_error(res);
     assert(res == 0);
 }
 
@@ -241,7 +241,7 @@
     int res = 0;
     res = pthread_mutex_init(&m_mutex, 0);
     if (res != 0)
- throw thread_resource_error();
+ throw thread_resource_error(res);
 }
 
 try_mutex::~try_mutex()
@@ -255,7 +255,7 @@
 {
     int res = 0;
     res = pthread_mutex_lock(&m_mutex);
- if (res == EDEADLK) throw lock_error();
+ if (res == EDEADLK) throw lock_error(res);
     assert(res == 0);
 }
 
@@ -263,7 +263,7 @@
 {
     int res = 0;
     res = pthread_mutex_trylock(&m_mutex);
- if (res == EDEADLK) throw lock_error();
+ if (res == EDEADLK) throw lock_error(res);
     assert(res == 0 || res == EBUSY);
     return res == 0;
 }
@@ -272,7 +272,7 @@
 {
     int res = 0;
     res = pthread_mutex_unlock(&m_mutex);
- if (res == EPERM) throw lock_error();
+ if (res == EPERM) throw lock_error(res);
     assert(res == 0);
 }
 
@@ -291,13 +291,13 @@
     int res = 0;
     res = pthread_mutex_init(&m_mutex, 0);
     if (res != 0)
- throw thread_resource_error();
+ throw thread_resource_error(res);
 
     res = pthread_cond_init(&m_condition, 0);
     if (res != 0)
     {
         pthread_mutex_destroy(&m_mutex);
- throw thread_resource_error();
+ throw thread_resource_error(res);
     }
 }
 
Index: libs/thread/src/recursive_mutex.cpp
===================================================================
RCS file: /cvsroot/boost/boost/libs/thread/src/recursive_mutex.cpp,v
retrieving revision 1.22
diff -u -r1.22 recursive_mutex.cpp
--- libs/thread/src/recursive_mutex.cpp 16 Sep 2004 17:49:16 -0000 1.22
+++ libs/thread/src/recursive_mutex.cpp 2 Oct 2004 23:52:00 -0000
@@ -300,14 +300,14 @@
         assert(res == 0);
     }
     if (res != 0)
- throw thread_resource_error();
+ throw thread_resource_error(res);
 
 # if !defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
     res = pthread_cond_init(&m_unlocked, 0);
     if (res != 0)
     {
         pthread_mutex_destroy(&m_mutex);
- throw thread_resource_error();
+ throw thread_resource_error(res);
     }
 # endif
 }
@@ -377,7 +377,7 @@
     {
         res = pthread_mutex_unlock(&m_mutex);
         assert(res == 0);
- throw lock_error();
+ throw lock_error(res);
     }
 
     if (--m_count == 0)
@@ -456,14 +456,14 @@
         assert(res == 0);
     }
     if (res != 0)
- throw thread_resource_error();
+ throw thread_resource_error(res);
 
 # if !defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
     res = pthread_cond_init(&m_unlocked, 0);
     if (res != 0)
     {
         pthread_mutex_destroy(&m_mutex);
- throw thread_resource_error();
+ throw thread_resource_error(res);
     }
 # endif
 }
@@ -577,7 +577,7 @@
     {
         res = pthread_mutex_unlock(&m_mutex);
         assert(res == 0);
- throw lock_error();
+ throw lock_error(res);
     }
 
     if (--m_count == 0)
@@ -641,13 +641,13 @@
     int res = 0;
     res = pthread_mutex_init(&m_mutex, 0);
     if (res != 0)
- throw thread_resource_error();
+ throw thread_resource_error(res);
 
     res = pthread_cond_init(&m_unlocked, 0);
     if (res != 0)
     {
         pthread_mutex_destroy(&m_mutex);
- throw thread_resource_error();
+ throw thread_resource_error(res);
     }
 }
 
@@ -764,7 +764,7 @@
     {
         res = pthread_mutex_unlock(&m_mutex);
         assert(res == 0);
- throw lock_error();
+ throw lock_error(res);
     }
 
     if (--m_count == 0)
Index: libs/thread/src/thread.cpp
===================================================================
RCS file: /cvsroot/boost/boost/libs/thread/src/thread.cpp,v
retrieving revision 1.18
diff -u -r1.18 thread.cpp
--- libs/thread/src/thread.cpp 5 Aug 2004 17:31:14 -0000 1.18
+++ libs/thread/src/thread.cpp 2 Oct 2004 23:52:00 -0000
@@ -160,7 +160,7 @@
     int res = 0;
     res = pthread_create(&m_thread, 0, &thread_proxy, &param);
     if (res != 0)
- throw thread_resource_error();
+ throw thread_resource_error(res);
 #elif defined(BOOST_HAS_MPTASKS)
     threads::mac::detail::thread_init();
     threads::mac::detail::create_singletons();


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk