mirror of
https://github.com/galaxyhaxz/devilution.git
synced 2026-02-19 05:46:45 +00:00
initial up
This commit is contained in:
148
2020_03_31/Source/dthread.cpp
Normal file
148
2020_03_31/Source/dthread.cpp
Normal file
@@ -0,0 +1,148 @@
|
||||
#include "diablo.h"
|
||||
#include "../3rdParty/Storm/Source/storm.h"
|
||||
|
||||
static CCritSect sgMemCrit; // idb
|
||||
static unsigned int sgnThreadId; // idb
|
||||
TDeltaInfo *sgpInfoHead;
|
||||
static BOOLEAN sgbThreadIsActive; // weak
|
||||
HANDLE sghWorkToDoEvent; // idb
|
||||
|
||||
/* rdata */
|
||||
static HANDLE sghThread = INVALID_HANDLE_VALUE; // idb
|
||||
|
||||
void dthread_remove_player(int pnum)
|
||||
{
|
||||
TDeltaInfo *p;
|
||||
|
||||
sgMemCrit.Enter();
|
||||
|
||||
for(p = sgpInfoHead; p != NULL; p = p->pNext) {
|
||||
if(p->pnum == pnum) {
|
||||
p->pnum = 4;
|
||||
}
|
||||
}
|
||||
|
||||
sgMemCrit.Leave();
|
||||
}
|
||||
|
||||
void dthread_send_delta(int pnum, BYTE cmd, const BYTE *pbSrc, DWORD dwLen)
|
||||
{
|
||||
TDeltaInfo *pCurr, *p;
|
||||
|
||||
/// ASSERT: assert((DWORD) pnum < MAX_PLRS);
|
||||
/// ASSERT: assert(pnum != myplr);
|
||||
/// ASSERT: assert(pbSrc);
|
||||
/// ASSERT: assert(dwLen);
|
||||
|
||||
if(gbMaxPlayers == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
pCurr = (TDeltaInfo *)DiabloAllocPtr(sizeof(*pCurr) + dwLen);
|
||||
pCurr->pNext = NULL;
|
||||
pCurr->pnum = pnum;
|
||||
pCurr->cmd = cmd;
|
||||
pCurr->size = dwLen;
|
||||
memcpy(pCurr->data, pbSrc, dwLen);
|
||||
|
||||
sgMemCrit.Enter();
|
||||
|
||||
p = (TDeltaInfo *)&sgpInfoHead;
|
||||
while(p->pNext != NULL) {
|
||||
p = p->pNext;
|
||||
}
|
||||
p->pNext = pCurr;
|
||||
|
||||
SetEvent(sghWorkToDoEvent);
|
||||
|
||||
sgMemCrit.Leave();
|
||||
}
|
||||
|
||||
void dthread_start()
|
||||
{
|
||||
/// ASSERT: assert(sghThread == INVALID_HANDLE_VALUE);
|
||||
|
||||
if(gbMaxPlayers == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
/// ASSERT: assert(! sgpInfoHead);
|
||||
/// ASSERT: assert(! sghWorkToDoEvent);
|
||||
sghWorkToDoEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if(sghWorkToDoEvent == NULL) {
|
||||
app_fatal("dthread:1\n%s", TraceLastError());
|
||||
}
|
||||
|
||||
sgbThreadIsActive = TRUE;
|
||||
|
||||
/// ASSERT: assert(sghThread == INVALID_HANDLE_VALUE);
|
||||
sghThread = (HANDLE)_beginthreadex(NULL, 0, dthread_handler, NULL, 0, &sgnThreadId);
|
||||
if(sghThread == INVALID_HANDLE_VALUE) {
|
||||
app_fatal("dthread2:\n%s", TraceLastError());
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int __stdcall dthread_handler(void *dummy)
|
||||
{
|
||||
DWORD dwTime;
|
||||
TDeltaInfo *p;
|
||||
|
||||
while(sgbThreadIsActive) {
|
||||
if(sgpInfoHead == NULL && WaitForSingleObject(sghWorkToDoEvent, INFINITE) == WAIT_FAILED) {
|
||||
app_fatal("dthread4:\n%s", TraceLastError());
|
||||
}
|
||||
sgMemCrit.Enter();
|
||||
p = sgpInfoHead;
|
||||
if(p != NULL) {
|
||||
sgpInfoHead = p->pNext;
|
||||
} else {
|
||||
ResetEvent(sghWorkToDoEvent);
|
||||
}
|
||||
sgMemCrit.Leave();
|
||||
if(p != NULL) {
|
||||
if(p->pnum != 4) {
|
||||
multi_send_zero_packet(p->pnum, p->cmd, p->data, p->size);
|
||||
}
|
||||
/// ASSERT: assert(gdwDeltaBytesSec);
|
||||
dwTime = 1000 * p->size / gdwDeltaBytesSec;
|
||||
if(dwTime >= 1) {
|
||||
dwTime = 1;
|
||||
}
|
||||
MemFreeDbg(p);
|
||||
if(dwTime != 0) {
|
||||
Sleep(dwTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dthread_cleanup()
|
||||
{
|
||||
TDeltaInfo *p;
|
||||
|
||||
if(sghWorkToDoEvent == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
sgbThreadIsActive = FALSE;
|
||||
SetEvent(sghWorkToDoEvent);
|
||||
|
||||
if(sghThread != INVALID_HANDLE_VALUE && sgnThreadId != GetCurrentThreadId()) {
|
||||
if(WaitForSingleObject(sghThread, INFINITE) == WAIT_FAILED) {
|
||||
app_fatal("dthread3:\n(%s)", TraceLastError());
|
||||
}
|
||||
CloseHandle(sghThread);
|
||||
sghThread = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
CloseHandle(sghWorkToDoEvent);
|
||||
sghWorkToDoEvent = NULL;
|
||||
|
||||
while(sgpInfoHead != NULL) {
|
||||
p = sgpInfoHead->pNext;
|
||||
MemFreeDbg(sgpInfoHead);
|
||||
sgpInfoHead = p;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user