Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r65453 - in sandbox/SOC/2010/process: boost/process/detail libs/process/test
From: boris_at_[hidden]
Date: 2010-09-18 16:55:22


Author: bschaeling
Date: 2010-09-18 16:55:20 EDT (Sat, 18 Sep 2010)
New Revision: 65453
URL: http://svn.boost.org/trac/boost/changeset/65453

Log:
Fixed a bug when waiting asynchronously for a process to terminate on POSIX
Text files modified:
   sandbox/SOC/2010/process/boost/process/detail/basic_status_service.hpp | 22 +++++++++++----
   sandbox/SOC/2010/process/libs/process/test/wait.cpp | 54 ++++++++++++++++++++++++++++++++++++++++
   2 files changed, 70 insertions(+), 6 deletions(-)

Modified: sandbox/SOC/2010/process/boost/process/detail/basic_status_service.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/detail/basic_status_service.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/detail/basic_status_service.hpp 2010-09-18 16:55:20 EDT (Sat, 18 Sep 2010)
@@ -24,6 +24,7 @@
 
 #if defined(BOOST_POSIX_API)
 # include <boost/process/operations.hpp>
+# include <string>
 # include <sys/types.h>
 # include <sys/wait.h>
 #elif defined(BOOST_WINDOWS_API)
@@ -77,7 +78,10 @@
     ~basic_status_service()
     {
 #if defined(BOOST_POSIX_API)
- if (work_thread_.joinable())
+ boost::unique_lock<boost::mutex> lock(work_thread_mutex_);
+ bool worker_thread_active = (pids_ != 0);
+ lock.unlock();
+ if (worker_thread_active)
         {
             stop_work_thread();
             work_thread_.join();
@@ -121,14 +125,14 @@
     {
 #if defined(BOOST_POSIX_API)
         boost::unique_lock<boost::mutex> lock(work_thread_mutex_);
- if (!work_)
+ if (++pids_ == 1)
+ {
             work_.reset(new boost::asio::io_service::work(
                 this->get_io_service()));
- ++pids_;
- if (!work_thread_.joinable())
             work_thread_ = boost::thread(
                 &basic_status_service<StatusImplementation>::work_thread,
                 this);
+ }
         impl->async_wait(pid, this->get_io_service().wrap(handler));
 #elif defined(BOOST_WINDOWS_API)
         HANDLE handle = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION,
@@ -155,7 +159,7 @@
     void work_thread()
     {
 #if defined(BOOST_POSIX_API)
- while (pids_)
+ for (;;)
         {
             int status;
             pid_t pid = ::wait(&status);
@@ -176,7 +180,10 @@
                     impls_.begin(); it != impls_.end(); ++it)
                     (*it)->complete(pid, status);
                 if (--pids_ == 0)
+ {
                     work_.reset();
+ break;
+ }
             }
         }
 #elif defined(BOOST_WINDOWS_API)
@@ -221,7 +228,10 @@
 #if defined(BOOST_POSIX_API)
         // By creating a child process which immediately exits
         // we interrupt wait().
- interrupt_pid_ = create_child("/bin/sh").get_id();
+ std::vector<std::string> args;
+ args.push_back("-c");
+ args.push_back("'exit'");
+ interrupt_pid_ = create_child("/bin/sh", args).get_id();
 #elif defined(BOOST_WINDOWS_API)
         // By signaling the event in the first slot WaitForMultipleObjects()
         // will return. The work thread won't do anything except checking if

Modified: sandbox/SOC/2010/process/libs/process/test/wait.cpp
==============================================================================
--- sandbox/SOC/2010/process/libs/process/test/wait.cpp (original)
+++ sandbox/SOC/2010/process/libs/process/test/wait.cpp 2010-09-18 16:55:20 EDT (Sat, 18 Sep 2010)
@@ -91,3 +91,57 @@
     s.async_wait(c.get_id(), handler);
     ioservice.run();
 }
+
+BOOST_AUTO_TEST_CASE(test_status_async_wait_for_two_child_processes)
+{
+ check_helpers();
+
+ std::vector<std::string> args;
+ args.push_back("exit-success");
+
+ bp::child c1 = bp::create_child(get_helpers_path(), args);
+ bp::child c2 = bp::create_child(get_helpers_path(), args);
+
+ ba::io_service ioservice;
+ bp::status s(ioservice);
+ s.async_wait(c1.get_id(), handler);
+ s.async_wait(c2.get_id(), handler);
+ ioservice.run();
+}
+
+BOOST_AUTO_TEST_CASE(test_status_async_wait_twice)
+{
+ check_helpers();
+
+ std::vector<std::string> args;
+ args.push_back("exit-success");
+
+ ba::io_service ioservice;
+ bp::status s(ioservice);
+
+ bp::child c1 = bp::create_child(get_helpers_path(), args);
+ s.async_wait(c1.get_id(), handler);
+ ioservice.run();
+
+ bp::child c2 = bp::create_child(get_helpers_path(), args);
+ s.async_wait(c2.get_id(), handler);
+ ioservice.run();
+}
+
+BOOST_AUTO_TEST_CASE(test_status_async_wait_shutdown)
+{
+ check_helpers();
+
+ std::vector<std::string> args;
+ args.push_back("loop");
+
+ bp::child c = bp::create_child(get_helpers_path(), args);
+
+ {
+ ba::io_service ioservice;
+ bp::status s(ioservice);
+ s.async_wait(c.get_id(), handler);
+ }
+
+ c.terminate();
+}


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