From 9e603d8adb02e90d08fec5c6453712df692b931c Mon Sep 17 00:00:00 2001
From: root <root>
Date: Tue, 15 Feb 2011 03:15:16 +0000
Subject: *** empty log message ***

---
 Changes   |  4 +++-
 eio.c     | 43 +++++++++++++++++++++++++++++++------------
 eio.h     |  1 +
 xthread.h | 28 ++++++++++++++++++++--------
 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)
-- 
cgit v1.2.3