|
|
Classification: |
C++ |
Category: |
Threads & Processes |
Created: |
02/28/2003 |
Modified: |
03/13/2003 |
Number: |
FAQ-0852 |
Platform: |
Not Applicable |
|
Question: I am maintaining static data in Thread Local Storage in a DLL. What data structure should I use, how should I initialise and
destroy my data, and how do I access my data?
Answer: How can I use Thread Local Storage to maintain static data in a DLL?
1. Determine the appropriate structure for my static data.
A Single static variable is possible although difficult to extend should access to additional variables become necessary.
More useful is to encapsulate all the static data variables into a single Struct or class. Extra data variables can easily
be added at a later time.
class TMyStaticData { public: TInt iData; TInt iMoreData; };
2. How / When should I create and destroy my static data?
Ideally, within the DLL entry point E32Dll.
On the device when the DLL is attached to a new thread, we should contruct our static data at this point and store this in Thread Local Storage using Dll::SetTLS().
Similarly, when the Dll is detached from the thread we should delete our static data, and reset the Thread Local Storage. Note : Thread Local Storage maintains a TAny* pointer so we need to cast appropriately when accessing our data.
GLDEF_C TInt E32Dll(TDllReason aReason) { TInt res=KErrNone; TMyStaticData* pMyData; switch (aReason) { case EDllThreadAttach: pMyData=new TMyStaticData; Dll::SetTls(pMyData); if (pMyData) { pMyData->iData = 100; pMyData->iMoreData = 200; }
break;
case EDllThreadDetach: pMyData = static_cast(Dll::Tls()); if (pMyData) delete pMyData; Dll::SetTls(NULL); break; default: break; } return(res); }
Within the emulator the techique is slighly different. A DLL will be attached to the current process rather than a thread :
GLDEF_C TInt E32Dll(TDllReason aReason) { TInt res=KErrNone; TMyStaticData* pMyData; switch (aReason) { case EDllProcessAttach: pMyData=new TMyStaticData; Dll::SetTls(pMyData); If (pMyData) {
pMyData->iData = 100;
pMyData->iMoreData = 200; } break; case EDllThreadAttach: break; case EDllThreadDetach: break; case EDllProcessDetach: pMyData = static_cast(Dll::Tls()); if (pMyData) delete pMyData; Dll::SetTls(NULL); break; } return(res); }
3. How can I access my data?
Cast and cache the TAny pointer contained within Thread Local Storage and access the static variables in the normal way.
It may be useful to create a utility function to make the process simpler and more maintainable:
inline TMyStaticData* GetStaticData() {return static_cast(Dll::Tls()); }
…
TMyStaticData* pData = GetStaticData(); if (pData) PData->iData = 300;
…
|
|
|