Click to See Complete Forum and Search --> : TlsSetValue---not working


goofy_10
February 10th, 2003, 05:54 AM
Hi Everyone,

I'm new to this group, Threads programming and COM. And I need help fast!!!!

I have created a simple server (ATL/COM exe) that has a global object "_Module" of the class "CServiceModule" with a DWORD member "iDomain"( this is a thread index) and 2 methods "GetValue()" and "SetValue()" that are used to set and fetch the value of "iDomain" using "TlsGetValue()" & "TlsSetValue()" respectively. This server is accessible to clients through an interface having 2 interface methods "IGetInfo()" and "ISetInfo()". I try to set & fetch the value of "iDomain" from the client through these interfaces which in turn call the object methods mentioned earlier. I have attached those methods also here for your reference.
void CServiceModule::SetValue(int *iDom)
{
int iTemp;
iTemp=*iDom;
TlsSetValue(_Module.iDomain,&iTemp);

}

int CServiceModule::GetValue()
{
int *itemp;
itemp=(int*) TlsGetValue(_Module.iDomain);
int iVal=*itemp;
return iVal;
}

Now I'm not able to set the value using TlsSetValue() and hence TlseGetValue() too doesn't give me the desired result.
However I have tried using thse 2 functions in a simple C++ program and they seem to work. What could be wrong? ANy help would be greatly appreciated. Thanks in advance.

galathaea
February 10th, 2003, 11:43 AM
In your set method you are passing the address of a local stack variable, which is invalid after the function returns. Instead, just pass set the address that is passed to the function (iDom).

goofy_10
February 10th, 2003, 08:14 PM
Hello,
Thanks a lot. :) .. That works ; but now there's something else happening that I'm not able to figure out.
As mentioned earlier, I use 2 interface methods "IGetInfo" and "ISetInfo" to access & modify this "iDomain" value from the client. Here's the implementation of these 2 methods.

STDMETHODIMP CUUtil::ISetInfo(int iVal)
{
// TODO: Add your implementation code here

int iTemp1;
TlsSetValue(_Module.iDomain,&iVal);
HRESULT hr=IGetInfo(&iTemp1);
if(iTemp1!=iVal)
return -1;
return S_OK;
}


STDMETHODIMP CUUtil::IGetInfo(int *iVal)
{
// TODO: Add your implementation code here

iVal=(int *)TlsGetValue(_Module.iDomain);

return S_OK;
}


I have placed a call to "IGetInfo" from within "ISetInfo" and directly tried to manipulate the value of "iDomain" for debugging purposes. NOw, when I call ISetInfo from the client end , passing it a value, then I notice that it's working fine and even the IGetInfo call from within it returns the same value that I set it to. But when I call "IGetInfo" from the client side, it returns an entirely different value...... Why is that happening? And, all this is just with 1 thread (main thread)

galathaea
February 11th, 2003, 02:03 AM
STDMETHODIMP CUUtil::ISetInfo(int iVal)
...
TlsSetValue(_Module.iDomain,&iVal);

These two lines show the origin of your problem, and it is pretty much the same problem as before. What is happening is that iVal is a local variable (even though it is a parameter, it is a value parameter and so copied into the local stack space) and you are taking the address off the stack. All variables on the stack should be assumed invalid outside the scope they are declared in (here, once the function returns), since the stack is reused over and over again for function calls. If you want a consistent address, take it off the free store by creating a pointer with new. The address of the pointed-to object can be passed around in pointers by value and will still not invalidate the pointed-to object.

goofy_10
February 14th, 2003, 07:10 AM
I got the point and I tried to change it using "new". But that still doesn't work :(

All that the problem statement allows me to have is a global index and this has to show different values to different threads that access it. But the problem I have encountered is that the same thread doesn't get the value it set the index to. And I can't use global pointers....

How best can I tackle this problem?