On Thu, Dec 14, 2023 at 05:55:41PM +0100, Peter Krempa wrote:
If you need any form of more complex logic in your application for
error
reporting (ab)using libvirt's thread local variable to store the error
I'm a bit lost on the "abuse" claim here. Is this abuse in your eyes:
```
int saved_errno = errno;
close(fd);
errno = saved_errno;
```
since "errno" is libc's thread local variable that stores the error?
for other functions in your application will not bring too much
simplification of the logic itself.
Excuse the pseudocode:
```
int func() {
...
cleanup:
err = virErrorSaveLast(error);
virDomainFree(domain);
virErrorRestore(error);
return ret;
}
func2() {
ret = func();
fprintf(stderr, "%s\n", virGetLastErrorMessage());
```
versus:
```
int func() {
...
cleanup:
err = pthread_getspecific(global->pthread_key_libvirt_error);
*err = virSaveLastError();
virDomainFree(domain);
pthread_setspecific(global->pthread_key_libvirt_error, err);
return ret;
}
func2() {
ret = func();
err = pthread_getspecific(global->pthread_key_libvirt_error);
fprintf(stderr, "%s\n", err->message);
```
If your argument is that the second version is somehow better, I don't think
we're going to agree, and we'll just keep another local patch. Thanks for the
discussion!
Using the global error handler function is not a very good idea in
multithreaded applications
Side note: there's little point in me going into it, but been there, earned the
scars. Due to, for example, various connection failures showing up as
VIR_ERR_INTERNAL_ERROR, there's no reliable way to use the close callback with
multiple threads sharing a connection and correctly differentiating between a
need to reconnect and an actual API failure.
Although, it sounds like you know of a counter-example piece of code: is it
something you could share?
regards
john