Boost logo

Boost :

Subject: Re: [boost] gil::io "non-review" (was: [gil] Can not open test.jpg)
From: John Bytheway (jbytheway+boost_at_[hidden])
Date: 2010-03-24 15:49:10


Phil Endecott wrote:
> Hi Christian,
>
> I wonder if anyone will notice this message amid all the mud and
> flame-slinging that's going on? I know - I'll get everyone's attention
> by pointing out that the fundamental problem here is that the C library,
> libjpeg, has a truly awful API design: when it gets an error, it calls a
> user-supplied function-pointer and that mustn't return.

Yes, that's pretty abominable.

> Christian Henning wrote:
>> Does that mean I have to call setjmp everytime before I call libjeg
>> function? This way the function that calls setjmp would not have been
>> terminated.
>
> Your choices are:
>
> 1. setjmp() in each function (scope?) that calls into libjpeg. That's
> nasty because setjmp(), IIRC, is detected by the compiler and prevents
> some optimisations. It's relatively non-intrusive in your code though.

I can't believe performance is a serious concern here. I think this is
the best option. There's still the thread-safety issue. Can you use
the cinfo to pass the jmp_buf through to error_exit? If not then I guess
the jmp_buf could be stored in static thread-local storage...

> 2. setjmp() once, and make sure that that is in a scope that contains
> all the calls. This means turning your code inside out, but it's not
> impossible because - as we've noted - you never leave a jpeg file open
> and return to the user code, i.e. the setjmp() can happen soon after the
> user calls into your code. I don't think that destructors will not be
> called when longjmp() "pops" the stack, so you need to be careful about
> what types you use.

Yes, that's undefined behaviour too; see e.g. N3000, [support.runtime] p4:

A setjmp/longjmp call pair has undefined behavior if replacing the
setjmp and longjmp by catch
and throw would invoke any non-trivial destructors for any automatic
objects.

> 5. (Grasping at straws) run libjpeg in a co-routine, err, not sure
> exactly how that would work, but something about an extra stack...

More trouble than it's worth, I'm pretty sure.

> 6. This is what I'd really like to see: copy the libjpeg source into
> your project, and then do (4). You could do some other tidying-up at
> the same time.

Sounds nice in principle, but again the benefit over solution 1 is
minor, and the maintenance burden would surely be huge. For example the
entire library would have to be put in a namespace or something so as
not to clash with the 'real' libjpeg.

John Bytheway


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