Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r80076 - in trunk/libs/thread: src/pthread test
From: vicente.botet_at_[hidden]
Date: 2012-08-18 07:26:53


Author: viboes
Date: 2012-08-18 07:26:51 EDT (Sat, 18 Aug 2012)
New Revision: 80076
URL: http://svn.boost.org/trac/boost/changeset/80076

Log:
Thread: try to fix 7238
Added:
   trunk/libs/thread/test/test_3628.cpp (contents, props changed)
   trunk/libs/thread/test/test_7328.cpp (contents, props changed)
Text files modified:
   trunk/libs/thread/src/pthread/thread.cpp | 25 +++++++++++++++++++------
   trunk/libs/thread/test/Jamfile.v2 | 2 ++
   2 files changed, 21 insertions(+), 6 deletions(-)

Modified: trunk/libs/thread/src/pthread/thread.cpp
==============================================================================
--- trunk/libs/thread/src/pthread/thread.cpp (original)
+++ trunk/libs/thread/src/pthread/thread.cpp 2012-08-18 07:26:51 EDT (Sat, 18 Aug 2012)
@@ -432,24 +432,37 @@
         sleep_for(const chrono::nanoseconds& ns)
         {
             using namespace chrono;
- if (ns >= nanoseconds::zero())
+ boost::detail::thread_data_base* const thread_info=boost::detail::get_current_thread_data();
+
+ if(thread_info)
+ {
+ unique_lock<mutex> lk(thread_info->sleep_mutex);
+ while(cv_status::no_timeout==thread_info->sleep_condition.wait_for(lk,ns)) {}
+ }
+ else
             {
+ if (ns >= nanoseconds::zero())
+ {
+
+ # if defined(BOOST_HAS_PTHREAD_DELAY_NP)
                 timespec ts;
                 ts.tv_sec = static_cast<long>(duration_cast<seconds>(ns).count());
                 ts.tv_nsec = static_cast<long>((ns - seconds(ts.tv_sec)).count());
-
-# if defined(BOOST_HAS_PTHREAD_DELAY_NP)
                 BOOST_VERIFY(!pthread_delay_np(&ts));
-# elif defined(BOOST_HAS_NANOSLEEP)
+ # elif defined(BOOST_HAS_NANOSLEEP)
+ timespec ts;
+ ts.tv_sec = static_cast<long>(duration_cast<seconds>(ns).count());
+ ts.tv_nsec = static_cast<long>((ns - seconds(ts.tv_sec)).count());
                 // nanosleep takes a timespec that is an offset, not
                 // an absolute time.
                 nanosleep(&ts, 0);
-# else
+ # else
                 mutex mx;
                 mutex::scoped_lock lock(mx);
                 condition_variable cond;
                 cond.wait_for(lock, ns);
-# endif
+ # endif
+ }
             }
         }
 #endif

Modified: trunk/libs/thread/test/Jamfile.v2
==============================================================================
--- trunk/libs/thread/test/Jamfile.v2 (original)
+++ trunk/libs/thread/test/Jamfile.v2 2012-08-18 07:26:51 EDT (Sat, 18 Aug 2012)
@@ -178,6 +178,7 @@
           [ thread-test test_2309.cpp ]
           [ thread-run test_2501.cpp ]
           [ thread-test test_2741.cpp ]
+ [ thread-run test_3628.cpp ]
           [ thread-run test_4521.cpp ]
           [ thread-run test_4648.cpp ]
           [ thread-run test_4882.cpp ]
@@ -189,6 +190,7 @@
           [ thread-run test_6170.cpp ]
           [ thread-run test_6174.cpp ]
           [ thread-run test_7160.cpp ]
+ [ thread-run test_7328.cpp ]
     ;
 
 

Added: trunk/libs/thread/test/test_3628.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/test/test_3628.cpp 2012-08-18 07:26:51 EDT (Sat, 18 Aug 2012)
@@ -0,0 +1,89 @@
+// Copyright (C) 2010 Vicente Botet
+//
+// 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)
+
+#include <boost/thread/thread.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/recursive_mutex.hpp>
+#include <list>
+#include <iostream>
+
+using namespace std;
+
+boost::recursive_mutex theMutex;
+
+typedef std::list<boost::condition*> Conditions;
+Conditions theConditions;
+
+void ThreadFuncWaiter()
+{
+ boost::condition con1;
+ //for(; ; )
+ for (int j = 0; j < 10; j++)
+ {
+ {
+ boost::recursive_mutex::scoped_lock lockMtx(theMutex);
+ theConditions.push_back(&con1);
+
+ cout << "Added " << boost::this_thread::get_id() << " " << &con1 << endl;
+ if (con1.timed_wait(lockMtx, boost::posix_time::time_duration(0, 0, 50)))
+ {
+ cout << "Woke Up " << boost::this_thread::get_id() << " " << &con1 << endl;
+ }
+ else
+ {
+ cout << "*****Timed Out " << boost::this_thread::get_id() << " " << &con1 << endl;
+ exit(13);
+ }
+
+ theConditions.remove(&con1);
+ cout << "Removed " << boost::this_thread::get_id() << " " << &con1 << endl;
+ cout << "Waiter " << j << endl;
+
+ }
+ //Sleep(2000);
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(200));
+ }
+}
+
+void ThreadFuncNotifier()
+{
+ for (int j = 0; j < 70; j++)
+ {
+ {
+ boost::recursive_mutex::scoped_lock lockMtx(theMutex);
+ cout << "<Notifier " << j << endl;
+
+ unsigned int i = 0;
+ for (Conditions::iterator it = theConditions.begin(); it != theConditions.end() && i < 2; ++it)
+ {
+ (*it)->notify_one();
+ //WORKAROUND_ lockMtx.unlock();
+ //WORKAROUND_ boost::this_thread::sleep_for(boost::chrono::milliseconds(50));
+ cout << "Notified One " << theConditions.size() << " " << (*it) << endl;
+ ++i;
+ //WORKAROUND_ lockMtx.lock();
+ }
+
+ cout << "Notifier> " << j << endl;
+ }
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(50));
+ }
+}
+
+int main()
+{
+ boost::thread_group tg;
+ for (int i = 0; i < 12; ++i)
+ {
+ tg.create_thread(ThreadFuncWaiter);
+ }
+
+ tg.create_thread(ThreadFuncNotifier);
+
+ tg.join_all();
+
+ return 0;
+}
+

Added: trunk/libs/thread/test/test_7328.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/test/test_7328.cpp 2012-08-18 07:26:51 EDT (Sat, 18 Aug 2012)
@@ -0,0 +1,39 @@
+// Copyright (C) 2010 Vicente Botet
+//
+// 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)
+
+#include <iostream>
+#include <boost/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+using namespace boost;
+using namespace boost::chrono;
+
+bool interrupted = false;
+void f()
+{
+ try
+ {
+ std::cout << "Starting sleep in thread" << std::endl;
+ while (true)
+ {
+ this_thread::sleep_for(seconds(60));
+ }
+ }
+ catch (const thread_interrupted&)
+ {
+ interrupted = true;
+ std::cout << "Thread interrupted." << std::endl;
+ }
+}
+
+int main()
+{
+ thread t(f);
+ t.interrupt();
+ t.join();
+ std::cout << "Joined with thread." << std::endl;
+ BOOST_TEST(interrupted);
+ return boost::report_errors();
+}


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk