views:

107

answers:

3

I have a class that contains a function that calls create thread, and needs to pass itself (this) as a parameter:

DWORD threadId;
HANDLE h = CreateThread( NULL, 0, runThread, this, 0, &threadId);

My runThread definition is as follows:

DWORD WINAPI runThread(LPVOID args)
{
    Obj *t = (Obj*)args;
    t->funct();
    return 0;
}

Unfortunately, the object t that I get in runThread() gets garbage. My Obj class has a function pointer attribute. Could that be the problem?

class Obj{
    void(*funct)();

and in the constructor:

Obj(void(*f)())
{
    funct = f;
}

where is my mistake? The function pointer, the createThread itself, or type-casting? I tried whatever I could think of.

+1  A: 

Assuming the object has been properly constructed, is there any chance that the object that is creating the thread has gone out of scope after CreateThread is called? This would leave your thread with a garbage object. If not, single step through the code with a debugger, and have a look at the objects 'this' pointer as the thread is being called, with a breakpoint at the thread start to see what it is getting as parameters.

Shane MacLaughlin
Setting a breakpoint into the object destructor could also be very helpful - if you see that it is *suddenly* called before the thread finishes you know the problem is with the object lifetime.
sharptooth
I tried seeing what it passed, the 'this' passed was correct. I found the bug though... the main thread where the object was created was destroying it before the thread executed. Thanks sharptooth!
Vanwaril
+1  A: 

The object was created in my main thread of execution. The error was because the object was going out of scope two lines down in that thread, so when the thread executed there was only garbage at the address.

Vanwaril
+1 always good to see the solution added for the next person that hits the same problem some time in the future.
Shane MacLaughlin
A: 

When I tried to do the same in my code I got a error like

Error   1   error C2664: 'CreateThread' : cannot convert parameter 3 from 'DWORD (__stdcall AcceptSocket::* )(LPVOID)' to 'LPTHREAD_START_ROUTINE'  D:\Work\Chess\Chess\Chess\NetWorking.cpp    65  1   Chess

I am posting my code

First the header file

#include<winsock.h>
#include<string>
#include<iostream>

using namespace std;

class AcceptSocket
{
static SOCKET s;    
protected:
SOCKET acceptSocket;
public:
AcceptSocket(){};
void setSocket(SOCKET socket);
static void EstablishConnection(int portNo,string&);
static void closeConnection();
static void StartAccepting();
virtual void threadDeal(); 
DWORD WINAPI MyThreadFunction(LPVOID lpParam);
};

Now the source file

#include<NetWorking.h>
#include<string>
#include<fstream>
#include<sstream>

SOCKET AcceptSocket::s;

void AcceptSocket::setSocket(SOCKET s)
{
acceptSocket=s;
}

void AcceptSocket::EstablishConnection(int portno,string &failure)
{
WSAData w;
int error = WSAStartup(0x0202,&w);

if(error)
    failure=failure+"\nWSAStartupFailure";

if(w.wVersion != 0x0202)
{
    WSACleanup();
    failure=failure+"\nVersion is different";
}

SOCKADDR_IN addr;

addr.sin_family=AF_INET;

addr.sin_port=htons(portno);

addr.sin_addr.s_addr=htonl(INADDR_ANY);

AcceptSocket::s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

if(AcceptSocket::s == INVALID_SOCKET)
    failure=failure+"\nsocket creating error";

if(bind(AcceptSocket::s,(LPSOCKADDR) &addr,sizeof(addr)) == SOCKET_ERROR)
    failure=failure+"\nbinding error";

listen(AcceptSocket::s,SOMAXCONN);
}

void AcceptSocket::closeConnection()
{
if(AcceptSocket::s)
    closesocket(AcceptSocket::s);

WSACleanup();
}

void AcceptSocket::StartAccepting()
{
sockaddr_in addrNew;
int size=sizeof(addrNew);
while(1)
{
    SOCKET temp=accept(AcceptSocket::s,(sockaddr *)&addrNew,&size);
    AcceptSocket * tempAcceptSocket=new AcceptSocket();
    tempAcceptSocket->setSocket(temp);
    DWORD threadId;
    cout << "Before the thread" << endl ;
    HANDLE thread=CreateThread(NULL,0,&AcceptSocket::MyThreadFunction,(LPVOID)(tempAcceptSocket),0,&threadId);
    cout << GetLastError() << endl ;
}
}

DWORD WINAPI AcceptSocket::MyThreadFunction(LPVOID lpParam)
{
AcceptSocket * acceptsocket=(AcceptSocket *) lpParam;
acceptsocket->threadDeal();
return 1;
}

Now the main

#include<Networking.h>

int main()
{
}

I don't how to correct this. Can anybody help me?

prabhakaran