summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changes4
-rw-r--r--eio.c43
-rw-r--r--eio.h1
-rw-r--r--xthread.h28
4 files changed, 55 insertions, 21 deletions
diff --git a/Changes b/Changes
index 0c76d18..17b869a 100644
--- a/Changes
+++ b/Changes
@@ -2,9 +2,11 @@ Revision history for libeio
TODO: maybe add mincore support? available on at least darwin, solaris, linux, freebsd
TODO: openbsd requires stdint.h for intptr_t - why posix?
-TODO: mutex init in child after fork?
1.0
+ - use nonstandard but maybe-working-on-bsd fork technique.
+ - support a max_idle value of 0.
+ - support setting of idle timeout value.
- readdir: correctly handle malloc failures.
- readdir: new flags argument, can return inode
and possibly filetype, can sort in various ways.
diff --git a/eio.c b/eio.c
index 2958f69..b303299 100644
--- a/eio.c
+++ b/eio.c
@@ -134,9 +134,6 @@
# define D_NAMLEN(de) strlen ((de)->d_name)
#endif
-/* number of seconds after which an idle threads exit */
-#define IDLE_TIMEOUT 10
-
/* used for struct dirent, AIX doesn't provide it */
#ifndef NAME_MAX
# define NAME_MAX 4096
@@ -225,12 +222,13 @@ static unsigned int max_poll_reqs; /* reslock */
static volatile unsigned int nreqs; /* reqlock */
static volatile unsigned int nready; /* reqlock */
static volatile unsigned int npending; /* reqlock */
-static volatile unsigned int max_idle = 4;
+static volatile unsigned int max_idle = 4; /* maximum number of threads that can idle indefinitely */
+static volatile unsigned int idle_timeout = 10; /* number of seconds after which an idle threads exit */
-static xmutex_t wrklock = X_MUTEX_INIT;
-static xmutex_t reslock = X_MUTEX_INIT;
-static xmutex_t reqlock = X_MUTEX_INIT;
-static xcond_t reqwait = X_COND_INIT;
+static xmutex_t wrklock;
+static xmutex_t reslock;
+static xmutex_t reqlock;
+static xcond_t reqwait;
#if !HAVE_PREADWRITE
/*
@@ -370,6 +368,14 @@ static ETP_REQ *reqq_shift (etp_reqq *q)
abort ();
}
+static void etp_thread_init (void)
+{
+ X_MUTEX_CREATE (wrklock);
+ X_MUTEX_CREATE (reslock);
+ X_MUTEX_CREATE (reqlock);
+ X_COND_CREATE (reqwait);
+}
+
static void etp_atfork_prepare (void)
{
X_LOCK (wrklock);
@@ -417,12 +423,13 @@ static void etp_atfork_child (void)
nready = 0;
npending = 0;
- etp_atfork_parent ();
+ etp_thread_init ();
}
static void
etp_once_init (void)
-{
+{
+ etp_thread_init ();
X_THREAD_ATFORK (etp_atfork_prepare, etp_atfork_parent, etp_atfork_child);
}
@@ -623,7 +630,14 @@ static void etp_set_max_poll_reqs (unsigned int maxreqs)
static void etp_set_max_idle (unsigned int nthreads)
{
if (WORDACCESS_UNSAFE) X_LOCK (reqlock);
- max_idle = nthreads <= 0 ? 1 : nthreads;
+ max_idle = nthreads;
+ if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock);
+}
+
+static void etp_set_idle_timeout (unsigned int seconds)
+{
+ if (WORDACCESS_UNSAFE) X_LOCK (reqlock);
+ idle_timeout = seconds;
if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock);
}
@@ -761,6 +775,11 @@ void eio_set_max_idle (unsigned int nthreads)
etp_set_max_idle (nthreads);
}
+void eio_set_idle_timeout (unsigned int seconds)
+{
+ etp_set_idle_timeout (seconds);
+}
+
void eio_set_min_parallel (unsigned int nthreads)
{
etp_set_min_parallel (nthreads);
@@ -1553,7 +1572,7 @@ X_THREAD_PROC (etp_proc)
++idle;
- ts.tv_sec = time (0) + IDLE_TIMEOUT;
+ ts.tv_sec = time (0) + idle_timeout;
if (X_COND_TIMEDWAIT (reqwait, reqlock, ts) == ETIMEDOUT)
{
if (idle > max_idle)
diff --git a/eio.h b/eio.h
index 9c621f9..001d3b9 100644
--- a/eio.h
+++ b/eio.h
@@ -241,6 +241,7 @@ void eio_set_max_poll_reqs (unsigned int nreqs);
void eio_set_min_parallel (unsigned int nthreads);
void eio_set_max_parallel (unsigned int nthreads);
void eio_set_max_idle (unsigned int nthreads);
+void eio_set_idle_timeout (unsigned int seconds);
unsigned int eio_nreqs (void); /* number of requests in-flight */
unsigned int eio_nready (void); /* number of not-yet handled requests */
diff --git a/xthread.h b/xthread.h
index 8400fdd..edc812b 100644
--- a/xthread.h
+++ b/xthread.h
@@ -29,6 +29,7 @@ typedef int ssize_t;
#include <windows.h>
#include <pthread.h>
#define sigset_t int
+#define sigfillset(a)
#define pthread_sigmask(a,b,c)
#define sigaddset(a,b)
#define sigemptyset(s)
@@ -36,11 +37,13 @@ typedef int ssize_t;
typedef pthread_mutex_t xmutex_t;
#define X_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
+#define X_MUTEX_CREATE(mutex) pthread_mutex_init (&(mutex), 0)
#define X_LOCK(mutex) pthread_mutex_lock (&(mutex))
#define X_UNLOCK(mutex) pthread_mutex_unlock (&(mutex))
typedef pthread_cond_t xcond_t;
#define X_COND_INIT PTHREAD_COND_INITIALIZER
+#define X_COND_CREATE(cond) pthread_cond_init (&(cond), 0)
#define X_COND_SIGNAL(cond) pthread_cond_signal (&(cond))
#define X_COND_WAIT(cond,mutex) pthread_cond_wait (&(cond), &(mutex))
#define X_COND_TIMEDWAIT(cond,mutex,to) pthread_cond_timedwait (&(cond), &(mutex), &(to))
@@ -95,18 +98,27 @@ thread_create (xthread_t *tid, void *(*proc)(void *), void *arg)
typedef pthread_mutex_t xmutex_t;
#if __linux && defined (PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP)
-# define X_MUTEX_INIT PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
+# define X_MUTEX_INIT PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
+# define X_MUTEX_CREATE(mutex) \
+ do { \
+ pthread_mutexattr_t attr; \
+ pthread_mutexattr_init (&attr); \
+ pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ADAPTIVE_NP); \
+ pthread_mutex_init (&(mutex), &attr); \
+ } while (0)
#else
-# define X_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
+# define X_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
+# define X_MUTEX_CREATE(mutex) pthread_mutex_init (&(mutex), 0)
#endif
-#define X_LOCK(mutex) pthread_mutex_lock (&(mutex))
-#define X_UNLOCK(mutex) pthread_mutex_unlock (&(mutex))
+#define X_LOCK(mutex) pthread_mutex_lock (&(mutex))
+#define X_UNLOCK(mutex) pthread_mutex_unlock (&(mutex))
typedef pthread_cond_t xcond_t;
-#define X_COND_INIT PTHREAD_COND_INITIALIZER
-#define X_COND_SIGNAL(cond) pthread_cond_signal (&(cond))
-#define X_COND_WAIT(cond,mutex) pthread_cond_wait (&(cond), &(mutex))
-#define X_COND_TIMEDWAIT(cond,mutex,to) pthread_cond_timedwait (&(cond), &(mutex), &(to))
+#define X_COND_INIT PTHREAD_COND_INITIALIZER
+#define X_COND_CREATE(cond) pthread_cond_init (&(cond), 0)
+#define X_COND_SIGNAL(cond) pthread_cond_signal (&(cond))
+#define X_COND_WAIT(cond,mutex) pthread_cond_wait (&(cond), &(mutex))
+#define X_COND_TIMEDWAIT(cond,mutex,to) pthread_cond_timedwait (&(cond), &(mutex), &(to))
typedef pthread_t xthread_t;
#define X_THREAD_PROC(name) static void *name (void *thr_arg)