159 lines
3.9 KiB
Text
159 lines
3.9 KiB
Text
--- libxc/xc_private.c.orig 2008-04-25 15:03:12.000000000 +0200
|
|
+++ libxc/xc_private.c 2008-09-14 23:37:40.000000000 +0200
|
|
@@ -10,7 +10,12 @@
|
|
#include <stdarg.h>
|
|
#include <pthread.h>
|
|
|
|
-static __thread xc_error last_error = { XC_ERROR_NONE, ""};
|
|
+static pthread_key_t last_error_pkey;
|
|
+static pthread_once_t last_error_pkey_once = PTHREAD_ONCE_INIT;
|
|
+
|
|
+static pthread_key_t errbuf_pkey;
|
|
+static pthread_once_t errbuf_pkey_once = PTHREAD_ONCE_INIT;
|
|
+
|
|
#if DEBUG
|
|
static xc_error_handler error_handler = xc_default_error_handler;
|
|
#else
|
|
@@ -23,15 +28,44 @@
|
|
fprintf(stderr, "ERROR %s: %s\n", desc, err->message);
|
|
}
|
|
|
|
+static void
|
|
+_xc_clean_last_error(void *m)
|
|
+{
|
|
+ if (m)
|
|
+ free(m);
|
|
+ pthread_setspecific(last_error_pkey, NULL);
|
|
+}
|
|
+
|
|
+static void
|
|
+_xc_init_last_error(void)
|
|
+{
|
|
+ pthread_key_create(&last_error_pkey, _xc_clean_last_error);
|
|
+}
|
|
+static xc_error *
|
|
+_xc_get_last_error(void) {
|
|
+ xc_error *last_error;
|
|
+
|
|
+ pthread_once(&last_error_pkey_once, _xc_init_last_error);
|
|
+
|
|
+ last_error = pthread_getspecific(last_error_pkey);
|
|
+ if (last_error == NULL) {
|
|
+ last_error = malloc(sizeof(xc_error));
|
|
+ pthread_setspecific(last_error_pkey, last_error);
|
|
+ }
|
|
+ return last_error;
|
|
+}
|
|
+
|
|
+
|
|
const xc_error *xc_get_last_error(void)
|
|
{
|
|
- return &last_error;
|
|
+ return _xc_get_last_error();
|
|
}
|
|
|
|
void xc_clear_last_error(void)
|
|
{
|
|
- last_error.code = XC_ERROR_NONE;
|
|
- last_error.message[0] = '\0';
|
|
+ xc_error *last_error = _xc_get_last_error();
|
|
+ last_error->code = XC_ERROR_NONE;
|
|
+ last_error->message[0] = '\0';
|
|
}
|
|
|
|
const char *xc_error_code_to_desc(int code)
|
|
@@ -64,9 +98,10 @@
|
|
|
|
static void _xc_set_error(int code, const char *msg)
|
|
{
|
|
- last_error.code = code;
|
|
- strncpy(last_error.message, msg, XC_MAX_ERROR_MSG_LEN - 1);
|
|
- last_error.message[XC_MAX_ERROR_MSG_LEN-1] = '\0';
|
|
+ xc_error *last_error = _xc_get_last_error();
|
|
+ last_error->code = code;
|
|
+ strncpy(last_error->message, msg, XC_MAX_ERROR_MSG_LEN - 1);
|
|
+ last_error->message[XC_MAX_ERROR_MSG_LEN-1] = '\0';
|
|
}
|
|
|
|
void xc_set_error(int code, const char *fmt, ...)
|
|
@@ -84,13 +119,19 @@
|
|
|
|
errno = saved_errno;
|
|
|
|
- if ( error_handler != NULL )
|
|
- error_handler(&last_error);
|
|
+ if ( error_handler != NULL ) {
|
|
+ xc_error *last_error = _xc_get_last_error();
|
|
+ error_handler(last_error);
|
|
+ }
|
|
}
|
|
|
|
int lock_pages(void *addr, size_t len)
|
|
{
|
|
int e = 0;
|
|
+ size_t offset = (u_long)addr & 0xfffUL;
|
|
+ addr -= offset;
|
|
+ len += offset;
|
|
+ len = (len + 0xfffUL) & ~0xfffUL; /* round up */
|
|
#ifndef __sun__
|
|
e = mlock(addr, len);
|
|
#endif
|
|
@@ -99,8 +140,10 @@
|
|
|
|
void unlock_pages(void *addr, size_t len)
|
|
{
|
|
+ void *laddr = (void *)((u_long)addr & ~0xfffUL);
|
|
+ size_t llen = (len + 0xfffUL) & ~0xfffUL;
|
|
#ifndef __sun__
|
|
- safe_munlock(addr, len);
|
|
+ safe_munlock(laddr, llen);
|
|
#endif
|
|
}
|
|
|
|
@@ -466,20 +509,43 @@
|
|
return new_mfn;
|
|
}
|
|
|
|
+static void
|
|
+_xc_clean_errbuf(void * m)
|
|
+{
|
|
+ if (m)
|
|
+ free(m);
|
|
+ pthread_setspecific(errbuf_pkey, NULL);
|
|
+}
|
|
+
|
|
+static void
|
|
+_xc_init_errbuf(void)
|
|
+{
|
|
+ pthread_key_create(&errbuf_pkey, _xc_clean_errbuf);
|
|
+}
|
|
+
|
|
char *safe_strerror(int errcode)
|
|
{
|
|
- static __thread char errbuf[32];
|
|
+#define XS_BUFSIZE 32
|
|
+ char *errbuf;
|
|
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
char *strerror_str;
|
|
|
|
+ pthread_once(&errbuf_pkey_once, _xc_init_errbuf);
|
|
+
|
|
+ errbuf = pthread_getspecific(errbuf_pkey);
|
|
+ if (errbuf == NULL) {
|
|
+ errbuf = malloc(XS_BUFSIZE);
|
|
+ pthread_setspecific(errbuf_pkey, errbuf);
|
|
+ }
|
|
+
|
|
/*
|
|
* Thread-unsafe strerror() is protected by a local mutex. We copy
|
|
* the string to a thread-private buffer before releasing the mutex.
|
|
*/
|
|
pthread_mutex_lock(&mutex);
|
|
strerror_str = strerror(errcode);
|
|
- strncpy(errbuf, strerror_str, sizeof(errbuf));
|
|
- errbuf[sizeof(errbuf)-1] = '\0';
|
|
+ strncpy(errbuf, strerror_str, XS_BUFSIZE);
|
|
+ errbuf[XS_BUFSIZE-1] = '\0';
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
return errbuf;
|