You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by dr...@apache.org on 2001/12/23 14:10:23 UTC
cvs commit: apr/locks/beos thread_cond.c
dreid 01/12/23 05:10:23
Modified: include/arch/beos thread_cond.h
locks/beos thread_cond.c
Log:
Change the conditional code for BeOS,
- move to using the ring macro's to allow us to keep lists of active
and free waiters rather than creating them every time
(suggested by Aaron)
- fix a bug in the call to acquire_sem_etc
The cleanup code still needs fixing.
Revision Changes Path
1.3 +8 -6 apr/include/arch/beos/thread_cond.h
Index: thread_cond.h
===================================================================
RCS file: /home/cvs/apr/include/arch/beos/thread_cond.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- thread_cond.h 2001/12/11 16:54:38 1.2
+++ thread_cond.h 2001/12/23 13:10:23 1.3
@@ -62,20 +62,22 @@
#include "apr_general.h"
#include "apr_lib.h"
#include "apr_portable.h"
+#include "apr_ring.h"
-struct waiter {
- apr_pool_t *pool;
+struct waiter_t {
+ APR_RING_ENTRY(waiter_t) link;
sem_id sem;
- struct waiter *next;
};
-
+
struct apr_thread_cond_t {
apr_pool_t *pool;
sem_id lock;
apr_thread_mutex_t *condlock;
thread_id owner;
- struct waiter *list;
- struct waiter *tail;
+ /* active list */
+ APR_RING_HEAD(active_list, waiter_t) alist;
+ /* free list */
+ APR_RING_HEAD(free_list, waiter_t) flist;
};
#endif /* THREAD_COND_H */
1.5 +62 -45 apr/locks/beos/thread_cond.c
Index: thread_cond.c
===================================================================
RCS file: /home/cvs/apr/locks/beos/thread_cond.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- thread_cond.c 2001/12/11 16:54:38 1.4
+++ thread_cond.c 2001/12/23 13:10:23 1.5
@@ -52,10 +52,6 @@
* <http://www.apache.org/>.
*/
-/*Read/Write locking implementation based on the MultiLock code from
- * Stephen Beaulieu <hi...@be.com>
- */
-
#include "beos/thread_mutex.h"
#include "beos/thread_cond.h"
#include "apr_strings.h"
@@ -67,22 +63,38 @@
apr_thread_cond_t *cond = (apr_thread_cond_t *)data;
acquire_sem(cond->lock);
- /* Go through waiters list and delete the sem's so we don't leak. */
- while (cond->list) {
- w = cond->list;
- cond->list = w->next;
+/*
+ APR_RING_FOREACH(w, &cond->alist, waiter_t, link) {
delete_sem(w->sem);
}
+*/
delete_sem(cond->lock);
return APR_SUCCESS;
}
+
+static struct waiter_t *make_waiter(apr_pool_t *pool)
+{
+ struct waiter_t *w = (struct waiter_t*)
+ apr_palloc(pool, sizeof(struct waiter_t));
+ if (w == NULL)
+ return NULL;
+
+ w->sem = create_sem(0, "apr conditional waiter");
+ if (w->sem < 0)
+ return NULL;
+
+ APR_RING_ELEM_INIT(w, link);
+ return w;
+}
+
APR_DECLARE(apr_status_t) apr_thread_cond_create(apr_thread_cond_t **cond,
apr_pool_t *pool)
{
apr_thread_cond_t *new_cond;
sem_id rv;
+ int i;
new_cond = (apr_thread_cond_t *)apr_palloc(pool, sizeof(apr_thread_cond_t));
@@ -94,8 +106,14 @@
new_cond->lock = rv;
new_cond->pool = pool;
- new_cond->list = NULL;
-
+ APR_RING_INIT(&new_cond->alist, waiter_t, link);
+ APR_RING_INIT(&new_cond->flist, waiter_t, link);
+
+ for (i=0;i < 10 ;i++) {
+ struct waiter_t *nw = make_waiter(pool);
+ APR_RING_INSERT_TAIL(&new_cond->flist, nw, waiter_t, link);
+ }
+
apr_pool_cleanup_register(new_cond->pool,
(void *)new_cond, thread_cond_cleanup,
apr_pool_cleanup_null);
@@ -104,52 +122,49 @@
return APR_SUCCESS;
}
+
static apr_status_t do_wait(apr_thread_cond_t *cond, apr_thread_mutex_t *mutex,
int timeout)
{
- struct waiter *wait = apr_palloc(cond->pool, sizeof(struct waiter));
+ struct waiter_t *wait;
thread_id cth = find_thread(NULL);
apr_status_t rv;
-
- if (!wait)
- return APR_ENOMEM;
-
- if (cond->owner > 0 && cth != cond->owner) {
+ int flags = B_RELATIVE_TIMEOUT;
+
+ /* We must be the owner of the mutex or we can't do this... */
+ if (mutex->owner != cth) {
/* What should we return??? */
return APR_EINVAL;
}
-
- wait->sem = create_sem(0, "apr conditional waiter");
- wait->next = NULL;
- wait->pool = cond->pool;
- cond->condlock = mutex;
-
- acquire_sem(cond->lock);
- cond->owner = -1;
- if (!cond->list)
- cond->list = wait;
+ acquire_sem(cond->lock);
+ wait = APR_RING_FIRST(&cond->flist);
+ if (wait)
+ APR_RING_REMOVE(wait, link);
else
- cond->tail->next = wait;
- cond->tail = wait;
-
+ wait = make_waiter(cond->pool);
+ APR_RING_INSERT_TAIL(&cond->alist, wait, waiter_t, link);
+ cond->condlock = mutex;
release_sem(cond->lock);
-
+
apr_thread_mutex_unlock(cond->condlock);
+
+ if (timeout == 0)
+ flags = 0;
+
+ rv = acquire_sem_etc(wait->sem, 1, flags, timeout);
- rv = acquire_sem_etc(wait->sem, 1, B_RELATIVE_TIMEOUT, timeout);
+ apr_thread_mutex_lock(cond->condlock);
+
if (rv != B_OK)
if (rv == B_TIMED_OUT)
return APR_TIMEUP;
- return rv;
-
- apr_thread_mutex_lock(cond->condlock);
+ return rv;
acquire_sem(cond->lock);
- cond->owner = find_thread(NULL);
+ APR_RING_REMOVE(wait, link);
+ APR_RING_INSERT_TAIL(&cond->flist, wait, waiter_t, link);
release_sem(cond->lock);
-
- delete_sem(wait->sem);
return APR_SUCCESS;
}
@@ -169,13 +184,14 @@
APR_DECLARE(apr_status_t) apr_thread_cond_signal(apr_thread_cond_t *cond)
{
- struct waiter *wake;
+ struct waiter_t *wake;
acquire_sem(cond->lock);
- if (cond->list) {
- wake = cond->list;
- cond->list = wake->next;
+ if (!APR_RING_EMPTY(&cond->alist, waiter_t, link)) {
+ wake = APR_RING_FIRST(&cond->alist);
+ APR_RING_REMOVE(wake, link);
release_sem(wake->sem);
+ APR_RING_INSERT_TAIL(&cond->flist, wake, waiter_t, link);
}
release_sem(cond->lock);
@@ -184,13 +200,14 @@
APR_DECLARE(apr_status_t) apr_thread_cond_broadcast(apr_thread_cond_t *cond)
{
- struct waiter *wake;
+ struct waiter_t *wake;
acquire_sem(cond->lock);
- while (cond->list) {
- wake = cond->list;
- cond->list = wake->next;
+ while (! APR_RING_EMPTY(&cond->alist, waiter_t, link)) {
+ wake = APR_RING_FIRST(&cond->alist);
+ APR_RING_REMOVE(wake, link);
release_sem(wake->sem);
+ APR_RING_INSERT_TAIL(&cond->flist, wake, waiter_t, link);
}
release_sem(cond->lock);