mirror of
https://github.com/solemnwarning/directplay-lite
synced 2024-12-30 16:45:37 +01:00
Track and wait for synchronous EnumHosts() calls in Close()
This commit is contained in:
parent
0239e5357d
commit
dd6488969e
@ -200,7 +200,7 @@ HRESULT DirectPlay8Peer::CancelAsyncOperation(CONST DPNHANDLE hAsyncHandle, CONS
|
|||||||
|
|
||||||
if(dwFlags & (DPNCANCEL_ENUM | DPNCANCEL_ALL_OPERATIONS))
|
if(dwFlags & (DPNCANCEL_ENUM | DPNCANCEL_ALL_OPERATIONS))
|
||||||
{
|
{
|
||||||
for(auto ei = host_enums.begin(); ei != host_enums.end(); ++ei)
|
for(auto ei = async_host_enums.begin(); ei != async_host_enums.end(); ++ei)
|
||||||
{
|
{
|
||||||
ei->second.cancel();
|
ei->second.cancel();
|
||||||
}
|
}
|
||||||
@ -224,8 +224,8 @@ HRESULT DirectPlay8Peer::CancelAsyncOperation(CONST DPNHANDLE hAsyncHandle, CONS
|
|||||||
}
|
}
|
||||||
else if((hAsyncHandle & AsyncHandleAllocator::TYPE_MASK) == AsyncHandleAllocator::TYPE_ENUM)
|
else if((hAsyncHandle & AsyncHandleAllocator::TYPE_MASK) == AsyncHandleAllocator::TYPE_ENUM)
|
||||||
{
|
{
|
||||||
auto ei = host_enums.find(hAsyncHandle);
|
auto ei = async_host_enums.find(hAsyncHandle);
|
||||||
if(ei == host_enums.end())
|
if(ei == async_host_enums.end())
|
||||||
{
|
{
|
||||||
return DPNERR_INVALIDHANDLE;
|
return DPNERR_INVALIDHANDLE;
|
||||||
}
|
}
|
||||||
@ -1473,8 +1473,8 @@ HRESULT DirectPlay8Peer::Close(CONST DWORD dwFlags)
|
|||||||
case STATE_TERMINATED: break;
|
case STATE_TERMINATED: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Signal all EnumHosts() calls to complete. */
|
/* Signal all asynchronous EnumHosts() calls to complete. */
|
||||||
for(auto ei = host_enums.begin(); ei != host_enums.end(); ++ei)
|
for(auto ei = async_host_enums.begin(); ei != async_host_enums.end(); ++ei)
|
||||||
{
|
{
|
||||||
ei->second.cancel();
|
ei->second.cancel();
|
||||||
}
|
}
|
||||||
@ -1523,7 +1523,7 @@ HRESULT DirectPlay8Peer::Close(CONST DWORD dwFlags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for outstanding EnumHosts() calls. */
|
/* Wait for outstanding EnumHosts() calls. */
|
||||||
host_enum_completed.wait(l, [this]() { return host_enums.empty(); });
|
host_enum_completed.wait(l, [this]() { return async_host_enums.empty() && sync_host_enums.empty(); });
|
||||||
|
|
||||||
/* We need to release the lock while the worker_pool destructor runs so that any worker
|
/* We need to release the lock while the worker_pool destructor runs so that any worker
|
||||||
* threads waiting for it can finish. No other thread should mess with it while we are in
|
* threads waiting for it can finish. No other thread should mess with it while we are in
|
||||||
@ -1553,11 +1553,9 @@ HRESULT DirectPlay8Peer::EnumHosts(PDPN_APPLICATION_DESC CONST pApplicationDesc,
|
|||||||
try {
|
try {
|
||||||
if(dwFlags & DPNENUMHOSTS_SYNC)
|
if(dwFlags & DPNENUMHOSTS_SYNC)
|
||||||
{
|
{
|
||||||
/* TODO: Instantiate synchronous instances in host_enums. */
|
|
||||||
|
|
||||||
HRESULT result;
|
HRESULT result;
|
||||||
|
|
||||||
HostEnumerator he(
|
sync_host_enums.emplace_front(
|
||||||
global_refcount,
|
global_refcount,
|
||||||
message_handler, message_handler_ctx,
|
message_handler, message_handler_ctx,
|
||||||
pApplicationDesc, pAddrHost, pDeviceInfo, pUserEnumData, dwUserEnumDataSize,
|
pApplicationDesc, pAddrHost, pDeviceInfo, pUserEnumData, dwUserEnumDataSize,
|
||||||
@ -1568,8 +1566,14 @@ HRESULT DirectPlay8Peer::EnumHosts(PDPN_APPLICATION_DESC CONST pApplicationDesc,
|
|||||||
result = r;
|
result = r;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
std::list<HostEnumerator>::iterator he = sync_host_enums.begin();
|
||||||
|
|
||||||
l.unlock();
|
l.unlock();
|
||||||
he.wait();
|
he->wait();
|
||||||
|
l.lock();
|
||||||
|
|
||||||
|
sync_host_enums.erase(he);
|
||||||
|
host_enum_completed.notify_all();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1578,7 +1582,7 @@ HRESULT DirectPlay8Peer::EnumHosts(PDPN_APPLICATION_DESC CONST pApplicationDesc,
|
|||||||
|
|
||||||
*pAsyncHandle = handle;
|
*pAsyncHandle = handle;
|
||||||
|
|
||||||
host_enums.emplace(
|
async_host_enums.emplace(
|
||||||
std::piecewise_construct,
|
std::piecewise_construct,
|
||||||
std::forward_as_tuple(handle),
|
std::forward_as_tuple(handle),
|
||||||
std::forward_as_tuple(
|
std::forward_as_tuple(
|
||||||
@ -1600,7 +1604,7 @@ HRESULT DirectPlay8Peer::EnumHosts(PDPN_APPLICATION_DESC CONST pApplicationDesc,
|
|||||||
message_handler(message_handler_ctx, DPN_MSGID_ASYNC_OP_COMPLETE, &oc);
|
message_handler(message_handler_ctx, DPN_MSGID_ASYNC_OP_COMPLETE, &oc);
|
||||||
|
|
||||||
std::unique_lock<std::mutex> l(lock);
|
std::unique_lock<std::mutex> l(lock);
|
||||||
host_enums.erase(handle);
|
async_host_enums.erase(handle);
|
||||||
|
|
||||||
host_enum_completed.notify_all();
|
host_enum_completed.notify_all();
|
||||||
}));
|
}));
|
||||||
|
@ -43,7 +43,8 @@ class DirectPlay8Peer: public IDirectPlay8Peer
|
|||||||
|
|
||||||
AsyncHandleAllocator handle_alloc;
|
AsyncHandleAllocator handle_alloc;
|
||||||
|
|
||||||
std::map<DPNHANDLE, HostEnumerator> host_enums;
|
std::map<DPNHANDLE, HostEnumerator> async_host_enums;
|
||||||
|
std::list<HostEnumerator> sync_host_enums;
|
||||||
std::condition_variable host_enum_completed;
|
std::condition_variable host_enum_completed;
|
||||||
|
|
||||||
GUID instance_guid;
|
GUID instance_guid;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user