Huge API change: The right way?

Re: “The right way to do it”

 While I wholeheartedly agree that the errno global variable is the 
 wrong way to do it, I don't think it's 100% clear that passing a 
 separate variable is the right solution.
 
 As detailed in an earlier message of mine, setting a thread-local 
 error buffer could be another alternative.  I haven't seen any 
 rebuttals of why that method would not work.  As detailed in my 
 earlier message, performance could be kept good.  Further, it would 
 keep the API simple.  Simplicity is good.
 
 Warren E. Downs

______________________________ Reply Separator _________________________________Subject: Re: [SDL] Huge API change
Author: at internet-mail
Date: 7/28/99 10:21 AM

Please forgive my rant.

On Wed, 28 Jul 1999, Sam Lantinga wrote:

I am ambivalent about the change. It would be the “Right Thing To Do”,
but the API gets more complicated, and the benefit only touches a few
people:

I’m with you Sam. The right thing to do is in fact the right thing to do.
Let’s put this in perspective. One additional parameter per function call
is about as close to zero in performance hit as you can get, so I don’t
want to hear anything about how inefficient this would be. But also, the
errno method was a kludge 30 years ago, and it is today. It’s just the
Wrong Way to do it. Now, people who have learned to deal with the
idiosyncrasies of passing data through global variables have just patched
a sinking ship. It just shouldn’t be done. I can’t count the number of
times that I’ve been screwed by this kind of thinking. But when I learned
to do things the right way, and not rely on “Well, I’ll just have to be
careful, and not do N.” Six months later, I’ll do N and not realize why
the whole system came crashing down.

Pro:
Thread-safe error handling
Internationalized error messages
Function-specific errors (i.e. no global errno value)
Better defined error conditions

Right on. A well-designed threaded machine kicks the pants of anything in
a single thread. Look at BeOS… then look at MacOS. :wink: Anything that
makes threaded programming easier and more stable is a Good Thing.

Con:
Adds complexity to the API

Minimal.

Lets make the change now, while we are in v0.9, lest we are stuck with
something yucky for a long long time.

Again, please forgive my rant. I just wanted Sam to know there’s someone
on his side, and lend support.

-Chuck

 As detailed in an earlier message of mine, setting a thread-local 
 error buffer could be another alternative.  I haven't seen any 
 rebuttals of why that method would not work.  As detailed in my 
 earlier message, performance could be kept good.  Further, it would 
 keep the API simple.  Simplicity is good.

I agree.

Here is the problem with the per-thread error buffer:

Let’s say you have 3 threads, each with an error buffer.
Since they all share the same memory, they need to traverse a list of
error buffers to determine which one to use every time they want to
save an error code.
This list needs to be locked so that when a new thread is created,
or a dead thread is cleaned up, it’s entry can be safely added or
removed from the list. The details of what happens if you do not
lock the list will be left to an excercise for the reader, but
suffice to say that it results in a potential crashing race condition.
Now let’s say that a thread is in the process of filling an error
buffer, and it gets an interrupt. A good example of this would be
a blit failing because the destination surface is an unsupported
pixel format. Now let’s say that the user hits Ctrl-C, generating
a signal interrupt in that thread. The Ctrl-C handler tries to
queue up a “user requested quit” message, which fails for some reason.
Now the Ctrl-C handler tries to lock the thread error buffer list
and deadlocks because it was already locked.

This scenario is specific to UNIX, but any place where a thread
can be handling an error and become interrupted could create a
similar problem.

Agreed, the chance that something like this could happen is small,
but it is still a possibility, and a well designed API should avoid
it if there is a choice.

-Sam Lantinga				(slouken at devolution.com)

Lead Programmer, Loki Entertainment Software–
“Any sufficiently advanced bug is indistinguishable from a feature”
– Rich Kulawiec