Files
libguestfs/lib/errors.c
Richard W.M. Jones b088eb5ef8 threads: Use thread-local storage for errors.
We permit the following constructs in libguestfs code:

  if (guestfs_some_call (g) == -1) {
    fprintf (stderr, "failed: error is %s\n", guestfs_last_error (g));
  }

and:

  guestfs_push_error_handler (g, NULL, NULL);
  guestfs_some_call (g);
  guestfs_pop_error_handler (g);

Neither of these would be safe if we allowed the handle to be used
from threads concurrently, since the error string or error handler
could be changed by another thread.

Solve this in approximately the same way that libvirt does: by making
the error, current error handler, and stack of error handlers use
thread-local storage (TLS).

The implementation is not entirely straightforward, mainly because
POSIX doesn't give us useful destructor behaviour, so effectively we
end up creating our own destructor using a linked list.

Note that you have to set the error handler in each thread separately,
which is an API change (eg: if you set the error handler in one
thread, then pass the handle 'g' to another thread, the error handler
in the second thread appears to have reset itself back to the default
error handler).  I haven't yet worked out a better way to solve this.
2017-09-16 23:06:25 +01:00

16 KiB