Boost logo

Boost :

From: Christopher Currie (christopher_at_[hidden])
Date: 2003-05-22 13:24:46


All,

I believe there is a bug in the BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE
implementation of recursive_try_mutex::do_trylock. The bug is the result
of an invalid assertion, that pthread_mutex_trylock should always return
0. The attached test case demonstrates the error. If the following patch
is applied, this test runs without errors. Comments and corrections are
appreciated.

Thanks,
Christopher Currie

ccurrie_at_thunderbird [14:21:27] [~/src/boost/libs/thread/src]
$ cvs diff -c recursive_mutex.cpp
Index: recursive_mutex.cpp
===================================================================
RCS file: /cvsroot/boost/boost/libs/thread/src/recursive_mutex.cpp,v
retrieving revision 1.13
diff -c -r1.13 recursive_mutex.cpp
*** recursive_mutex.cpp 23 Feb 2003 17:38:11 -0000 1.13
--- recursive_mutex.cpp 22 May 2003 18:22:40 -0000
***************
*** 495,501 ****
   # if defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
       int res = 0;
       res = pthread_mutex_trylock(&m_mutex);
! assert(res == 0);

       if (res == 0)
       {
--- 495,501 ----
   # if defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
       int res = 0;
       res = pthread_mutex_trylock(&m_mutex);
! assert( (res == 0) || (res == EBUSY) );

       if (res == 0)
       {


// Copyright (C) 2003
// Christopher Currie, William E. Kempf
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. The authors make no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.

#include <boost/bind.hpp>
#include <boost/thread/recursive_mutex.hpp>
#include <boost/thread/thread.hpp>

#include <boost/test/unit_test.hpp>
#include <boost/test/unit_test_suite_ex.hpp>

#define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_sleep_only
#include "util.inl"

template <typename M>
struct try_lock_thread
{
    typedef M mutex_type;
    typedef typename M::scoped_try_lock try_lock_type;
    typedef void result_type;

    void operator()( mutex_type & mutex, bool first )
    {
      try_lock_type lock( mutex, false );
      BOOST_CHECK( first ? lock.try_lock() : !lock.try_lock() );
      if ( first )
        {
          boost::function0<void> function =
             boost::bind( try_lock_thread<mutex_type>(),
                          ref( mutex ),
                          false );
          boost::thread thread( function );
          thread.join();
        }
    }
};

void test_recursive_try_mutex()
{
    boost::recursive_try_mutex mutex;
    boost::function0<void> function =
      boost::bind( try_lock_thread<boost::recursive_try_mutex>(),
                   ref( mutex ),
                   true );
    boost::thread thread( function );
    thread.join();
}

boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
{
    boost::unit_test_framework::test_suite* test =
        BOOST_TEST_SUITE("Boost.Threads: recursive_try_mutex test case");

    test->add(BOOST_TEST_CASE(&test_recursive_try_mutex));

    return test;
}


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