1
0
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:
Daniel Collins 2018-10-16 13:23:48 +01:00
parent 0239e5357d
commit dd6488969e
2 changed files with 18 additions and 13 deletions

View File

@ -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();
})); }));

View File

@ -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;