|
Thank you, it looks very promising. > The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Sometimes you just have to hate coding to do it well. <
|
|
|
|
|
|
That also looks good, thank you. > The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Sometimes you just have to hate coding to do it well. <
|
|
|
|
|
i've had good luck with this class:
#if !defined (__THREADLOCAL_H__)
#define __THREADLOCAL_H__
#include < list >
class TlsException
{
public:
explicit TlsException (DWORD error) : m_error (error) {}
private:
DWORD m_error;
TlsException ();
};
template < class T > class CISThreadLocal
{
public:
explicit CISThreadLocal () : m_index (::TlsAlloc ())
{
if (m_index == ~0)
{
#ifdef _DEBUG
throw TlsException (GetLastError ());
#endif
}
InitializeCriticalSection(&g_CritSection);
}
~CISThreadLocal ()
{
if (m_index != ~0)
{
::TlsFree (m_index);
}
m_index = 0;
EnterCriticalSection(&g_CritSection);
for (std::list< T *>::iterator it = m_tsdList.begin(); it!=m_tsdList.end(); it++)
{
delete (*it);
}
m_tsdList.clear();
LeaveCriticalSection(&g_CritSection);
DeleteCriticalSection(&g_CritSection);
}
inline T* operator -> ()
{
return GetThreadLocal ();
}
T* GetThreadLocal ()
{
T* tsd = 0;
try
{
if (m_index != ~0)
{
tsd = reinterpret_cast <T*> (::TlsGetValue (m_index));
if (tsd == 0)
{
tsd = new T;
BOOL success = ::TlsSetValue (m_index, tsd);
if (!success)
throw TlsException (::GetLastError ());
EnterCriticalSection(&g_CritSection);
m_tsdList.push_back(tsd);
LeaveCriticalSection(&g_CritSection);
}
}
}
catch (...)
{
tsd = NULL;
}
return tsd;
}
bool HasTLS()
{
T* tsd = 0;
try
{
if (m_index != ~0)
{
tsd = reinterpret_cast <T*> (::TlsGetValue (m_index));
}
}
catch (...)
{
tsd = NULL;
}
return (tsd != 0);
}
void DeleteThreadTLS()
{
try
{
if (m_index != ~0)
{
T* tsd = reinterpret_cast <T*> (::TlsGetValue (m_index));
if (tsd)
{
BOOL success = ::TlsSetValue (m_index, 0);
if (!success)
throw TlsException (::GetLastError ());
EnterCriticalSection(&g_CritSection);
m_tsdList.remove(tsd);
delete tsd;
LeaveCriticalSection(&g_CritSection);
}
}
}
catch (...)
{
}
}
private:
DWORD m_index;
std::list<T *> m_tsdList;
CRITICAL_SECTION g_CritSection;
CISThreadLocal (const CISThreadLocal&);
void operator = (const CISThreadLocal&);
};
the way it works is:
1. define a class that will hold all your thread-safe data:
class CMyThreadSafeData
{
...
int m_foo;
....
};
2. declare and define a single global variable of type CISThreadLocal:
extern CISThreadLocal < CMyThreadSafeData > threadSafeData;
...
CISThreadLocal < CMyThreadSafeData > threadSafeData;
3. whenever you need to access that thread-safe data, do this:
int threadFoo = threadSafeData->m_foo;
|
|
|
|
|
Thank you. > The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Sometimes you just have to hate coding to do it well. <
|
|
|
|
|
Coorect me if I wrong my interpretation: It looks that you have only to pass an input parameter of the threads.
Well, in this case I think that the usual way is not to store the variable into the global memory but pass a pointer to the thread when it is starting. this pointer points to a struct where the new thread can find all the initial values. You have only to wait that the new thread read all the parameters and store they into his local memory, then the caller can continue the flow destroing the objects.
If that parameters can be changed from the main thread during the execution you can then pass to every single thread a set of pointers to these variables. Of course you'll need to allocate an array of variable (one per each thread). Russell
|
|
|
|
|
Thanks for the reply. Either i misunderstand you or you misunderstand me but if i am correct you are not talking about what i meant. I will try to explain with an example:
Let's say you have a 3rd party library that performs some task, you can specify a pointer to a function for this 3rd party library and during its processing the library will call your specified function, for example to report progress. Let's say, this method has to have one parameter, an unsigned char that will change from 0 to 100 (percentage) as the 3rd party advances in the task.
void MyProgress(unsigned char percentage)
{
...
}
...
SetCallBackProcFor3rdPartyLib(MyProgress);
Do3rdPartyLibProcessing();
... Now, what if you would like to give other parameters to your MyProgress method, for example a handle to a control that should display the progress? You can't just do this:
void MyProgress(unsigned char percentage, HWND control)
{
...
} since the lib requires the method to take only one unsigned char parameter and nothing else. So what you can do to have a way for the MyProgress procedure to have access to this information (the handle) is to create a global variable, store this handle in this before you let the lib do the magic, and use this same variable inside MyProgress .
HWND the_control = NULL;
void MyProgress(unsigned char percentage)
{
CString str;
str.Format("%d %%", percentage);
SetWindowText(the_control, str);
}
...
the_control = handle_of_the_control;
SetCallBackProcFor3rdPartyLib(MyProgress);
Do3rdPartyLibProcessing();
... This works, right? But if you have multiple threads all executing Do3rdPartyLibProcessing and all threads having their very own control to display the progress in, you can no longer use the same approach, since the_control exists only once in memory, so every executing thread would use this same memory when trying to store/retrieve their own control's window handle and bang, welcome to chaosland. So my original question is basicly: how to have a "thread level" global variable (so one that is unique per thread and can be accessed everywhere "inside" the thread). As the others said, TLS (Thread-Local Storage) seems to be just the answer for that.
I hope this clears any misunderstandings, sorry if not.> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Sometimes you just have to hate coding to do it well. <
|
|
|
|
|
VC++
Windows XP
Hi,
I have to maintain a large application which sometimes crashes at the end. The cause is probably a buffer overflow somewhere: From time to time a system error message showed up which said that the code segment had been affected. I would like to find the source of the overflow but couldn't figure out where it could be.
It only happens in the release version. I think this is due to the different initialization of debug memory with CD DD and so on. I think it would be easier, when I could run a debug session with heap and stack being initialized in the same way as in the release version. Is there any possibility to get that?
Or is there a tool which can show me e.g.
slice of memory on the heap | origin routine | virtual addr begin | virtual addr end |
pFoo bar 0x00002000 0x20000000
Thank you
Regards
Werner
|
|
|
|
|
You could compile your project without optimization (debug)
and link it with the debug "pdb" information
(These are the project settings)
Secondly,
you could try to restrict the RT reproducing context as possible virtual void BeHappy() = 0;
|
|
|
|
|
Try also to make the following test (may be in a small separate application) :
{
int* pInt = new int[20];
pInt = new int[10];
pInt = new int[30];
pInt = new int[10];
}
...an then pass it to your diagnostic tool virtual void BeHappy() = 0;
|
|
|
|
|
Dear Eugen,
the diagnostic tool which I would find very useful would be one, which can show me something like
variable | chunk of heap start | chunk of heap end | length of heap | allocated by (method signature)
pFoo 0x00002000 0x20000000 536862720 heapcrusher
because I suspect, that the point in the program, where the exception happens is not the one which caused the trouble, but another, which caused a buffer overflow. Sometimes the app crashed at the end and signaled a segment fault. I also tried to debug the app as release version as you suggested but couldn't find out, why it crashed at the point, where it did. Do you know any which can do that?
PS is it actually possible to see variable values in the debugger when I debug the release version? I thought there is no way.
Thank you
regards
Werner
|
|
|
|
|
|
See the Newcomer's classic "Surviving the Release Version"
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
I prefer WinDbg, very effective in finding the application crashes, handle leaks and all([^]) Величие не Бога может быть недооценена.
|
|
|
|
|
Dear Adam,
please refer to my answer to Eugen, thank you
Werner
|
|
|
|
|
Hai,
I have an application in which the .ini file will be placed in the server. Is it possible to give the path of the .ini file as url,i.e
http://xyz//abc.ini
Whether we can read from that location .If not possible can anyone suggest me any other method.
|
|
|
|
|
havent you tried it? Press F1 for help or google it.
Greetings from Germany
|
|
|
|
|
yes, I tried
But it is not working
|
|
|
|
|
jannathali wrote: Whether we can read from that location
How do you try to read, please ? virtual void BeHappy() = 0;
|
|
|
|
|
You'll probably want to use a UNC path."One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
Hiii...
I wanna create a Gui like windows operating system for Linux. The latest Linux versions are user friendly .But I want to do this as a mini project just for practice. So my aim is a simple gui for Linux.
And there are so many gui development tools like gtk, Kdevelopr, Qt/...etc.
Which one I've to select , which one is better for my need. Presently I use Fedora 11.
Wait for a reply...
thanking you
KRISHThumbs Down
|
|
|
|
|
Qt would be a nice tool for GUI development. Qt has both paid and open source versions. Qt source code is protable (if coded carefully) to other operating systems like Windows and Mac as well. http://qt.nokia.com/products[^]
|
|
|
|
|
Ok.... in Qt we program in C++...at any time , if I wanna attach any C- codes, whether it makes any complication or not.Actually I know something about qt, I've created small GUI's like small dialog widgets and all.. So according to you continue with qt is best.!!!
Anyway
thank you.
Krishna
|
|
|
|
|
I think you can reuse you C code in Qt without much problems. Give it a try.
|
|
|
|
|
I'll second Qt - Qt's nice. And you've got QtCreator, which is a nice Qt-centric IDE. Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
CodeProject MVP for 2010 - who'd'a thunk it!
|
|
|
|