Boost logo

Boost :

From: Tony Juricic (tonygeek_at_[hidden])
Date: 2004-07-29 17:12:56


"Stefan Seefeld" wrote

> ....
> But how is it cleaned up ? You get the idea...

Sure. Example like:

<code>
class TLSTest
{
public:
TLSTest() { std::cout << "Constructor" << std::endl; }
~TLSTest() { std::cout << "Destructor" << std::endl; }
};

boost::thread_specific_ptr<TLSTest> ptr;

int main(int argc, char* argv[])
{
    ptr.reset(new TLSTest());
    return 0;
}
</code>

works like a dream, taking care of programmer's sloppiness.

What worried me is the case where boost program calls into non-boost
(foreign) shared library. It is not rare (especially under Win32) that
library call requires a callback function. Foreign shared library may have a
worker thread(s) that invoke callbacks and programmer may write callback
code unaware that it will be executed on some 'external' thread.

Here is one very simplistic example of such 'foreign' DLL code, that I used
for yesterday's testing:

<code>
HANDLE g_thread=NULL;
DWORD g_threadid=0;
DWORD WINAPI ThreadProc(LPVOID args);

typedef void (*callback)(int);

struct ThreadData
{
 int iparam;
 callback cb;
};

ThreadData g_td;

BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD ul_reason_for_call,
                       LPVOID lpReserved
      )
{
    return TRUE;
}

extern "C" __declspec(dllexport) void __stdcall DLLDoSomething( int iparam,
callback cb )
{
 g_td.iparam=iparam;
 g_td.cb=cb;

 g_thread = reinterpret_cast<HANDLE>(_beginthreadex(
  0,
  0,
  reinterpret_cast<unsigned int (__stdcall*)(void*)>(&ThreadProc),
  &g_td,
  0,
  reinterpret_cast<unsigned int*>(&g_threadid)));
}

DWORD WINAPI ThreadProc(LPVOID args)
{
     DWORD ret=0;
    ThreadData* data=reinterpret_cast<ThreadData*>(args);

     data->cb( data->iparam+100 );
    return ret;
}
</code>

This worked just fine, all forgotten TLS objects were cleaned properly but:

<code>
 case DLL_THREAD_DETACH:
{
     on_thread_exit();
     break;
}
</code>

in boost threads DLL was crucial in accomplishing that. This prompts me to
try test more complex cases where shared library loading/unloading sequence
may (in theory) introduce leaks.

Finally, stretching one possible use case a bit too far, careless programmer
may pack thread code (along with other boost code required by his app) into
his own DLL and forget to provide proper cleanup calls in DLL process and
thread notifications.

Tony


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk