|
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