Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r66258 - in sandbox/SOC/2010/process: boost/process/detail libs/process/test libs/process/test/util
From: boris_at_[hidden]
Date: 2010-10-29 18:22:07


Author: bschaeling
Date: 2010-10-29 18:22:04 EDT (Fri, 29 Oct 2010)
New Revision: 66258
URL: http://svn.boost.org/trac/boost/changeset/66258

Log:
Fixed bug in worker thread of status service and added test case
Text files modified:
   sandbox/SOC/2010/process/boost/process/detail/basic_status_service.hpp | 21 +++++++++++-------
   sandbox/SOC/2010/process/boost/process/detail/status_impl.hpp | 5 +++
   sandbox/SOC/2010/process/libs/process/test/util/boost.hpp | 1
   sandbox/SOC/2010/process/libs/process/test/util/helpers.cpp | 16 ++++++++++++++
   sandbox/SOC/2010/process/libs/process/test/wait.cpp | 45 ++++++++++++++++++++++++++++++++++++++++
   5 files changed, 79 insertions(+), 9 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-10-29 18:22:04 EDT (Fri, 29 Oct 2010)
@@ -186,10 +186,11 @@
             else
             {
                 boost::unique_lock<boost::mutex> lock(work_thread_mutex_);
+ bool regchild = false;
                 for (typename std::vector<implementation_type>::iterator it =
                     impls_.begin(); it != impls_.end(); ++it)
- (*it)->complete(pid, status);
- if (--pids_ == 0)
+ regchild |= (*it)->complete(pid, status);
+ if (regchild && --pids_ == 0)
                 {
                     work_.reset();
                     break;
@@ -220,14 +221,18 @@
                     BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(
                         "GetExitCodeProcess() failed");
                 boost::unique_lock<boost::mutex> lock(work_thread_mutex_);
+ bool regchild = false;
                 for (std::vector<implementation_type>::iterator it =
                     impls_.begin(); it != impls_.end(); ++it)
- (*it)->complete(handle, exit_code);
- std::vector<HANDLE>::iterator it = handles_.begin();
- std::advance(it, res - WAIT_OBJECT_0);
- handles_.erase(it);
- if (handles_.size() == 1)
- work_.reset();
+ regchild |= (*it)->complete(handle, exit_code);
+ if (regchild)
+ {
+ std::vector<HANDLE>::iterator it = handles_.begin();
+ std::advance(it, res - WAIT_OBJECT_0);
+ handles_.erase(it);
+ if (handles_.size() == 1)
+ work_.reset();
+ }
             }
         }
 #endif

Modified: sandbox/SOC/2010/process/boost/process/detail/status_impl.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/detail/status_impl.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/detail/status_impl.hpp 2010-10-29 18:22:04 EDT (Fri, 29 Oct 2010)
@@ -161,10 +161,12 @@
         ops_.insert(ph, new wrapped_handler<Handler>(handler));
     }
 
- void complete(phandle ph, int exit_code)
+ bool complete(phandle ph, int exit_code)
     {
         boost::iterator_range<operations_type::iterator> r =
             ops_.equal_range(ph);
+ if (r.begin() == r.end())
+ return false;
         for (operations_type::iterator it = r.begin(); it != r.end(); ++it)
             (*it->second)(exit_code);
         ops_.erase(r.begin(), r.end());
@@ -172,6 +174,7 @@
         if (!CloseHandle(ph))
             BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CloseHandle() failed");
 #endif
+ return true;
     }
 
 private:

Modified: sandbox/SOC/2010/process/libs/process/test/util/boost.hpp
==============================================================================
--- sandbox/SOC/2010/process/libs/process/test/util/boost.hpp (original)
+++ sandbox/SOC/2010/process/libs/process/test/util/boost.hpp 2010-10-29 18:22:04 EDT (Fri, 29 Oct 2010)
@@ -19,6 +19,7 @@
 #include <boost/test/included/unit_test.hpp>
 #include <boost/filesystem.hpp>
 #include <boost/asio.hpp>
+#include <boost/thread.hpp>
 #include <boost/bind.hpp>
 #include <boost/ref.hpp>
 #include <boost/lexical_cast.hpp>

Modified: sandbox/SOC/2010/process/libs/process/test/util/helpers.cpp
==============================================================================
--- sandbox/SOC/2010/process/libs/process/test/util/helpers.cpp (original)
+++ sandbox/SOC/2010/process/libs/process/test/util/helpers.cpp 2010-10-29 18:22:04 EDT (Fri, 29 Oct 2010)
@@ -14,6 +14,7 @@
 #include <boost/process/config.hpp>
 
 #if defined(BOOST_POSIX_API)
+# include <unistd.h>
 # include <stdlib.h>
 #elif defined(BOOST_WINDOWS_API)
 # include <windows.h>
@@ -23,6 +24,7 @@
 
 #include <boost/process/detail/systembuf.hpp>
 #include <boost/filesystem.hpp>
+#include <boost/lexical_cast.hpp>
 #include <iostream>
 #include <string>
 #include <cstdlib>
@@ -69,6 +71,19 @@
     return EXIT_SUCCESS;
 }
 
+int h_wait_exit(int argc, char *argv[])
+{
+ int sec = boost::lexical_cast<int>(argv[1]);
+
+#if defined(BOOST_POSIX_API)
+ sleep(sec);
+#elif defined(BOOST_WINDOWS_API)
+ Sleep(sec * 1000);
+#endif
+
+ return EXIT_SUCCESS;
+}
+
 int h_is_closed_stdin(int argc, char *argv[])
 {
     std::string word;
@@ -243,6 +258,7 @@
     { "echo-stdout-stderr", h_echo_stdout_stderr, 2, "message" },
     { "exit-failure", h_exit_failure, 1, "" },
     { "exit-success", h_exit_success, 1, "" },
+ { "wait-exit", h_wait_exit, 2, "integer" },
     { "is-closed-stdin", h_is_closed_stdin, 1, "" },
     { "is-closed-stdout", h_is_closed_stdout, 1, "" },
     { "is-closed-stderr", h_is_closed_stderr, 1, "" },

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-10-29 18:22:04 EDT (Fri, 29 Oct 2010)
@@ -130,6 +130,51 @@
     ioservice.run();
 }
 
+void start_child()
+{
+ std::vector<std::string> args;
+ args.push_back("wait-exit");
+ args.push_back("1");
+
+ bp::child c = bp::create_child(get_helpers_path(), args);
+ c.wait();
+}
+
+void handler2(boost::system::error_code ec, int exit_code, bool &called)
+{
+ called = true;
+ BOOST_REQUIRE_EQUAL(ec, boost::system::error_code());
+#if defined(BOOST_POSIX_API)
+ BOOST_REQUIRE(WIFEXITED(exit_code));
+ BOOST_CHECK_EQUAL(WEXITSTATUS(exit_code), EXIT_SUCCESS);
+#elif defined(BOOST_WINDOWS_API)
+ BOOST_CHECK_EQUAL(exit_code, EXIT_SUCCESS);
+#endif
+}
+
+BOOST_AUTO_TEST_CASE(test_status_sync_and_async_wait)
+{
+ check_helpers();
+
+ bool called = false;
+
+ ba::io_service ioservice;
+ bp::status s(ioservice);
+
+ std::vector<std::string> args;
+ args.push_back("wait-exit");
+ args.push_back("2");
+
+ bp::child c = bp::create_child(get_helpers_path(), args);
+ s.async_wait(c.get_id(), boost::bind(handler2, _1, _2, boost::ref(called)));
+
+ boost::thread(start_child);
+
+ ioservice.run();
+
+ BOOST_CHECK_EQUAL(called, true);
+}
+
 BOOST_AUTO_TEST_CASE(test_status_async_wait_shutdown)
 {
     check_helpers();


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