Click here to Skip to main content
15,911,142 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
AnswerRe: Can not take my own IP address (Windows Server 2003) Pin
joseaxyz8-Jun-07 7:13
joseaxyz8-Jun-07 7:13 
AnswerRe: Can not take my own IP address (Windows Server 2003) Pin
alejandrofuchs8-Jun-07 7:26
alejandrofuchs8-Jun-07 7:26 
GeneralRe: Can not take my own IP address (Windows Server 2003) Pin
David Crow8-Jun-07 7:33
David Crow8-Jun-07 7:33 
GeneralRe: Can not take my own IP address (Windows Server 2003) [modified] Pin
Mark Salsbery8-Jun-07 7:46
Mark Salsbery8-Jun-07 7:46 
GeneralRe: Can not take my own IP address (Windows Server 2003) Pin
alejandrofuchs8-Jun-07 8:15
alejandrofuchs8-Jun-07 8:15 
GeneralRe: Can not take my own IP address (Windows Server 2003) Pin
Mark Salsbery8-Jun-07 8:33
Mark Salsbery8-Jun-07 8:33 
GeneralRe: Can not take my own IP address (Windows Server 2003) Pin
Mark Salsbery8-Jun-07 8:43
Mark Salsbery8-Jun-07 8:43 
QuestionHeap corruption in personal threadpool implementation [modified] Pin
Cyrilix8-Jun-07 5:48
Cyrilix8-Jun-07 5:48 
EDITED: I have since fixed the problem, instead of using "delete this" in ThreadPool::Release(), I now call "delete m_threadPool" from Main.cpp. Now, I don't know exactly why this works, but here's a possibility:

Link to discussion on RtlFreeHeap

I will cut down on the source code that's not required to shorten my post.

/////////////////////////////////////////////////////////

So far, I haven't done too too much work on this project, however, I do have a few problems already. One is that when running the program, I get heap corruption (Error Message: HEAP[Core.exe]: Invalid Address specified to RtlFreeHeap( 00340000, 00373798 )). The second is that CThreadLocalObject::GetData() will cause an access violation exception which is handled (probably within MFC), but it still worries me that I get this exception. I can't debug into it either, so it's likely something I'm doing that's causing a failure somewhere deep below. The code might be a bit long for most people to want to read. The source code is posted below. The line that actually fails is "delete this" in ThreadPool::Release(). On top of all this, if anyone has any design considerations that they might have to offer, I would be glad to hear them. This is the first time I've worked with any multithreading framework, so any tips to prevent future headaches are appreciated.

Thanks a lot to anyone that takes the time to read this through.

//Main.cpp (entry point of my MFC application)

#include <afxwin.h>
#include <THInc.h>

class MainWindow : public CFrameWnd
{
public:
	CButton start;
	CButton end;
	CEdit textbox;

	ThreadPool* m_threadPool;
	EventSource* m_source;
	EventReceiver* m_receiver;

	MainWindow()
	{
		Create(NULL, "MFC Window");
		start.Create("Start", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, CRect(10,10,100,30), this, 1);
		end.Create("End", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, CRect(10,40,100,60), this, 2);
		textbox.Create(WS_VISIBLE|ES_READONLY|ES_LEFT|ES_MULTILINE|ES_AUTOVSCROLL, CRect(10,70,100,120), this, 3);
	}
	void ButtonStart();
	void ButtonEnd();
	void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
	DECLARE_MESSAGE_MAP()
};

void MainWindow::ButtonStart()
{
	m_threadPool = new ThreadPool();
	m_source = new EventSource();
	m_receiver = new EventReceiver(m_threadPool);
	m_receiver->HookThreadPool(m_source);
}

void MainWindow::ButtonEnd()
{
	if (m_threadPool)
	{
		m_receiver->ReleaseThreadPool(m_source);
		m_threadPool->Release();
		m_threadPool = 0;
	}
}

void MainWindow::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	if (nChar == VK_ESCAPE)
		MessageBox("Escape button pressed");
}

BEGIN_MESSAGE_MAP(MainWindow, CFrameWnd)
	ON_BN_CLICKED(1, MainWindow::ButtonStart)
	ON_BN_CLICKED(2, MainWindow::ButtonEnd)
	ON_WM_KEYDOWN()
END_MESSAGE_MAP()

class Application : public CWinApp
{
public:
	BOOL InitInstance()
	{
		m_pMainWnd = new MainWindow();
		m_pMainWnd->ShowWindow(SW_SHOW);
		return TRUE;
	}
};

Application theApp;


//ThreadPool.cpp (main threading class)

#include "ThreadPool.h"

//Static Declarations

HANDLE ThreadPool::m_threadHandles[3];
map<int, WorkUnit*> ThreadPool::m_workQueue;
bool ThreadPool::m_terminate = false;

//Public Functions

ThreadPool::ThreadPool()
{
	InitThreads();
}

ThreadPool::~ThreadPool()
{
}

void ThreadPool::SignalTermination()
{
	HANDLE termMutex = CreateMutex(NULL, false, "TerminateThreadPool");
	WaitForSingleObject(termMutex, INFINITE);
	m_terminate = true;
	ReleaseMutex(termMutex);
}

void ThreadPool::Release()
{
	//Wait for threads to finish work before terminating
	WaitForMultipleObjects(3, m_threadHandles, true, INFINITE);
	delete this;
}

//int ThreadPool::Process(int (*ptrToFunc)(void))
//{
//	void* funcPtr = ptrToFunc;
//	return 0;
//}

//Private Functions

void ThreadPool::InitThreads()
{
	unsigned int threadID[3];

	for (int i = 0; i < 3; i++)
	{
		int* index = new int(i);
		m_threadHandles[i] = (HANDLE)_beginthreadex(0, 0, &ThreadPool::BeginThread, index, 0, &threadID[i]);
	}
}

unsigned int ThreadPool::BeginThread(void* pArgs)
{
	//Work loop
	HANDLE hWQMutex = CreateMutex(NULL, false, "WorkQueue");
	HANDLE termMutex = CreateMutex(NULL, false, "TerminateThreadPool");
	while (true)
	{
		//Search work queue for work
		WaitForSingleObject(hWQMutex, INFINITE);
		int key = -1;
		WorkUnit* value = 0;
		if (m_workQueue.size() > 0)
		{
			map<int, WorkUnit*>::iterator iter;
			for (iter = m_workQueue.begin(); iter != m_workQueue.end(); iter++)
			{
				value = (*iter).second;
				if (value->GetState() == WorkState_Queued)
				{
					key = (*iter).first;
					value = (*iter).second;
					value->SetState(WorkState_Active);
				}
				else
					continue;
			}
		}
		ReleaseMutex(hWQMutex);

		//If termination has been signaled, return thread
		WaitForSingleObject(termMutex, INFINITE);
		if (m_terminate)
			break;
		ReleaseMutex(termMutex);

		//If no key has been set, sleep thread
		if (key == -1)
			Sleep(1000);
	}

	//Thread termination
	m_threadHandles[*((int*)pArgs)] = 0;
	delete pArgs;
	return 0;
}


-- modified at 13:06 Friday 8th June, 2007
QuestionAutomation object failure on Project Creation Pin
...---...8-Jun-07 4:35
...---...8-Jun-07 4:35 
AnswerRe: Automation object failure on Project Creation Pin
Matthew Faithfull8-Jun-07 5:05
Matthew Faithfull8-Jun-07 5:05 
GeneralRe: Automation object failure on Project Creation Pin
...---...8-Jun-07 5:27
...---...8-Jun-07 5:27 
QuestionDialogBar Pin
thenewbee8-Jun-07 3:14
thenewbee8-Jun-07 3:14 
AnswerRe: DialogBar Pin
Rajkumar R8-Jun-07 3:30
Rajkumar R8-Jun-07 3:30 
GeneralRe: DialogBar Pin
vivekphlp10-Jun-07 17:33
vivekphlp10-Jun-07 17:33 
QuestionRe: DialogBar Pin
Rajkumar R10-Jun-07 18:56
Rajkumar R10-Jun-07 18:56 
AnswerRe: DialogBar Pin
thenewbee10-Jun-07 19:56
thenewbee10-Jun-07 19:56 
QuestionCEdit box buffer limit Pin
NYTSX8-Jun-07 3:03
NYTSX8-Jun-07 3:03 
AnswerRe: CEdit box buffer limit Pin
David Crow8-Jun-07 3:08
David Crow8-Jun-07 3:08 
GeneralRe: CEdit box buffer limit Pin
NYTSX8-Jun-07 3:36
NYTSX8-Jun-07 3:36 
GeneralRe: CEdit box buffer limit Pin
David Crow8-Jun-07 3:43
David Crow8-Jun-07 3:43 
GeneralRe: CEdit box buffer limit Pin
NYTSX8-Jun-07 3:55
NYTSX8-Jun-07 3:55 
QuestionRe: CEdit box buffer limit Pin
David Crow8-Jun-07 3:59
David Crow8-Jun-07 3:59 
GeneralRe: CEdit box buffer limit Pin
daveyerwin8-Jun-07 6:14
daveyerwin8-Jun-07 6:14 
QuestionHow to retrieve text Pin
arun kumar kk8-Jun-07 1:31
arun kumar kk8-Jun-07 1:31 
AnswerRe: How to retrieve text [modified] Pin
Rajkumar R8-Jun-07 2:23
Rajkumar R8-Jun-07 2:23 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.