unsigned open_flags) {
xc_interface xch_buf, *xch = &xch_buf;
+ xch->flags = open_flags;
xch->fd = -1;
xch->dombuild_logger_file = 0;
xc_clear_last_error(xch);
const char *xc_strerror(xc_interface *xch, int errcode)
{
+ if ( xch->flags & XC_OPENFLAG_NON_REENTRANT )
+ {
+ return strerror(errcode);
+ }
+ else
+ {
#define XS_BUFSIZE 32
- char *errbuf;
- static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
- char *strerror_str;
+ char *errbuf;
+ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+ char *strerror_str;
- pthread_once(&errbuf_pkey_once, _xc_init_errbuf);
+ 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, XS_BUFSIZE);
- errbuf[XS_BUFSIZE-1] = '\0';
- pthread_mutex_unlock(&mutex);
+ errbuf = pthread_getspecific(errbuf_pkey);
+ if (errbuf == NULL) {
+ errbuf = malloc(XS_BUFSIZE);
+ pthread_setspecific(errbuf_pkey, errbuf);
+ }
- return 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, XS_BUFSIZE);
+ errbuf[XS_BUFSIZE-1] = '\0';
+ pthread_mutex_unlock(&mutex);
+
+ return errbuf;
+ }
}
void bitmap_64_to_byte(uint8_t *bp, const uint64_t *lp, int nbits)
* if dombuild_logger=NULL, will log to a file
*/
+/*
+ * Note: if XC_OPENFLAG_NON_REENTRANT is passed then libxc must not be
+ * called reentrantly and the calling application is responsible for
+ * providing mutual exclusion surrounding all libxc calls itself.
+ *
+ * In particular xc_{get,clear}_last_error only remain valid for the
+ * duration of the critical section containing the call which failed.
+ */
enum xc_open_flags {
- XC_OPENFLAG_DUMMY = 01, /* do not actually open a xenctrl interface */
+ XC_OPENFLAG_DUMMY = 1<<0, /* do not actually open a xenctrl interface */
+ XC_OPENFLAG_NON_REENTRANT = 1<<1, /* assume library is only every called from a single thread */
};
/**