S
smorrey
Howdy folks,
I recently purchased a book on C++ MUD creation and it features alot of
nifty tidbits.
The book is
MUD GAME PROGRAMMING by Ron Penton
Publisher: Premier Press
Anyways of particular interest and what drew me to the book was the
crossplatform threading library.
But the problem is it appears to be broken at a single line of code,
and I can't seem to refactor it to get it work. It's likely something
incredibly simple I'm missing here.
There are only 2 files involved, one is the header and one is the
implementation of the header a "testapp" as it were.
The test app fails to compile properly with this message
ThreadLibTest.cpp: In function 'void PrintThread(void*)':
ThreadLibTest.cpp:8: error: cast from 'void*' to 'char' loses
precision
Here is the code for the testapp
#include <iostream>
#include <unistd.h>
#include "ThreadLib.h"
int main() {
ThreadLib::ThreadID a, b;
a = ThreadLib::Create( PrintThread, (void*)'a' );
b = ThreadLib::Create( PrintThread, (void*)'b' );
ThreadLib::WaitForFinish( b );
ThreadLib::WaitForFinish( a );
char c;
cin >> c;
return 0;
}
void PrintThread( void* data ) {
// convert the data passed in into a character.
char c = (char)data;
for( int i = 0; i < 10000; i++ ) {
cout << c;
cout.flush();
}
}
And here is the code for the ThreadLib.h file
#include <unistd.h>
#ifdef WIN32 // Windows 95 and above
#include <windows.h>
#else // Linux
#include <pthread.h>
#endif
namespace ThreadLib{
typedef void (*ThreadFunc)(void*);
#ifdef WIN32 // Windows 95 and above
typedef DWORD ThreadID;
std::map< DWORD, HANDLE > g_handlemap;
#else // Linux
typedef pthread_t ThreadID;
#endif
class DummyData {
public:
ThreadFunc m_func;
void* m_data;
};
#ifdef WIN32
DWORD WINAPI DummyRun( void* p_data )
#else
void* DummyRun( void* p_data )
#endif
{
// convert the dummy data
DummyData* data = (DummyData*)p_data;
// run the function with the given data
data->m_func( data->m_data );
// now delete the data
delete data;
// and return 0.
return 0;
}
inline ThreadID Create(ThreadFunc p_func, void* p_param ){
ThreadID t;
// create a new dummy data block
DummyData* data = new DummyData;
data->m_func = p_func;
data->m_data = p_param;
#ifdef WIN32 // create a WIN32 thread
HANDLE h;
h = CreateThread( NULL, 0, DummyRun, data, 0, &t );
if( h != 0 ) {
// insert the handle into the handlemap
g_handlemap[t] = h;
}
#else // create a Linux thread
pthread_create( &t, 0, DummyRun, data );
#endif
if( t == 0 ) {
// delete the data first
delete data;
// throw an error
//throw Exception( CreationFailure );
}
return t;
}
inline ThreadID GetID() {
#ifdef WIN32
return GetCurrentThreadId();
#else
return pthread_self();
#endif
}
inline void WaitForFinish( ThreadID p_thread ) {
#ifdef WIN32
// look up the handle and wait for the thread to finish
WaitForSingleObject( g_handlemap[p_thread], INFINITE );
// close the handle of the thread
CloseHandle( g_handlemap[p_thread] );
// remove the handle from the map
g_handlemap.erase( p_thread );
#else
// "join" the thread. This essentially transfers control over to
// the thread and waits for it to finish.
pthread_join( p_thread, NULL );
#endif
}
inline void Kill( ThreadID& p_thread ) {
#ifdef WIN32
// terminate the thread
TerminateThread( g_handlemap[p_thread], 0 );
// close the handle of the thread
CloseHandle( g_handlemap[p_thread] );
// remove the handle from the map
g_handlemap.erase( p_thread );
#else
// cancel the thread.
pthread_cancel( p_thread );
#endif
}
inline void YieldThread( int p_milliseconds = 1 ) {
#ifdef WIN32
Sleep( p_milliseconds );
#else
usleep( p_milliseconds * 1000 );
#endif
}
}
Any help on this would be appreciated, I tried to go to the authors
website but it appears to be down.
I'm just so frustrated because to me at least this code looks exactly
right.
Anyways thanks in advance!
Regards,
I recently purchased a book on C++ MUD creation and it features alot of
nifty tidbits.
The book is
MUD GAME PROGRAMMING by Ron Penton
Publisher: Premier Press
Anyways of particular interest and what drew me to the book was the
crossplatform threading library.
But the problem is it appears to be broken at a single line of code,
and I can't seem to refactor it to get it work. It's likely something
incredibly simple I'm missing here.
There are only 2 files involved, one is the header and one is the
implementation of the header a "testapp" as it were.
The test app fails to compile properly with this message
ThreadLibTest.cpp: In function 'void PrintThread(void*)':
ThreadLibTest.cpp:8: error: cast from 'void*' to 'char' loses
precision
Here is the code for the testapp
#include <iostream>
#include <unistd.h>
#include "ThreadLib.h"
int main() {
ThreadLib::ThreadID a, b;
a = ThreadLib::Create( PrintThread, (void*)'a' );
b = ThreadLib::Create( PrintThread, (void*)'b' );
ThreadLib::WaitForFinish( b );
ThreadLib::WaitForFinish( a );
char c;
cin >> c;
return 0;
}
void PrintThread( void* data ) {
// convert the data passed in into a character.
char c = (char)data;
for( int i = 0; i < 10000; i++ ) {
cout << c;
cout.flush();
}
}
And here is the code for the ThreadLib.h file
#include <unistd.h>
#ifdef WIN32 // Windows 95 and above
#include <windows.h>
#else // Linux
#include <pthread.h>
#endif
namespace ThreadLib{
typedef void (*ThreadFunc)(void*);
#ifdef WIN32 // Windows 95 and above
typedef DWORD ThreadID;
std::map< DWORD, HANDLE > g_handlemap;
#else // Linux
typedef pthread_t ThreadID;
#endif
class DummyData {
public:
ThreadFunc m_func;
void* m_data;
};
#ifdef WIN32
DWORD WINAPI DummyRun( void* p_data )
#else
void* DummyRun( void* p_data )
#endif
{
// convert the dummy data
DummyData* data = (DummyData*)p_data;
// run the function with the given data
data->m_func( data->m_data );
// now delete the data
delete data;
// and return 0.
return 0;
}
inline ThreadID Create(ThreadFunc p_func, void* p_param ){
ThreadID t;
// create a new dummy data block
DummyData* data = new DummyData;
data->m_func = p_func;
data->m_data = p_param;
#ifdef WIN32 // create a WIN32 thread
HANDLE h;
h = CreateThread( NULL, 0, DummyRun, data, 0, &t );
if( h != 0 ) {
// insert the handle into the handlemap
g_handlemap[t] = h;
}
#else // create a Linux thread
pthread_create( &t, 0, DummyRun, data );
#endif
if( t == 0 ) {
// delete the data first
delete data;
// throw an error
//throw Exception( CreationFailure );
}
return t;
}
inline ThreadID GetID() {
#ifdef WIN32
return GetCurrentThreadId();
#else
return pthread_self();
#endif
}
inline void WaitForFinish( ThreadID p_thread ) {
#ifdef WIN32
// look up the handle and wait for the thread to finish
WaitForSingleObject( g_handlemap[p_thread], INFINITE );
// close the handle of the thread
CloseHandle( g_handlemap[p_thread] );
// remove the handle from the map
g_handlemap.erase( p_thread );
#else
// "join" the thread. This essentially transfers control over to
// the thread and waits for it to finish.
pthread_join( p_thread, NULL );
#endif
}
inline void Kill( ThreadID& p_thread ) {
#ifdef WIN32
// terminate the thread
TerminateThread( g_handlemap[p_thread], 0 );
// close the handle of the thread
CloseHandle( g_handlemap[p_thread] );
// remove the handle from the map
g_handlemap.erase( p_thread );
#else
// cancel the thread.
pthread_cancel( p_thread );
#endif
}
inline void YieldThread( int p_milliseconds = 1 ) {
#ifdef WIN32
Sleep( p_milliseconds );
#else
usleep( p_milliseconds * 1000 );
#endif
}
}
Any help on this would be appreciated, I tried to go to the authors
website but it appears to be down.
I'm just so frustrated because to me at least this code looks exactly
right.
Anyways thanks in advance!
Regards,