Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Weird threading error with LibTiff

Weird threading error with LibTiff

Scheduled Pinned Locked Moved C / C++ / MFC
csharphelpc++htmlperformance
3 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Alan Balkany
    wrote on last edited by
    #1

    Hi, I'm using LibTiff to write TIFF files (from multiple threads) in C++, and getting the following error message: "Probable I/O race condition detected while copying memory. The I/O package is not thread safe by default. In multithreaded applications, a stream must be accessed in a thread-safe way, such as a thread-safe wrapper returned by TeaxtReader´s or TextWriters´s Synchronized methods. This also applies to classes like StreamWriter and StreamReader" (The C++ is being called from a C# GUI, which accounts for the .NET class names.) The weird thing is that the LibTiff call is in a critical section, which (theoretically) should avoid race conditions:

    DLLEXPORT int writeVariableImage (HBITMAP staticBlackLayer, HBITMAP varLayer,
    VariableObject* varObj, int numVarObjects,
    char* fileName)
    {
    if (!criticalSectionInitialized)
    {
    InitializeCriticalSection (&cs);
    criticalSectionInitialized = true;
    }

    EnterCriticalSection(&cs);
    
    try
    {							// Make copy of black
    	if (!copyBitmap (varLayer, staticBlackLayer))	// layer to mark up:
    		throw 666;				// Problem found.
    
    	HDC memDc = CreateCompatibleDC (NULL);		// Prepare to draw:
    	HGDIOBJ Obmp  = SelectObject(memDc, varLayer);
    
    	if (!memDc  ||  !Obmp)
    		throw 666;				// Problem found.
    
    							// Go through objects:
    	for (int i = 0;   i < numVarObjects;   ++i)	// Draw markup:
    		drawVariableObject (memDc, &varObj \[i\]);// Draw next var object.
    
    	invertLayer (memDc, varLayer); 
    	writeToTiffFile (varLayer, fileName);		// Write to file.
    
    	if (!SelectObject (memDc, Obmp)  ||		// Clean up:
    		!DeleteDC (memDc))
    		throw 666;				// Problem found.
    }
    catch (...)
    {
    	DWORD err = GetLastError ();
    
    	if (err)
    	{
    		LPTSTR s;				// Show error message:
    		FormatMessage(FORMAT\_MESSAGE\_ALLOCATE\_BUFFER | FORMAT\_MESSAGE\_FROM\_SYSTEM,
    			NULL, err, 0, (LPTSTR)&s, 0, NULL);
    		MessageBox (NULL, s, L"Error", 0);
    		LocalFree (s);
    	}
    
    	LeaveCriticalSection(&cs);
    	return 0;					// Failed.
    }
    
    LeaveCriticalSection(&cs);
    return 1;						// Success.
    

    }

    The other oddity is that the error only shows up on 1 out of the 4 computers it's been tried on. (The computer that shows the error has 4 cores, the others, 2.) Any ideas what could be causing this, or how to avoid it? Thanks!

    B 1 Reply Last reply
    0
    • A Alan Balkany

      Hi, I'm using LibTiff to write TIFF files (from multiple threads) in C++, and getting the following error message: "Probable I/O race condition detected while copying memory. The I/O package is not thread safe by default. In multithreaded applications, a stream must be accessed in a thread-safe way, such as a thread-safe wrapper returned by TeaxtReader´s or TextWriters´s Synchronized methods. This also applies to classes like StreamWriter and StreamReader" (The C++ is being called from a C# GUI, which accounts for the .NET class names.) The weird thing is that the LibTiff call is in a critical section, which (theoretically) should avoid race conditions:

      DLLEXPORT int writeVariableImage (HBITMAP staticBlackLayer, HBITMAP varLayer,
      VariableObject* varObj, int numVarObjects,
      char* fileName)
      {
      if (!criticalSectionInitialized)
      {
      InitializeCriticalSection (&cs);
      criticalSectionInitialized = true;
      }

      EnterCriticalSection(&cs);
      
      try
      {							// Make copy of black
      	if (!copyBitmap (varLayer, staticBlackLayer))	// layer to mark up:
      		throw 666;				// Problem found.
      
      	HDC memDc = CreateCompatibleDC (NULL);		// Prepare to draw:
      	HGDIOBJ Obmp  = SelectObject(memDc, varLayer);
      
      	if (!memDc  ||  !Obmp)
      		throw 666;				// Problem found.
      
      							// Go through objects:
      	for (int i = 0;   i < numVarObjects;   ++i)	// Draw markup:
      		drawVariableObject (memDc, &varObj \[i\]);// Draw next var object.
      
      	invertLayer (memDc, varLayer); 
      	writeToTiffFile (varLayer, fileName);		// Write to file.
      
      	if (!SelectObject (memDc, Obmp)  ||		// Clean up:
      		!DeleteDC (memDc))
      		throw 666;				// Problem found.
      }
      catch (...)
      {
      	DWORD err = GetLastError ();
      
      	if (err)
      	{
      		LPTSTR s;				// Show error message:
      		FormatMessage(FORMAT\_MESSAGE\_ALLOCATE\_BUFFER | FORMAT\_MESSAGE\_FROM\_SYSTEM,
      			NULL, err, 0, (LPTSTR)&s, 0, NULL);
      		MessageBox (NULL, s, L"Error", 0);
      		LocalFree (s);
      	}
      
      	LeaveCriticalSection(&cs);
      	return 0;					// Failed.
      }
      
      LeaveCriticalSection(&cs);
      return 1;						// Success.
      

      }

      The other oddity is that the error only shows up on 1 out of the 4 computers it's been tried on. (The computer that shows the error has 4 cores, the others, 2.) Any ideas what could be causing this, or how to avoid it? Thanks!

      B Offline
      B Offline
      Blake Miller
      wrote on last edited by
      #2

      Some ideas to help you track down problem. 1. You seem to have the 'source code'. I would move the critical section initialization outside this function and make damn sure it is already done before ANY thead has a achance to call the function. 2. Make sure no two calls are trying to write to the same file. 3. Increment a local variable along the way - print out its value in the exception handler to get an idea WHERE you had a problem. They currently thow 666 everywhere - not too easy to tell what the real problem is when that is being done. I would not try too hard to figure out what is wrong without the changes I suggest above, which is what I would do to allow me to diagnose the actual problem.

      A 1 Reply Last reply
      0
      • B Blake Miller

        Some ideas to help you track down problem. 1. You seem to have the 'source code'. I would move the critical section initialization outside this function and make damn sure it is already done before ANY thead has a achance to call the function. 2. Make sure no two calls are trying to write to the same file. 3. Increment a local variable along the way - print out its value in the exception handler to get an idea WHERE you had a problem. They currently thow 666 everywhere - not too easy to tell what the real problem is when that is being done. I would not try too hard to figure out what is wrong without the changes I suggest above, which is what I would do to allow me to diagnose the actual problem.

        A Offline
        A Offline
        Alan Balkany
        wrote on last edited by
        #3

        Great suggestions! Thanks! (I especially like #1; multiple threads could hit this at once.)

        1 Reply Last reply
        0
        Reply
        • Reply as topic
        Log in to reply
        • Oldest to Newest
        • Newest to Oldest
        • Most Votes


        • Login

        • Don't have an account? Register

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • World
        • Users
        • Groups