|
|
@ -16,13 +16,12 @@ static CRITICAL_SECTION HandlerMtx;
|
|
|
|
std::list< win32_tun_io* > tun_listeners;
|
|
|
|
std::list< win32_tun_io* > tun_listeners;
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
|
begin_tun_loop(int nThreads)
|
|
|
|
begin_tun_loop(int nThreads, llarp_ev_loop* loop)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
kThreadPool = new HANDLE[nThreads];
|
|
|
|
kThreadPool = new HANDLE[nThreads];
|
|
|
|
for(int i = 0; i < nThreads; ++i)
|
|
|
|
for(int i = 0; i < nThreads; ++i)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
kThreadPool[i] =
|
|
|
|
kThreadPool[i] = CreateThread(nullptr, 0, &tun_ev_loop, loop, 0, nullptr);
|
|
|
|
CreateThread(nullptr, 0, &tun_ev_loop, nullptr, 0, nullptr);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
llarp::LogInfo("created ", nThreads, " threads for TUN event queue");
|
|
|
|
llarp::LogInfo("created ", nThreads, " threads for TUN event queue");
|
|
|
|
poolSize = nThreads;
|
|
|
|
poolSize = nThreads;
|
|
|
@ -74,7 +73,7 @@ win32_tun_io::setup()
|
|
|
|
|
|
|
|
|
|
|
|
// first TUN device gets to set up the event port
|
|
|
|
// first TUN device gets to set up the event port
|
|
|
|
bool
|
|
|
|
bool
|
|
|
|
win32_tun_io::add_ev()
|
|
|
|
win32_tun_io::add_ev(llarp_ev_loop* loop)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(tun_event_queue == INVALID_HANDLE_VALUE)
|
|
|
|
if(tun_event_queue == INVALID_HANDLE_VALUE)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -85,7 +84,7 @@ win32_tun_io::add_ev()
|
|
|
|
// threads
|
|
|
|
// threads
|
|
|
|
tun_event_queue = CreateIoCompletionPort(tunif->tun_fd, nullptr,
|
|
|
|
tun_event_queue = CreateIoCompletionPort(tunif->tun_fd, nullptr,
|
|
|
|
(ULONG_PTR)this, numCPU * 2);
|
|
|
|
(ULONG_PTR)this, numCPU * 2);
|
|
|
|
begin_tun_loop(numCPU * 2);
|
|
|
|
begin_tun_loop(numCPU * 2, loop);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
CreateIoCompletionPort(tunif->tun_fd, tun_event_queue, (ULONG_PTR)this, 0);
|
|
|
|
CreateIoCompletionPort(tunif->tun_fd, tun_event_queue, (ULONG_PTR)this, 0);
|
|
|
@ -106,7 +105,7 @@ win32_tun_io::do_write(void* data, size_t sz)
|
|
|
|
pkt->sz = sz;
|
|
|
|
pkt->sz = sz;
|
|
|
|
pkt->write = true;
|
|
|
|
pkt->write = true;
|
|
|
|
memset(&pkt->pkt, '\0', sizeof(pkt->pkt));
|
|
|
|
memset(&pkt->pkt, '\0', sizeof(pkt->pkt));
|
|
|
|
WriteFile(tunif->tun_fd, data, sz, nullptr, &pkt->pkt);
|
|
|
|
WriteFile(tunif->tun_fd, data, sz, nullptr, p & pkt->pkt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// while this one is called from the event loop
|
|
|
|
// while this one is called from the event loop
|
|
|
@ -131,9 +130,9 @@ win32_tun_io::read(byte_t* buf, size_t sz)
|
|
|
|
|
|
|
|
|
|
|
|
// and now the event loop itself
|
|
|
|
// and now the event loop itself
|
|
|
|
extern "C" DWORD FAR PASCAL
|
|
|
|
extern "C" DWORD FAR PASCAL
|
|
|
|
tun_ev_loop(void* unused)
|
|
|
|
tun_ev_loop(void* u)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
UNREFERENCED_PARAMETER(unused);
|
|
|
|
llarp_ev_loop* logic = static_cast< llarp_ev_loop* >(u);
|
|
|
|
|
|
|
|
|
|
|
|
DWORD size = 0;
|
|
|
|
DWORD size = 0;
|
|
|
|
OVERLAPPED* ovl = nullptr;
|
|
|
|
OVERLAPPED* ovl = nullptr;
|
|
|
@ -154,9 +153,11 @@ tun_ev_loop(void* unused)
|
|
|
|
for(const auto& tun : tun_listeners)
|
|
|
|
for(const auto& tun : tun_listeners)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
EnterCriticalSection(&HandlerMtx);
|
|
|
|
EnterCriticalSection(&HandlerMtx);
|
|
|
|
if(tun->t->tick)
|
|
|
|
logic->call_soon([tun = tun.get()]() {
|
|
|
|
tun->t->tick(tun->t);
|
|
|
|
if(tun->t->tick)
|
|
|
|
tun->flush_write();
|
|
|
|
tun->t->tick(tun->t);
|
|
|
|
|
|
|
|
tun->flush_write();
|
|
|
|
|
|
|
|
});
|
|
|
|
LeaveCriticalSection(&HandlerMtx);
|
|
|
|
LeaveCriticalSection(&HandlerMtx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
continue; // let's go at it once more
|
|
|
|
continue; // let's go at it once more
|
|
|
@ -178,8 +179,11 @@ tun_ev_loop(void* unused)
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// EnterCriticalSection(&HandlerMtx);
|
|
|
|
// EnterCriticalSection(&HandlerMtx);
|
|
|
|
if(ev->t->recvpkt)
|
|
|
|
logic->call_soon([pkt, size, ev]() {
|
|
|
|
ev->t->recvpkt(ev->t, llarp_buffer_t(pkt->buf, size));
|
|
|
|
if(ev->t->recvpkt)
|
|
|
|
|
|
|
|
ev->t->recvpkt(ev->t, llarp_buffer_t(pkt->buf, size));
|
|
|
|
|
|
|
|
delete pkt;
|
|
|
|
|
|
|
|
});
|
|
|
|
ev->read(ev->readbuf, sizeof(ev->readbuf));
|
|
|
|
ev->read(ev->readbuf, sizeof(ev->readbuf));
|
|
|
|
// LeaveCriticalSection(&HandlerMtx);
|
|
|
|
// LeaveCriticalSection(&HandlerMtx);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -191,11 +195,12 @@ tun_ev_loop(void* unused)
|
|
|
|
// LeaveCriticalSection(&HandlerMtx);
|
|
|
|
// LeaveCriticalSection(&HandlerMtx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
EnterCriticalSection(&HandlerMtx);
|
|
|
|
EnterCriticalSection(&HandlerMtx);
|
|
|
|
if(ev->t->tick)
|
|
|
|
logic->call_soon([ev]() {
|
|
|
|
ev->t->tick(ev->t);
|
|
|
|
if(ev->t->tick)
|
|
|
|
ev->flush_write();
|
|
|
|
ev->t->tick(ev->t);
|
|
|
|
|
|
|
|
ev->flush_write();
|
|
|
|
|
|
|
|
});
|
|
|
|
LeaveCriticalSection(&HandlerMtx);
|
|
|
|
LeaveCriticalSection(&HandlerMtx);
|
|
|
|
delete pkt; // don't leak
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
llarp::LogDebug("exit TUN event loop thread from system managed thread pool");
|
|
|
|
llarp::LogDebug("exit TUN event loop thread from system managed thread pool");
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|