Jack
2010-04-08 12:08:09 UTC
Dear all,
First some code snippets,
//////////////////////////////////////////////////////////////////////////
class Thread
{
public:
Thread(std::auto_ptr<Runnable> runnable_);
Thread();
virtual ~Thread();
void start();
void *join();
private:
HANDLE hThread;
unsigned winThreadID;
std::auto_ptr<Runnable> runnable;
Thread(const Thread&);
const Thread& operator = (const Thread&);
void setCompleted();
void *result;
virtual void *run() { return 0; }
static unsigned WINAPI startThreadRunnable(LPVOID pVoid);
static unsigned WINAPI startThread(LPVOID pVoid);
void PrintError(LPTSTR lpszFunction, LPSTR fileName, int lineNumber);
};
Thread::Thread(std::auto_ptr<Runnable> runnable_) : runnable(runnable_)
{
if (runnable.get() == NULL)
PrintError("Thread(std::auto_ptr<Runnable> runnable_) failed at ",
__FILE__, __LINE__);
hThread = (HANDLE) _beginthreadex(NULL, 0, Thread::startThreadRunnable,
(LPVOID) this, CREATE_SUSPENDED, &winThreadID);
if (!hThread)
PrintError("_beginthreadex failed at ", __FILE__, __LINE__);
}
Thread::Thread() : runnable(NULL)
{
hThread = (HANDLE) _beginthreadex(NULL, 0, Thread::startThread,
(LPVOID)this, CREATE_SUSPENDED, &winThreadID);
if (!hThread)
PrintError("_beginthreadex failed at ", __FILE__, __LINE__);
}
unsigned WINAPI Thread::startThreadRunnable(LPVOID pVoid)
{
Thread *runnableThread = static_cast<Thread *>(pVoid);
runnableThread->setCompleted();
return reinterpret_cast<unsigned>(runnableThread->result);
}
//// Destructor called before this function is.
//// so the whole context gets destroyed
//// but why did that happen?
unsigned WINAPI Thread::startThread(LPVOID pVoid)
{
Thread *aThread = static_cast<Thread *>(pVoid);
aThread->result = aThread->run();
aThread->setCompleted();
return reinterpret_cast<unsigned>(aThread->result);
}
Thread::~Thread()
{
if (winThreadID != GetCurrentThreadId())
{
DWORD rc = CloseHandle(hThread);
if (!rc)
PrintError ("CloseHandle failed at ", __FILE__, __LINE__);
}
}
void Thread::start()
{
assert(hThread != NULL);
DWORD rc = ResumeThread(hThread);
if (!rc)
PrintError("ResumeThread failed at ", __FILE__, __LINE__);
}
void *Thread::join()
{
return result;
}
void Thread::setCompleted()
{
}
/////////////////////////////////////////////////////////////////////////////////////////
class BFThread : public Thread
{
public:
BFThread(int ID) : myID(ID) { }
virtual void *run()
{
return reinterpret_cast<void *>(myID);
}
private:
int myID;
};
//////////////////////////////////////////////////////////////////////////////////
// main module
std::auto_ptr<BFThread> thread1(new BFThread(1));
thread1->start();
int result1 = reinterpret_cast<int>(thread1->join());
///////////////////////////////////////////////////////////////////////////////
The errors are:
First-chance exception at 0x004177c7 in GridPartition.exe: 0xC0000005:
Access violation reading location 0xfeeefef2.
Unhandled exception at 0x004177c7 in GridPartition.exe: 0xC0000005: Access
violation reading location 0xfeeefef2.
I wrote the comments above. Could anyone please check my code why the
destructor is called before the startThread function is?
Thanks
Jack
First some code snippets,
//////////////////////////////////////////////////////////////////////////
class Thread
{
public:
Thread(std::auto_ptr<Runnable> runnable_);
Thread();
virtual ~Thread();
void start();
void *join();
private:
HANDLE hThread;
unsigned winThreadID;
std::auto_ptr<Runnable> runnable;
Thread(const Thread&);
const Thread& operator = (const Thread&);
void setCompleted();
void *result;
virtual void *run() { return 0; }
static unsigned WINAPI startThreadRunnable(LPVOID pVoid);
static unsigned WINAPI startThread(LPVOID pVoid);
void PrintError(LPTSTR lpszFunction, LPSTR fileName, int lineNumber);
};
Thread::Thread(std::auto_ptr<Runnable> runnable_) : runnable(runnable_)
{
if (runnable.get() == NULL)
PrintError("Thread(std::auto_ptr<Runnable> runnable_) failed at ",
__FILE__, __LINE__);
hThread = (HANDLE) _beginthreadex(NULL, 0, Thread::startThreadRunnable,
(LPVOID) this, CREATE_SUSPENDED, &winThreadID);
if (!hThread)
PrintError("_beginthreadex failed at ", __FILE__, __LINE__);
}
Thread::Thread() : runnable(NULL)
{
hThread = (HANDLE) _beginthreadex(NULL, 0, Thread::startThread,
(LPVOID)this, CREATE_SUSPENDED, &winThreadID);
if (!hThread)
PrintError("_beginthreadex failed at ", __FILE__, __LINE__);
}
unsigned WINAPI Thread::startThreadRunnable(LPVOID pVoid)
{
Thread *runnableThread = static_cast<Thread *>(pVoid);
runnableThread->setCompleted();
return reinterpret_cast<unsigned>(runnableThread->result);
}
//// Destructor called before this function is.
//// so the whole context gets destroyed
//// but why did that happen?
unsigned WINAPI Thread::startThread(LPVOID pVoid)
{
Thread *aThread = static_cast<Thread *>(pVoid);
aThread->result = aThread->run();
aThread->setCompleted();
return reinterpret_cast<unsigned>(aThread->result);
}
Thread::~Thread()
{
if (winThreadID != GetCurrentThreadId())
{
DWORD rc = CloseHandle(hThread);
if (!rc)
PrintError ("CloseHandle failed at ", __FILE__, __LINE__);
}
}
void Thread::start()
{
assert(hThread != NULL);
DWORD rc = ResumeThread(hThread);
if (!rc)
PrintError("ResumeThread failed at ", __FILE__, __LINE__);
}
void *Thread::join()
{
return result;
}
void Thread::setCompleted()
{
}
/////////////////////////////////////////////////////////////////////////////////////////
class BFThread : public Thread
{
public:
BFThread(int ID) : myID(ID) { }
virtual void *run()
{
return reinterpret_cast<void *>(myID);
}
private:
int myID;
};
//////////////////////////////////////////////////////////////////////////////////
// main module
std::auto_ptr<BFThread> thread1(new BFThread(1));
thread1->start();
int result1 = reinterpret_cast<int>(thread1->join());
///////////////////////////////////////////////////////////////////////////////
The errors are:
First-chance exception at 0x004177c7 in GridPartition.exe: 0xC0000005:
Access violation reading location 0xfeeefef2.
Unhandled exception at 0x004177c7 in GridPartition.exe: 0xC0000005: Access
violation reading location 0xfeeefef2.
I wrote the comments above. Could anyone please check my code why the
destructor is called before the startThread function is?
Thanks
Jack