$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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();
+}