ec = get_last_error();
return;
}
+}
+inline void associate_completion_port(::boost::winapi::HANDLE_ job,
+ ::boost::winapi::HANDLE_ io_port)
+{
+ workaround::JOBOBJECT_ASSOCIATE_COMPLETION_PORT_ port;
+ port.CompletionKey = job;
+ port.CompletionPort = io_port;
+ if (!workaround::set_information_job_object(
+ job,
+ workaround::JobObjectAssociateCompletionPortInformation_,
+ static_cast<void*>(&port),
+ sizeof(port)))
+ throw_last_error("SetInformationJobObject() failed");
}
-
struct group_handle
{
::boost::winapi::HANDLE_ _job_object;
+ ::boost::winapi::HANDLE_ _io_port;
typedef ::boost::winapi::HANDLE_ handle_t;
handle_t handle() const { return _job_object; }
explicit group_handle(handle_t h) :
- _job_object(h)
+ _job_object(h),
+ _io_port(::CreateIoCompletionPort(::boost::winapi::INVALID_HANDLE_VALUE_, nullptr, 0, 1))
{
enable_break_away(_job_object);
+ associate_completion_port(_job_object, _io_port);
}
~group_handle()
{
::boost::winapi::CloseHandle(_job_object);
+ ::boost::winapi::CloseHandle(_io_port);
}
group_handle(const group_handle & c) = delete;
- group_handle(group_handle && c) : _job_object(c._job_object)
+ group_handle(group_handle && c) : _job_object(c._job_object),
+ _io_port(c._io_port)
{
c._job_object = ::boost::winapi::invalid_handle_value;
+ c._io_port = ::boost::winapi::invalid_handle_value;
}
group_handle &operator=(const group_handle & c) = delete;
group_handle &operator=(group_handle && c)
{
+ ::boost::winapi::CloseHandle(_io_port);
+ _io_port = c._io_port;
+ c._io_port = ::boost::winapi::invalid_handle_value;
::boost::winapi::CloseHandle(_job_object);
_job_object = c._job_object;