2017.03.17 21:02 "Re: [Tiff] TIFFSetErrorHandler vs TIFFSetErrorHandlerExt", by
On 2017-03-17 17:02, Bob Friesenhahn wrote:
If I understand you correctly, I cannot have multiple threads each with its own handler throwing errors/warnings. i need to ensure that only one thread does the error handling, am I correct?
You can only register one error handling function at a time. The function will be called under the same context as the thread which encountered the problem. Knowing that it is called under the same execution context can be very useful.
As a follow up, do i have to set the client_data field with a pointer to my class such that it is accessible in the callbacks?
The client_data is for you. If you use TIFFClientOpen() then it is provided so that you can use it has a handle for I/O or other purposes (e.g. also for errors).
In GraphicsMagick I use TIFFSetErrorHandler()/TIFFSetWarningHandler() and I use thread-specific data (POSIX or Windows) to reconcile between the error callback data and what the thread was working on. I don't use client_data for that purpose. This approach works if there is just one thread which ever does libtiff operations for a given handle.
The reason for the approach in GraphicsMagick is that the implementation pre-dates the addition of TIFFSetErrorHandlerExt() and it also works for older libtiff.
Could I suggest a perhaps controversial but useful solution for handling errors, which might be worth your consideration.
If the libtiff core were to use a C++ TIFF class reporting errors via exceptions, it would be possible for this to be wrapped by the existing C API calling the C++ code in a try/catch block and reporting any thrown errors via the handlers. Or direct use by C++ code without any of that overhead--it could use the C++ API directly with exceptions. This would permit completely thread-safe use from C++, and it would also permit multiple C error handling strategies--either with the global handler as now, a per-TIFF handler or something completely different. The C API could simply be a thin wrapper around the C++ core, and remain 100% backward compatible while also allowing direct use from C++ without wrapping the C code.
In the OME project I currently work on, we already have a fairly complex C++ wrapper around the C API. It works, but due to the need to synchronise for the context-specific error handler, it's much more inefficient and complex than it would need to be were it native. If using a C++ core would be something worth considering, it's likely I could dedicate some paid time to working on it, since it would replace a whole lot of wrapper code we already have to maintain.