Sign in to follow this  

Prgram locking up completly

This topic is 3550 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I know it has something to do wi the CMD_CREATEUSER (no crash without it) and the main/net threads but with it locking my computer up everytime and many of the commands being a few thousand lines (I got board stepping through one of the mysql functions after half an hour in the end) I'm not sure how to debug I cannot see anything in my code that would lock my computer up completly...I can't even get the task manager up to close vs and my program... Net.cpp
...
#define REP_USERCREATE 0x02
struct CommandData
{
	//this is the users session id, 0 is the "public" user and is highly limited
	unsigned long SessionId;
	//this isn't changed by the server so is the same in the reply. 
	//Can be used to detect the reply to this command
	unsigned char Id;
	//the command
	unsigned char Cmd;
	//command data
	std::list<unsigned char> Data;
	//the ip this command came from
	std::string ip;
};
...
void CommandAdd(HANDLE &HCommand, CommandData* Command);//use this to add new commands to the stack (thread safe)
ReplyData* ReplyGet(HANDLE &HReply);//use this to get the next reply. Returns NULL if there are no waiting replys (thread safe)


HANDLE NetHCommand, NetHReply;
bool NetRun=true, NetExit=false;
unsigned int __stdcall NetMain(void* Params)
{
	CreateSemaphores(NetHCommand, NetHReply);
//test user create
	CommandData* Cmd = new CommandData;
	Cmd->ip = "192.168.1.6:3197";
	Cmd->Cmd = CMD_USERCREATE;
	Cmd->SessionId = 0x00000000;
	Cmd->Id = 0x00;
	Cmd->Data.push_back('F');
	Cmd->Data.push_back('i');
	Cmd->Data.push_back('r');
	Cmd->Data.push_back('e');
	Cmd->Data.push_back(' ');
	Cmd->Data.push_back('L');
	Cmd->Data.push_back('a');
	Cmd->Data.push_back('n');
	Cmd->Data.push_back('c');
	Cmd->Data.push_back('e');
	Cmd->Data.push_back('r');
	Cmd->Data.push_back('\0');
	Cmd->Data.push_back('e');
	Cmd->Data.push_back('n');
	Cmd->Data.push_back('r');
	Cmd->Data.push_back('y');
	Cmd->Data.push_back('p');
	Cmd->Data.push_back('t');
	Cmd->Data.push_back('\0');
	Cmd->Data.push_back('D');
	Cmd->Data.push_back('r');
	Cmd->Data.push_back('a');
	Cmd->Data.push_back('g');
	Cmd->Data.push_back('o');
	Cmd->Data.push_back('n');
	Cmd->Data.push_back('_');
	Cmd->Data.push_back('F');
	Cmd->Data.push_back('l');
	Cmd->Data.push_back('y');
	Cmd->Data.push_back('1');
	Cmd->Data.push_back('1');
	Cmd->Data.push_back('0');
	Cmd->Data.push_back('2');
	Cmd->Data.push_back('@');
	Cmd->Data.push_back('h');
	Cmd->Data.push_back('o');
	Cmd->Data.push_back('t');
	Cmd->Data.push_back('m');
	Cmd->Data.push_back('a');
	Cmd->Data.push_back('i');
	Cmd->Data.push_back('l');
	Cmd->Data.push_back('.');
	Cmd->Data.push_back('c');
	Cmd->Data.push_back('o');
	Cmd->Data.push_back('m');
	Cmd->Data.push_back('\0');
	CommandAdd(NetHCommand, Cmd);

	while(NetRun)//the server sets this to false on shutdown
	{
		Sleep(100);
	}
	NetExit = true;
	_endthreadex(0);
	return 0;
}

Command.cpp
#include "command.h"
std::list<CommandData*> CommandsQueue;
std::list<CommandData*> CommandsDone;
std::list<ReplyData*> ReplyQueue;
CommandData* Command;

void CreateSemaphores(HANDLE &HCommand, HANDLE &HReply)
{
	HCommand = NULL;
	while(!HCommand)HCommand = CreateMutex(NULL, FALSE, "SYNC_COMMAND");
	HReply   = NULL;
	while(!HReply)  HReply   = CreateMutex(NULL, FALSE, "SYNC_REPLY");
}

bool CommandNext(HANDLE &HCommand)
{
	while(WaitForSingleObject(HCommand, 10000)==WAIT_TIMEOUT);
	if(CommandsQueue.empty())
	{
		Command = NULL;
		ReleaseMutex(HCommand);
		return false;
	}
	Command = CommandsQueue.front();
	CommandsQueue.pop_front();
	ReleaseMutex(HCommand);
	return true;
}
void CommandDone(HANDLE &HCommand)
{
	while(WaitForSingleObject(HCommand, 10000)==WAIT_TIMEOUT);
	CommandsDone.push_back(Command);
	Command = NULL;
	ReleaseMutex(HCommand);
}
void CommandAdd(HANDLE &HCommand, CommandData* Command)
{
	while(WaitForSingleObject(HCommand, 10000)==WAIT_TIMEOUT);
	CommandsQueue.push_back(Command);
	ReleaseMutex(HCommand);
}
ReplyData* ReplyGet(HANDLE &HReply)
{
	while(WaitForSingleObject(HReply, 10000)==WAIT_TIMEOUT);
	ReplyData* Reply = ReplyQueue.front();
	ReplyQueue.pop_front();
	ReleaseMutex(HReply);
	return Reply;
}
void ReplyAdd(HANDLE &HReply, ReplyData* Reply)
{
	while(WaitForSingleObject(HReply, 10000)==WAIT_TIMEOUT);
	ReplyQueue.push_back(Reply);
	ReleaseMutex(HReply);
}

main.cpp
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	//create log file
	Buffer << "logs\\log_" << time(NULL) << ".txt";
	Log.open(Buffer.str().c_str());
	Log << "Server started at: " << StringTime(time(NULL)) << std::endl;
	//create sync samaphores
	CreateSemaphores(MainHCommand, MainHReply);
	//connect to server
	if(SqlConnect()) Log << "Connected to mysql server" << std::endl;
	else
	{
		Log << "Fatal Error-Failed to connect to mysql server" << std::endl;
		return 0;
	}		
	//create gui thread
	unsigned int GuiId;
	uintptr_t GuiThread = _beginthreadex(
		NULL,
		0,
		GuiMain,
		(void*)hInstance,
		0,
		&GuiId);
	unsigned int NetId;
	//create net thread
	uintptr_t NetThread = _beginthreadex(
		NULL,
		0,
		NetMain,
		NULL,
		0,
		&NetId);

	unsigned long GuiLastUpdate = GetTickCount();
	while(MainRun)
	{
		if(GuiLastUpdate+500 < GetTickCount())
		{
			GuiLastUpdate = GetTickCount();
			InvalidateRect(GuiHwnd, NULL, true);
		}
		//if there is no command wait untill there is one
		if(CommandNext(MainHCommand))
		{
			//log before loggin any replys
			Log << StringCommand(Command) << std::endl;
			//process command
			switch(Command->Cmd)
			{
			case CMD_EXIT:
				{
					MainRun = false;
					NetRun  = false;
					GuiRun  = false;
					break;
				}
			case CMD_LOGIN:
				{
...
				}
			case CMD_USERCREATE:
				{
					std::string User, Pass, Email;
					std::list<unsigned char>::iterator it = Command->Data.begin();
					while(*it != 0x00)
					{
						User += (char)*it;
						++it;
					}
					++it;//get rid of that last NULL
					while(*it != 0x00)
					{
						Pass += (char)*it;
						++it;
					}
					++it;//get rid of that last NULL
					while(*it != 0x00)
					{
						Email += (char)*it;
						++it;
					}

					unsigned char Result = UserCreate(User, Pass, Email);

					ReplyData* Reply = new ReplyData;
					Reply->Cmd = REP_USERCREATE;
					Reply->ip = Command->ip;
					Reply->Id = Command->Id;
					Reply->Data.push_back(Result);
					Log << StringReply(Reply) << std::endl;
					ReplyAdd(MainHReply, Reply);
					break;
				}
			case CMD_LOGOUT:
				{
...
				}
			default:
				{
					break;
				}
			}
			CommandDone(MainHCommand);
		}
		//wait a bit then check if a message has come in
		else Sleep(50);
	}
	while(!GuiExit || !NetExit)Sleep(10);
	return 0;
}

User.cpp
...
int UserCreate(const std::string &Name, const std::string &Pass, const std::string &Email)
{
	if(Name.size() > 32)return 2;

	mysqlpp::StoreQueryResult res;
	std::string str = "SELECT id FROM users WHERE name=\""+Name+"\"";
	res = SendQuery(str);//seems to be here
	if(res.num_rows() > 0)return 1;//user already exists

	str = "SELECT id FROM users WHERE email=\""+Email+"\"";
	res = SendQuery(str);
	if(res.num_rows() > 0)return 3;//email already used

	str = "INSERT INTO users (name, password, email) VALUES(\""+Name+"\",\""+Pass+"\",\""+Email+"\")";
	res = SendQuery(str);
	return 0;
}
...

Sql.cpp
...
#include "mysql++.h"
...
mysqlpp::StoreQueryResult SendQuery(const std::string &Sql)
{
	//query
	mysqlpp::Query query = conn.query(Sql.c_str());
	mysqlpp::StoreQueryResult res = query.store();
	//check for errors
	std::string Error = query.error();
	if(Error=="")return res;
	else  
	{
		MessageBox(NULL, Error.c_str(), "Sql Error", MB_ICONERROR);
		return res;
	}
}
...

Share this post


Link to post
Share on other sites

This topic is 3550 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this