2004.12.23 05:11 "[Tiff] Q : TIFFSetTagExtender", by Chris Losinger

i'm getting deadlocks in a multi-threaded .Net app when calling into a C DLL that uses TIFFSetTagExtender, once per thread. if i take out the TIFFSetTagExtender call, the deadlocks seem to go away.

are there any threading considerations i should be aware of when using TIFFSetTagExtender?

should each thread in an application call this, or is once enough?

TIFFSetTagExtender is called once per thread and the DLL uses thread-local storage to hold a flag and a function pointer to the parent extender - the flag insures that the extender is called only once per thread. the extender initialization is done immediately before the call to TIFFClientOpen (on the first time the thread tries to open a TIFF).

using the CVS stuff from about a week ago...

the extender code is pretty much what's documented on the LibTiff site:

static const TIFFFieldInfo xtiffFieldInfo[] =
{
    { TIFFTAG_TAG1, 1, 1, TIFF_LONG, FIELD_CUSTOM, TRUE,   FALSE, "BigSecret1" },
    { TIFFTAG_TAG2,    -3,-3, TIFF_BYTE, FIELD_CUSTOM, FALSE,  TRUE,  "BigSecret2" },
};

static void MyExtendTiffDir(TIFF *tif)
{
    _TIFFMergeFieldInfo(tif, xtiffFieldInfo, ARRAYSIZE(xtiffFieldInfo));

    if (TLSData->m_tiffInfo.m_tiffParentExtender)
    {
       // call parent extender if we have one
       (*TLSData->m_tiffInfo.m_tiffParentExtender)(tif);
    }
}
static void MyInitializeTiffTags(void)
{
    if (!TLSData->m_tiffInfo.m_bTiffTagExtensionsInitialized)
    {
       // first time here?
       TLSData->m_tiffInfo.m_bTiffTagExtensionsInitialized = true;

       // embrace and extend
       TLSData->m_tiffInfo.m_tiffParentExtender = TIFFSetTagExtender(MyExtendTiffDir);
    }
}

TIFF* MyTIFFFdOpen(things* foo, const char * mode)
{
    MyInitializeTiffTags();

    TIFF* tif;

    tif = TIFFClientOpen(...etc)
        ... etc
}

----
Chris Losinger
losinger@earthlink.net
smallest@smalleranimals.com          http://www.smalleranimals.com