Boost logo

Boost :

From: Malcolm Noyes (boost_at_[hidden])
Date: 2004-06-11 12:27:05


On Fri, 11 Jun 2004 07:14:40 -0400, in gmane.comp.lib.boost.devel
Michael Glassford wrote:

>I assume this means that "attach" callbacks are called before the C
>library's and "detach"
>callbacks are called *after* the C library's? Otherwise it's not a
>problem, as Boost.Thread's tss cleanup is interested primarily in
>detach callbacks (a process attach callback would be used to call
>TlsAlloc(), but that should work regardless of whether the C library
>is loaded).

I agree - loading shouldn't be a problem, however wouldn't you need to
have the C runtime loaded so that when the tls cleanup handler runs it
has access to functions that may be called during object releasing -
for example a custom cleanup handler might call 'free', and this might
fail, if I understand correctly ?

Also, my impression is that this is related in some way to
__declspec(thread) variables which suggests that:

a) this may not work well for dynamically loaded DLLs (i.e.
LoadLibrary, not statically linked to the stubs)

b) we'd probably need to check that whatever mechanism works for MSVC
doesn't break __declspec(thread) variables.

Both will be pretty easy to check, of course.

>It may not be much of a problem, anyway, except when the cleanup is of
>a sort that must be performed even on process exit, which seems
>unusual to me for thread-specific storage. What I mean is, if
>necessary, the tss cleanup could detect that the process is exiting
>and stop trying to run cleanup commands (to prevent access errors,
>etc.), "leaking" any resources stored in thread_specific_ptr objects.
>It seems to me that for many applications such leaking wouldn't be
>much of a problem (but I may be wrong).

I think I'd agree, and for any 'corner cases' it's always possible to
require a call to 'tss.reset(0)' to free the resources before the
process exits.

>> >Hmm. So an application whose tls cleanup required 'C' library
>> >functions would probably fail.
>
>That's what it sounds like to me--but only when the process is
>exiting, I presume?

That was my understanding as well; having read the relevant bits of
the documentation it almost looks like the TLS callback 'hooks' were
put there to implement just what we need. My only concern would be
why they never got implemented (it appears to have been in the PE
format for some time) - maybe someone from MS can enlighten us . . .

>I'm not seeing this.

Sorry - didn't explain myself very well. Application to be tested
does this:

struct thread_info
{
    thread_info(const std::string& name)
    {
        _id = GetCurrentThreadId();
        _id_name = // make some string to identify the thread
        HANDLE h = CreateMutex(..., "NameKnownToUsAndMonitor");
        WaitForSingleObject(h,INFINITE);
        // stuff the string into proces shared memory
        ReleaseMutex(h);
        CloseHandle(h);
    }
    ~thread_info()
    {
        HANDLE h = CreateMutex(..., "NameKnownToUsAndMonitor");
        WaitForSingleObject(h,INFINITE);
        // remove the string from shared memory
        ReleaseMutex(h);
        CloseHandle(h);
    }
    DWORD _id;
    std::string _id_name;
};

thread_specfic_ptr<thread_info> g_ti;

DWORD WINAPI thread_proc(void*)
{
    g_ti.reset(new thread_info("foo thread"));
    ....
    // when thread exits, thread local g_ti object is destroyed,
    // removes id from shared memory
}

const int NUM_THREADS = 10;

int main(int, char*[])
{
    HANDLE h[NUM_THREADS];;
    for (int i=0; i < NUM_THREADS; ++i)
        h[i] = CreateThread(NULL, 0, thread_proc, NULL, 0, NULL);
    
    WaitForMultipleObjects(NUM_THREADS, h, TRUE, // wait all
                                INFINITE);
}

Monitor does something like this:

void foo()
{
    HANDLE h = CreateMutex(..., "NameKnownToUsAndMonitor");
    while(1)
    {
        WaitForSingleObject(h,INFINITE);
        // read strings from shared memory and display on dialog box
        ReleaseMutex(h);
        Sleep(100); // for example
    }
    CloseHandle(h);
}

Thus monitor 'knows' about all threads in test app. I'm planning to
implement this as a test case for the three variations of 'fixes' that
I outlined the other day (i'm working on test cases for 2 of these
variations now ;-).

>Please do: I'm very interested.
So am I, and having read the docs (and not being an expert on
linking), I can't begin to imagine how Aaron will make it work with
MSVC, but I'll be very happy if it does work ;-) Good luck Aaron!

Malcolm
Malcolm Noyes


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