summaryrefslogtreecommitdiff
path: root/apt-pkg/contrib/error.cc
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg/contrib/error.cc')
-rw-r--r--apt-pkg/contrib/error.cc26
1 files changed, 24 insertions, 2 deletions
diff --git a/apt-pkg/contrib/error.cc b/apt-pkg/contrib/error.cc
index 143b99557..2de13b4ae 100644
--- a/apt-pkg/contrib/error.cc
+++ b/apt-pkg/contrib/error.cc
@@ -32,11 +32,33 @@
/*}}}*/
// Global Error Object /*{{{*/
+/* If the implementation supports posix threads then the accessor function
+ is compiled to be thread safe otherwise a non-safe version is used. A
+ Per-Thread error object is maintained in much the same manner as libc
+ manages errno */
+#if defined(_POSIX_THREADS) && defined(HAVE_PTHREAD)
+#include <pthread.h>
+
+static pthread_key_t ErrorKey;
+static void ErrorDestroy(void *Obj) { delete (GlobalError *)Obj; };
+static void KeyAlloc() { pthread_key_create(&ErrorKey, ErrorDestroy); };
+
GlobalError *_GetErrorObj()
{
- static thread_local GlobalError Obj;
- return &Obj;
+ static pthread_once_t Once = PTHREAD_ONCE_INIT;
+ pthread_once(&Once, KeyAlloc);
+
+ void *Res = pthread_getspecific(ErrorKey);
+ if (Res == 0)
+ pthread_setspecific(ErrorKey, Res = new GlobalError);
+ return (GlobalError *)Res;
+}
+#else
+GlobalError *_GetErrorObj() {
+ static GlobalError *Obj = new GlobalError;
+ return Obj;
}
+#endif
/*}}}*/
// GlobalError::GlobalError - Constructor /*{{{*/
GlobalError::GlobalError() : PendingFlag(false) {}