__gthread_cond_t and __gthread_equal / __gthread_self. Check
this. */
+/* #undef __GTHREADS_CXX0X - uncomment for checking non-threading
+ systems. */
+
#if defined(__GTHREAD_HAS_COND) && defined(__GTHREADS_CXX0X)
#define ASYNC_IO 1
#else
#undef DEBUG_ASYNC
#ifdef DEBUG_ASYNC
+#ifndef __GTHREADS_CXX0X
+#error "gthreads support required for DEBUG_ASYNC"
+#endif
/* Define this if you want to use ANSI color escape sequences in your
debugging output. */
#define DEBUG_LINE(...) __VA_ARGS__
-#else
+#else /* DEBUG_ASYNC */
+
#define DEBUG_PRINTF(...) {}
#define CHECK_LOCK(au, mutex, status) {}
#define NOTE(str, ...) {}
#define DEBUG_LINE(...)
#define T_ERROR(func, ...) func(__VA_ARGS__)
#define LOCK(mutex) INTERN_LOCK (mutex)
-#define LOCK_UNIT(unit) do { \
- if (__gthread_active_p ()) { \
- LOCK (&(unit)->lock); (unit)->self = __gthread_self (); \
- } \
+
+#ifdef __GTHREADS_CXX0X
+
+/* When pthreads are not active, we do not touch the lock for locking /
+ unlocking; the only use for this is checking for recursion. */
+
+#define LOCK_UNIT(unit) do { \
+ if (__gthread_active_p ()) { \
+ LOCK (&(unit)->lock); (unit)->self = __gthread_self (); \
+ } else { \
+ (unit)->self = 1; \
+ } \
} while(0)
+#else
+
+#define LOCK_UNIT(unit) do { \
+ (unit)->self = 1; \
+ } while(0)
+
+#endif
+
#define UNLOCK(mutex) INTERN_UNLOCK (mutex)
+
+#ifdef __GTHREADS_CXX0X
+
#define UNLOCK_UNIT(unit) do { \
if (__gthread_active_p ()) { \
(unit)->self = 0 ; UNLOCK(&(unit)->lock); \
+ } else { \
+ (unit)->self = 0; \
} \
+} while(0)
+#else
+#define UNLOCK_UNIT(unit) do { \
+ (unit)->self = 0; \
} while(0)
+
+#endif
+
#define TRYLOCK(mutex) (__gthread_mutex_trylock (mutex))
+
+#ifdef __GTHREADS_CXX0X
#define TRYLOCK_UNIT(unit) ({ \
int res; \
if (__gthread_active_p ()) { \
if (!res) \
(unit)->self = __gthread_self (); \
} \
- else \
- res = 0; \
+ else { \
+ res = (unit)->self; \
+ (unit)->self = 1; \
+ } \
res; \
})
+#else
+#define TRYLOCK_UNIT(unit) ({ \
+ int res = (unit)->self; \
+ (unit)->self = 1; \
+ res; \
+ })
+#endif
+
#ifdef __GTHREAD_RWLOCK_INIT
#define RDLOCK(rwlock) INTERN_RDLOCK (rwlock)
#define WRLOCK(rwlock) INTERN_WRLOCK (rwlock)
extern __thread gfc_unit *thread_unit;
#endif
+/* When threading is not active, or there is no thread system, we fake the ID
+ to be 1. */
+
+#ifdef __GTHREADS_CXX0X
+#define OWN_THREAD_ID (__gthread_active_p () ? __gthread_self () : 1)
+#else
+#define OWN_THREAD_ID 1
+#endif
+
enum aio_do {
AIO_INVALID = 0,
AIO_DATA_TRANSFER_INIT,
internal_proto (async_wait_id);
bool collect_async_errors (st_parameter_common *, async_unit *);
-internal_proto (collect_async_errors);
+internal_proto (collect_async_errors);
void async_close (async_unit *);
internal_proto (async_close);
/* Recursive I/O is not allowed. Check to see if the UNIT exists and if
so, check if the UNIT is locked already. This check does not apply
to DTIO. */
+
void
check_for_recursive (st_parameter_dt *dtp)
{
/* The lock failed. This unit is locked either our own
thread, which is illegal recursive I/O, or somebody by
else, in which case we are doing OpenMP or similar; this
- is harmless and permitted. */
- __gthread_t locker = __atomic_load_n (&p->self, __ATOMIC_RELAXED);
- if (locker == __gthread_self ())
+ is harmless and permitted. When threading is not active, or
+ there is no thread system, we fake the ID to be 1. */
+ if (__atomic_load_n (&p->self, __ATOMIC_RELAXED) == OWN_THREAD_ID)
generate_error (&dtp->common, LIBERROR_RECURSIVE_IO, NULL);
return;
}