1
0
mirror of https://github.com/solemnwarning/directplay-lite synced 2024-12-30 16:45:37 +01:00

IDirectPlay8Peer: Complete asynchronous sends in the worker pool.

Starting threads is expensive, far too expensive to be doing it
on every asynchronous SendTo() call.
This commit is contained in:
Daniel Collins 2018-11-27 18:50:44 +00:00
parent 1837aa1915
commit 8d46ae9e9b
2 changed files with 38 additions and 5 deletions

View File

@ -124,6 +124,7 @@ HRESULT DirectPlay8Peer::Initialize(PVOID CONST pvUserContext, CONST PFNDPNMESSA
worker_pool->add_handle(udp_socket_event, [this]() { handle_udp_socket_event(); });
worker_pool->add_handle(other_socket_event, [this]() { handle_other_socket_event(); });
worker_pool->add_handle(work_ready, [this]() { handle_work(); });
state = STATE_INITIALISED;
@ -832,9 +833,7 @@ HRESULT DirectPlay8Peer::SendTo(CONST DPNID dpnid, CONST DPN_BUFFER_DESC* CONST
unsigned char *payload_copy = new unsigned char[payload_size];
memcpy(payload_copy, payload.data(), payload_size);
/* TODO: Do this in a properly managed worker thread. */
std::thread t([this, payload_size, payload_copy, handle_send_complete, dwFlags]()
queue_work([this, payload_size, payload_copy, handle_send_complete, dwFlags]()
{
std::unique_lock<std::mutex> l(lock);
@ -861,8 +860,6 @@ HRESULT DirectPlay8Peer::SendTo(CONST DPNID dpnid, CONST DPN_BUFFER_DESC* CONST
handle_send_complete(l, S_OK);
});
t.detach();
}
return DPNSUCCESS_PENDING;
@ -3189,6 +3186,35 @@ void DirectPlay8Peer::handle_other_socket_event()
peer_accept(l);
}
void DirectPlay8Peer::queue_work(const std::function<void()> &work)
{
work_queue.push(work);
SetEvent(work_ready);
}
void DirectPlay8Peer::handle_work()
{
std::unique_lock<std::mutex> l(lock);
if(!work_queue.empty())
{
std::function<void()> work = work_queue.front();
work_queue.pop();
if(!work_queue.empty())
{
/* Wake up another thread, in case we are heavily loaded and the pool isn't
* keeping up with the events from queue_work()
*/
SetEvent(work_ready);
}
l.unlock();
work();
}
}
void DirectPlay8Peer::io_peer_triggered(unsigned int peer_id)
{
std::unique_lock<std::mutex> l(lock);

View File

@ -7,6 +7,7 @@
#include <map>
#include <mutex>
#include <objbase.h>
#include <queue>
#include <stdint.h>
#include <windows.h>
@ -69,6 +70,9 @@ class DirectPlay8Peer: public IDirectPlay8Peer
HandleHandlingPool *worker_pool;
std::queue< std::function<void()> > work_queue;
EventObject work_ready;
SendQueue udp_sq;
struct Peer
@ -207,6 +211,9 @@ class DirectPlay8Peer: public IDirectPlay8Peer
void io_udp_send(std::unique_lock<std::mutex> &l);
void handle_other_socket_event();
void queue_work(const std::function<void()> &work);
void handle_work();
void io_peer_triggered(unsigned int peer_id);
void io_peer_connected(std::unique_lock<std::mutex> &l, unsigned int peer_id);
void io_peer_send(std::unique_lock<std::mutex> &l, unsigned int peer_id);