httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Aaron Bannert <aa...@ebuilt.com>
Subject [PATCH] APR thread updates and associated httpd-2.0 changes
Date Fri, 20 Jul 2001 17:30:53 GMT
I submitted most of this patch last weekend. Since then I've fixed
a small bug in the apr_thread_exit() patch I made (I could really
use APR commit access for the little things like this :). I haven't
heard any objections (Ryan ;), so I assume these changes were acceptable.

I've also brought my httpd-2.0 tree up to date with the APR patch.
(Pretty minor changes. Please verify.)

As a reminder, here are the things this fixes/changes:

- fixes apr_thread_exit(), it wasn't actually passing the return status back.
- changes apr_thread_start_t (worker's function prototype) to take the
  parameter apr_thread_param_t, which contains the thread pointer and
  the opaque data pointer.
- adds a new test in test/testthread.c to make sure apr_thread_exit() is
  working.

(and the new parts for httpd-2.0)
- updates httpd-2.0 to work with the above changes. changes the worker
  functions in the threaded mpm and perchild mpm.

enjoy,
-aaron


Index: server/mpm/perchild/perchild.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/server/mpm/perchild/perchild.c,v
retrieving revision 1.71
diff -u -r1.71 perchild.c
--- server/mpm/perchild/perchild.c	2001/07/18 20:45:35	1.71
+++ server/mpm/perchild/perchild.c	2001/07/20 17:11:30
@@ -512,7 +512,7 @@
     }
 }
 
-static void *worker_thread(void *);
+static void *worker_thread(apr_thread_param_t *);
 
 /* Starts a thread as long as we're below max_threads */
 static int start_thread(void)
@@ -579,8 +579,9 @@
 
 /* idle_thread_count should be incremented before starting a worker_thread */
 
-static void *worker_thread(void *arg)
+static void *worker_thread(apr_thread_param_t *param)
 {
+    apr_thread_t *thread = param->t;
     apr_socket_t *csd = NULL;
     apr_pool_t *tpool;		/* Pool for this thread           */
     apr_pool_t *ptrans;		/* Pool for per-transaction stuff */
@@ -588,7 +589,7 @@
     int srv;
     int curr_pollfd, last_pollfd = 0;
     int thread_just_started = 1;
-    int thread_num = *((int *) arg);
+    int thread_num = *((int *) param->data);
     long conn_id = child_num * HARD_THREAD_LIMIT + thread_num;
     apr_pollfd_t *pollset;
     int n;
@@ -789,6 +790,7 @@
     }
     apr_lock_release(worker_thread_count_mutex);
 
+    apr_thread_exit(thread, NULL);
     return NULL;
 }
 
Index: server/mpm/threaded/threaded.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/server/mpm/threaded/threaded.c,v
retrieving revision 1.46
diff -u -r1.46 threaded.c
--- server/mpm/threaded/threaded.c	2001/07/18 20:45:36	1.46
+++ server/mpm/threaded/threaded.c	2001/07/20 17:11:32
@@ -520,9 +520,10 @@
     apr_lock_release(pipe_of_death_mutex);
 }
 
-static void * worker_thread(void * dummy)
+static void * worker_thread(apr_thread_param_t *param)
 {
-    proc_info * ti = dummy;
+    apr_thread_t *thread = param->t;
+    proc_info * ti = param->data;
     int process_slot = ti->pid;
     int thread_slot = ti->tid;
     apr_pool_t *tpool = ti->tpool;
@@ -658,6 +659,7 @@
     }
     apr_lock_release(worker_thread_count_mutex);
 
+    apr_thread_exit(thread, NULL);
     return NULL;
 }
 
@@ -671,9 +673,10 @@
     return 0;
 }
 
-static void *start_threads(void * dummy)
+static void *start_threads(apr_thread_param_t *param)
 {
-    thread_starter *ts = dummy;
+    apr_thread_t *thread = param->t;
+    thread_starter *ts = param->data;
     apr_thread_t **threads = ts->threads;
     apr_threadattr_t *thread_attr = ts->threadattr;
     int child_num_arg = ts->child_num_arg;
@@ -733,6 +736,7 @@
      *  "life_status" is almost right, but it's in the worker's structure, and 
      *  the name could be clearer.   gla
      */
+    apr_thread_exit(thread, NULL);
     return NULL;
 }
 
Index: srclib/apr/include/apr_thread_proc.h
===================================================================
RCS file: /home/cvspublic/apr/include/apr_thread_proc.h,v
retrieving revision 1.65
diff -u -r1.65 apr_thread_proc.h
--- srclib/apr/include/apr_thread_proc.h	2001/06/06 18:11:06	1.65
+++ srclib/apr/include/apr_thread_proc.h	2001/07/20 17:11:32
@@ -125,7 +125,13 @@
 typedef struct apr_other_child_rec_t  apr_other_child_rec_t;
 #endif /* APR_HAS_OTHER_CHILD */
 
-typedef void *(APR_THREAD_FUNC *apr_thread_start_t)(void *);
+struct apr_thread_param_t {
+    apr_thread_t *t;
+    void *data;
+};
+typedef struct apr_thread_param_t apr_thread_param_t;
+
+typedef void *(APR_THREAD_FUNC *apr_thread_start_t)(apr_thread_param_t *);
 
 enum kill_conditions {
     kill_never,                 /* process is never sent any signals */
Index: srclib/apr/test/testthread.c
===================================================================
RCS file: /home/cvspublic/apr/test/testthread.c,v
retrieving revision 1.17
diff -u -r1.17 testthread.c
--- srclib/apr/test/testthread.c	2001/03/14 15:56:44	1.17
+++ srclib/apr/test/testthread.c	2001/07/20 17:11:33
@@ -72,57 +72,66 @@
 }
 #else /* !APR_HAS_THREADS */
 
-void * APR_THREAD_FUNC thread_func1(void *data);
-void * APR_THREAD_FUNC thread_func2(void *data);
-void * APR_THREAD_FUNC thread_func3(void *data);
-void * APR_THREAD_FUNC thread_func4(void *data);
+void * APR_THREAD_FUNC thread_func1(apr_thread_param_t *thrparm);
+void * APR_THREAD_FUNC thread_func2(apr_thread_param_t *thrparm);
+void * APR_THREAD_FUNC thread_func3(apr_thread_param_t *thrparm);
+void * APR_THREAD_FUNC thread_func4(apr_thread_param_t *thrparm);
 
 
 apr_lock_t *thread_lock;
 apr_pool_t *context;
 int x = 0;
+apr_status_t exit_ret_val = 123; /* just some made up number to check on later */
 
-void * APR_THREAD_FUNC thread_func1(void *data)
+void * APR_THREAD_FUNC thread_func1(apr_thread_param_t *thrparm)
 {
     int i;
+    apr_thread_t *thread = thrparm->t;
     for (i = 0; i < 10000; i++) {
         apr_lock_acquire(thread_lock);
         x++;
         apr_lock_release(thread_lock);
     }
+    apr_thread_exit(thread, &exit_ret_val);
     return NULL;
 } 
 
-void * APR_THREAD_FUNC thread_func2(void *data)
+void * APR_THREAD_FUNC thread_func2(apr_thread_param_t *thrparm)
 {
     int i;
+    apr_thread_t *thread = thrparm->t;
     for (i = 0; i < 10000; i++) {
         apr_lock_acquire(thread_lock);
         x++;
         apr_lock_release(thread_lock);
     }
+    apr_thread_exit(thread, &exit_ret_val);
     return NULL;
 } 
 
-void * APR_THREAD_FUNC thread_func3(void *data)
+void * APR_THREAD_FUNC thread_func3(apr_thread_param_t *thrparm)
 {
     int i;
+    apr_thread_t *thread = thrparm->t;
     for (i = 0; i < 10000; i++) {
         apr_lock_acquire(thread_lock);
         x++;
         apr_lock_release(thread_lock);
     }
+    apr_thread_exit(thread, &exit_ret_val);
     return NULL;
 } 
 
-void * APR_THREAD_FUNC thread_func4(void *data)
+void * APR_THREAD_FUNC thread_func4(apr_thread_param_t *thrparm)
 {
     int i;
+    apr_thread_t *thread = thrparm->t;
     for (i = 0; i < 10000; i++) {
         apr_lock_acquire(thread_lock);
         x++;
         apr_lock_release(thread_lock);
     }
+    apr_thread_exit(thread, &exit_ret_val);
     return NULL;
 } 
 
@@ -172,7 +181,15 @@
     apr_thread_join(&s2, t2);
     apr_thread_join(&s3, t3);
     apr_thread_join(&s4, t4);
-    fprintf (stdout, "OK\n");   
+    fprintf (stdout, "OK\n");
+
+    fprintf(stdout, "Checking thread's returned value.......");
+    if (s1 != exit_ret_val || s2 != exit_ret_val ||
+        s3 != exit_ret_val || s4 != exit_ret_val) {
+        fprintf(stderr, "Invalid return value (not expected value)\n");
+        exit(-1);
+    }
+    fprintf(stdout, "OK\n");
 
     fprintf(stdout, "Checking if locks worked......."); 
     if (x != 40000) {
Index: srclib/apr/threadproc/beos/thread.c
===================================================================
RCS file: /home/cvspublic/apr/threadproc/beos/thread.c,v
retrieving revision 1.22
diff -u -r1.22 thread.c
--- srclib/apr/threadproc/beos/thread.c	2001/06/14 18:52:05	1.22
+++ srclib/apr/threadproc/beos/thread.c	2001/07/20 17:11:33
@@ -94,13 +94,17 @@
 {
     int32 temp;
     apr_status_t stat;
+    struct thread_info_t *thr_info;
+    apr_thread_t *thread;
+    apr_thread_param_t *thrparm;
     
-    (*new) = (apr_thread_t *)apr_palloc(cont, sizeof(apr_thread_t));
-    if ((*new) == NULL) {
+    thread = (apr_thread_t *)apr_palloc(cont, sizeof(apr_thread_t));
+    (*new) = thread;
+    if (thread == NULL) {
         return APR_ENOMEM;
     }
 
-    (*new)->cntxt = cont;
+    thread->cntxt = cont;
 
     /* First we create the new thread...*/
 	if (attr)
@@ -108,14 +112,23 @@
 	else
 	    temp = B_NORMAL_PRIORITY;
 
-    stat = apr_pool_create(&(*new)->cntxt, cont);
+    stat = apr_pool_create(&thread->cntxt, cont);
     if (stat != APR_SUCCESS) {
         return stat;
     }
 
-    (*new)->td = spawn_thread((thread_func)func, "apr thread", temp, data);
+    thread->cntxt = cont;
+
+    thrparm = (apr_thread_param_t *)apr_palloc(cont, sizeof(apr_thread_param_t));
+    if (thrparm == NULL) {
+        return APR_ENOMEM;
+    }
+    thrparm->t = thread;
+    thrparm->data = data;
+
+    thread->td = spawn_thread((thread_func)func, "apr thread", temp, thrparm);
     /* Now we try to run it...*/
-    if (resume_thread((*new)->td) == B_NO_ERROR) {
+    if (resume_thread(thread->td) == B_NO_ERROR) {
         return APR_SUCCESS;
     }
     else {
@@ -142,7 +155,11 @@
 
 apr_status_t apr_thread_join(apr_status_t *retval, apr_thread_t *thd)
 {
-    if (wait_for_thread(thd->td,(void *)&retval) == B_NO_ERROR) {
+    apr_status_t *thrstat = NULL;
+
+    if (wait_for_thread(thd->td,(void *)&thrstat) == B_NO_ERROR) {
+        if (retval != NULL && thrstat != NULL)
+            *retval = *thrstat;
         return APR_SUCCESS;
     }
     else {
Index: srclib/apr/threadproc/os2/thread.c
===================================================================
RCS file: /home/cvspublic/apr/threadproc/os2/thread.c,v
retrieving revision 1.22
diff -u -r1.22 thread.c
--- srclib/apr/threadproc/os2/thread.c	2001/06/16 01:27:15	1.22
+++ srclib/apr/threadproc/os2/thread.c	2001/07/20 17:11:33
@@ -94,8 +94,18 @@
 
 static void apr_thread_begin(void *arg)
 {
-  apr_thread_t *thread = (apr_thread_t *)arg;
-  thread->rv = thread->func(thread->data);
+    apr_thread_param_t *thrparm;
+    apr_thread_t *thread = (apr_thread_t *)arg;
+
+    thrparm = (apr_thread_param_t *)apr_palloc(cont, sizeof(apr_thread_param_t));
+    if (thrparm == NULL) {
+        return APR_ENOMEM;
+    }
+
+    thrparm->t = thread;
+    thrparm->data = data;
+
+    thread->rv = thread->func(thrparm);
 }
 
 
@@ -132,12 +142,23 @@
         }
     }
     
-    if (thread->attr->attr & APR_THREADATTR_DETACHED)
+    if (thread->attr->attr & APR_THREADATTR_DETACHED) {
+        apr_thread_param_t *thrparm;
+
+        thrparm = (apr_thread_param_t *)apr_palloc(cont, sizeof(apr_thread_param_t));
+        if (thrparm == NULL) {
+            return APR_ENOMEM;
+        }
+
+        thrparm->t = thread;
+        thrparm->data = data;
+
         thread->tid = _beginthread((os2_thread_start_t)func, NULL, 
-                                   APR_THREAD_STACKSIZE, data);
-    else
+                                   APR_THREAD_STACKSIZE, thrparm);
+    } else {
         thread->tid = _beginthread(apr_thread_begin, NULL, 
                                    APR_THREAD_STACKSIZE, thread);
+    }
         
     if (thread->tid < 0) {
         return errno;
@@ -180,7 +201,8 @@
     if (rc == ERROR_INVALID_THREADID)
         rc = 0; /* Thread had already terminated */
 
-    *retval = (apr_status_t)thd->rv;
+    if (retval != NULL)
+        *retval = (apr_status_t)thd->rv;
     return APR_OS2_STATUS(rc);
 }
 
Index: srclib/apr/threadproc/unix/thread.c
===================================================================
RCS file: /home/cvspublic/apr/threadproc/unix/thread.c,v
retrieving revision 1.39
diff -u -r1.39 thread.c
--- srclib/apr/threadproc/unix/thread.c	2001/06/14 18:52:09	1.39
+++ srclib/apr/threadproc/unix/thread.c	2001/07/20 17:11:33
@@ -122,32 +122,43 @@
 {
     apr_status_t stat;
     pthread_attr_t *temp;
+    apr_thread_t *thread;
+    apr_thread_param_t *thrparm;
  
-    (*new) = (apr_thread_t *)apr_pcalloc(cont, sizeof(apr_thread_t));
+    thread = (apr_thread_t *)apr_pcalloc(cont, sizeof(apr_thread_t));
+    (*new) = thread;
 
-    if ((*new) == NULL) {
+    if (thread == NULL) {
         return APR_ENOMEM;
     }
 
-    (*new)->td = (pthread_t *)apr_pcalloc(cont, sizeof(pthread_t));
+    thread->td = (pthread_t *)apr_pcalloc(cont, sizeof(pthread_t));
 
-    if ((*new)->td == NULL) {
+    if (thread->td == NULL) {
         return APR_ENOMEM;
     }
 
-    (*new)->cntxt = cont;
-
     if (attr)
         temp = attr->attr;
     else
         temp = NULL;
-    
-    stat = apr_pool_create(&(*new)->cntxt, cont);
+
+    thread->cntxt = cont;
+
+    stat = apr_pool_create(&thread->cntxt, cont);
     if (stat != APR_SUCCESS) {
         return stat;
     }
+
+    thrparm = (apr_thread_param_t *)apr_pcalloc(cont, sizeof(apr_thread_param_t));
+    if (thrparm == NULL) {
+        return APR_ENOMEM;
+    }
 
-    if ((stat = pthread_create((*new)->td, temp, func, data)) == 0) {
+    thrparm->t = thread;
+    thrparm->data = data;
+
+    if ((stat = pthread_create(thread->td, temp, (void*)func, thrparm)) == 0) {
         return APR_SUCCESS;
     }
     else {
@@ -155,7 +166,7 @@
         stat = errno;
 #endif
         return stat;
-    } 
+    }
 }
 
 apr_os_thread_t apr_os_thread_current(void)
@@ -178,8 +189,11 @@
 apr_status_t apr_thread_join(apr_status_t *retval, apr_thread_t *thd)
 {
     apr_status_t stat;
+    apr_status_t *thrstat = NULL;
 
-    if ((stat = pthread_join(*thd->td,(void *)&retval)) == 0) {
+    if ((stat = pthread_join(*thd->td,(void **)&thrstat)) == 0) {
+        if (retval != NULL && thrstat != NULL)
+            *retval = *thrstat;
         return APR_SUCCESS;
     }
     else {
Index: srclib/apr/threadproc/win32/thread.c
===================================================================
RCS file: /home/cvspublic/apr/threadproc/win32/thread.c,v
retrieving revision 1.32
diff -u -r1.32 thread.c
--- srclib/apr/threadproc/win32/thread.c	2001/07/06 14:20:03	1.32
+++ srclib/apr/threadproc/win32/thread.c	2001/07/20 17:11:33
@@ -97,25 +97,36 @@
     apr_status_t stat;
 	unsigned temp;
     int lasterror;
+    apr_thread_t *thread;
+    apr_thread_param_t *thrparm;
  
-    (*new) = (apr_thread_t *)apr_palloc(cont, sizeof(apr_thread_t));
+    thread = (apr_thread_t *)apr_palloc(cont, sizeof(apr_thread_t));
+    (*new) = thread;
 
-    if ((*new) == NULL) {
+    if (thread == NULL) {
         return APR_ENOMEM;
     }
 
-    (*new)->cntxt = cont;
+    thread->cntxt = cont;
     
-    stat = apr_pool_create(&(*new)->cntxt, cont);
+    stat = apr_pool_create(&thread->cntxt, cont);
     if (stat != APR_SUCCESS) {
         return stat;
     }
 
+    thrparm = (apr_thread_param_t *)apr_palloc(cont, sizeof(apr_thread_param_t));
+    if (thrparm == NULL) {
+        return APR_ENOMEM;
+    }
+
+    thrparm->t = thread;
+    thrparm->data = data;
+
     /* Use 0 for Thread Stack Size, because that will default the stack to the
      * same size as the calling thread. 
      */
-    if (((*new)->td = (HANDLE *)_beginthreadex(NULL, 0, (unsigned int (APR_THREAD_FUNC
*)(void *))func,
-                                               data, 0, &temp)) == 0) {
+    if ((thread->td = (HANDLE *)_beginthreadex(NULL, 0, (unsigned int (APR_THREAD_FUNC
*)(void *))func,
+                                               thrparm, 0, &temp)) == 0) {
         lasterror = apr_get_os_error();
         return APR_EEXIST; 
         /* MSVC++ doc doesn't mention any additional error info 
@@ -124,7 +135,7 @@
     }
 
     if (attr && attr->detach) {
-        CloseHandle((*new)->td);
+        CloseHandle(thread->td);
     }
 
     return APR_SUCCESS;


Mime
View raw message