1
0
Fork 0

msgqueue now uses std::concurrency

This commit is contained in:
Nukem 2015-03-31 20:58:51 -04:00
parent 187a20c48a
commit 29cd3e42f1
4 changed files with 49 additions and 92 deletions

View File

@ -47,22 +47,22 @@ bool FunctionGet(uint Address, uint* Start, uint* End)
if(!DbgIsDebugging()) if(!DbgIsDebugging())
return false; return false;
const uint modbase = ModBaseFromAddr(Address); const uint moduleBase = ModBaseFromAddr(Address);
// Lookup by module hash, then function range // Lookup by module hash, then function range
SHARED_ACQUIRE(LockFunctions); SHARED_ACQUIRE(LockFunctions);
auto found = functions.find(ModuleRange(ModHashFromAddr(modbase), Range(Address - modbase, Address - modbase))); auto found = functions.find(ModuleRange(ModHashFromAddr(moduleBase), Range(Address - moduleBase, Address - moduleBase)));
// Was this range found? // Was this range found?
if(found == functions.end()) if(found == functions.end())
return false; return false;
if(Start) if(Start)
*Start = found->second.start + modbase; *Start = found->second.start + moduleBase;
if(End) if(End)
*End = found->second.end + modbase; *End = found->second.end + moduleBase;
return true; return true;
} }

View File

@ -1,89 +1,49 @@
#include "msgqueue.h" #include "msgqueue.h"
#include <stdio.h>
//allocate a message (internal) // Allocate a message stack
static MESSAGE* msgalloc() MESSAGE_STACK* MsgAllocStack()
{ {
return (MESSAGE*)emalloc(sizeof(MESSAGE), "msgalloc:msg"); // Use placement new to ensure all constructors are called correctly
PVOID memoryBuffer = emalloc(sizeof(MESSAGE_STACK), "MsgAllocStack:memoryBuffer");
MESSAGE_STACK* messageStack = new(memoryBuffer) MESSAGE_STACK;
if(!messageStack)
return nullptr;
return messageStack;
} }
//free a message (internal) // Free a message stack and all messages in the queue
static void msgfree(MESSAGE* msg) void MsgFreeStack(MESSAGE_STACK* Stack)
{ {
efree(msg, "msgfree:msg"); // Destructor must be called manually due to placement new
Stack->FIFOStack.~unbounded_buffer();
// Free memory
efree(Stack, "MsgFreeStack:Stack");
} }
//allocate a message stack // Add a message to the stack
MESSAGE_STACK* msgallocstack() bool MsgSend(MESSAGE_STACK* msgstack, int msg, uint param1, uint param2)
{ {
MESSAGE_STACK* msgstack = (MESSAGE_STACK*)emalloc(sizeof(MESSAGE_STACK), "msgallocstack:msgstack"); MESSAGE messageInfo;
if(!msgstack) messageInfo.msg = msg;
return 0; messageInfo.param1 = param1;
memset(msgstack, 0, sizeof(MESSAGE_STACK)); messageInfo.param2 = param2;
InitializeCriticalSection(&msgstack->cr);
return msgstack;
}
//free a message stack // Asynchronous send. Return value doesn't matter.
void msgfreestack(MESSAGE_STACK* msgstack) concurrency::asend(msgstack->FIFOStack, messageInfo);
{
DeleteCriticalSection(&msgstack->cr);
int stackpos = msgstack->stackpos;
for(int i = 0; i < stackpos; i++) //free all messages left in stack
msgfree(msgstack->msg[i]);
efree(msgstack, "msgfreestack:msgstack");
}
//add a message to the stack
bool msgsend(MESSAGE_STACK* msgstack, int msg, uint param1, uint param2)
{
CRITICAL_SECTION* cr = &msgstack->cr;
EnterCriticalSection(cr);
int stackpos = msgstack->stackpos;
if(stackpos >= MAX_MESSAGES)
{
LeaveCriticalSection(cr);
return false;
}
MESSAGE* newmsg = msgalloc();
if(!newmsg)
{
LeaveCriticalSection(cr);
return false;
}
newmsg->msg = msg;
newmsg->param1 = param1;
newmsg->param2 = param2;
msgstack->msg[stackpos] = newmsg;
msgstack->stackpos++; //increase stack pointer
LeaveCriticalSection(cr);
return true; return true;
} }
//get a message from the stack (will return false when there are no messages) // Get a message from the stack (will return false when there are no messages)
bool msgget(MESSAGE_STACK* msgstack, MESSAGE* msg) bool MsgGet(MESSAGE_STACK* Stack, MESSAGE* Message)
{ {
CRITICAL_SECTION* cr = &msgstack->cr; return concurrency::try_receive(Stack->FIFOStack, *Message);
EnterCriticalSection(cr);
int stackpos = msgstack->stackpos;
if(!msgstack->stackpos) //no messages to process
{
LeaveCriticalSection(cr);
return false;
}
msgstack->stackpos--; //current message is at stackpos-1
stackpos--;
MESSAGE* stackmsg = msgstack->msg[stackpos];
memcpy(msg, stackmsg, sizeof(MESSAGE));
msgfree(stackmsg);
msgstack->msg[stackpos] = 0;
LeaveCriticalSection(cr);
return true;
} }
//wait for a message on the specified stack // Wait for a message on the specified stack
void msgwait(MESSAGE_STACK* msgstack, MESSAGE* msg) void MsgWait(MESSAGE_STACK* Stack, MESSAGE* Message)
{ {
while(!msgget(msgstack, msg)) *Message = concurrency::receive(Stack->FIFOStack);
Sleep(1);
} }

View File

@ -3,10 +3,9 @@
#include "_global.h" #include "_global.h"
#include <windows.h> #include <windows.h>
#include <agents.h>
#define MAX_MESSAGES 256 // Message structure
//message structure
struct MESSAGE struct MESSAGE
{ {
int msg; int msg;
@ -14,19 +13,17 @@ struct MESSAGE
uint param2; uint param2;
}; };
//message stack structure // Message stack structure.
// Supports an unlimited number of messages.
struct MESSAGE_STACK struct MESSAGE_STACK
{ {
CRITICAL_SECTION cr; concurrency::unbounded_buffer<MESSAGE> FIFOStack;
int stackpos;
MESSAGE* msg[MAX_MESSAGES];
}; };
//function definitions MESSAGE_STACK* MsgAllocStack();
MESSAGE_STACK* msgallocstack(); void MsgFreeStack(MESSAGE_STACK* Stack);
void msgfreestack(MESSAGE_STACK* msgstack); bool MsgSend(MESSAGE_STACK* msgstack, int msg, uint param1, uint param2);
bool msgsend(MESSAGE_STACK* msgstack, int msg, uint param1, uint param2); bool MsgGet(MESSAGE_STACK* Stack, MESSAGE* Message);
bool msgget(MESSAGE_STACK* msgstack, MESSAGE* msg); void MsgWait(MESSAGE_STACK* Stack, MESSAGE* Message);
void msgwait(MESSAGE_STACK* msgstack, MESSAGE* msg);
#endif // _MSGQUEUE_H #endif // _MSGQUEUE_H

View File

@ -194,7 +194,7 @@ static void registercommands()
static bool cbCommandProvider(char* cmd, int maxlen) static bool cbCommandProvider(char* cmd, int maxlen)
{ {
MESSAGE msg; MESSAGE msg;
msgwait(gMsgStack, &msg); MsgWait(gMsgStack, &msg);
char* newcmd = (char*)msg.param1; char* newcmd = (char*)msg.param1;
if(strlen(newcmd) >= deflen) if(strlen(newcmd) >= deflen)
{ {
@ -211,7 +211,7 @@ extern "C" DLL_EXPORT bool _dbg_dbgcmdexec(const char* cmd)
int len = (int)strlen(cmd); int len = (int)strlen(cmd);
char* newcmd = (char*)emalloc((len + 1) * sizeof(char), "_dbg_dbgcmdexec:newcmd"); char* newcmd = (char*)emalloc((len + 1) * sizeof(char), "_dbg_dbgcmdexec:newcmd");
strcpy_s(newcmd, len + 1, cmd); strcpy_s(newcmd, len + 1, cmd);
return msgsend(gMsgStack, 0, (uint)newcmd, 0); return MsgSend(gMsgStack, 0, (uint)newcmd, 0);
} }
static DWORD WINAPI DbgCommandLoopThread(void* a) static DWORD WINAPI DbgCommandLoopThread(void* a)
@ -259,7 +259,7 @@ extern "C" DLL_EXPORT const char* _dbg_dbginit()
strcpy_s(szSymbolCachePath, dir); strcpy_s(szSymbolCachePath, dir);
PathAppendA(szSymbolCachePath, "symbols"); PathAppendA(szSymbolCachePath, "symbols");
SetCurrentDirectoryW(StringUtils::Utf8ToUtf16(dir).c_str());; SetCurrentDirectoryW(StringUtils::Utf8ToUtf16(dir).c_str());;
gMsgStack = msgallocstack(); gMsgStack = MsgAllocStack();
if(!gMsgStack) if(!gMsgStack)
return "Could not allocate message stack!"; return "Could not allocate message stack!";
varinit(); varinit();
@ -306,7 +306,7 @@ extern "C" DLL_EXPORT void _dbg_dbgexitsignal()
CloseHandle(hCommandLoopThread); CloseHandle(hCommandLoopThread);
cmdfree(command_list); cmdfree(command_list);
varfree(); varfree();
msgfreestack(gMsgStack); MsgFreeStack(gMsgStack);
if(memleaks()) if(memleaks())
{ {
char msg[256] = ""; char msg[256] = "";