dreid 01/06/07 19:34:39
Modified: include apr_sms.h
memory/unix apr_sms.c
Log:
Some more locking, this time at the top level of sms to protect
cleanups and the child lists.
Submitted by: Sander Striker <[EMAIL PROTECTED]>
David Reid <[EMAIL PROTECTED]>
Reviewed by: David Reid <[EMAIL PROTECTED]>
Revision Changes Path
1.13 +2 -1 apr/include/apr_sms.h
Index: apr_sms.h
===================================================================
RCS file: /home/cvs/apr/include/apr_sms.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- apr_sms.h 2001/06/08 00:44:51 1.12
+++ apr_sms.h 2001/06/08 02:34:23 1.13
@@ -97,7 +97,8 @@
const char *identity; /* a string identifying the module */
apr_pool_t *pool;
-
+ apr_lock_t *sms_lock;
+
struct apr_sms_cleanup *cleanups;
void * (*malloc_fn) (apr_sms_t *mem_sys, apr_size_t size);
1.16 +63 -8 apr/memory/unix/apr_sms.c
Index: apr_sms.c
===================================================================
RCS file: /home/cvs/apr/memory/unix/apr_sms.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- apr_sms.c 2001/06/08 00:44:51 1.15
+++ apr_sms.c 2001/06/08 02:34:34 1.16
@@ -186,16 +186,28 @@
*/
if (pms) {
+ /*
+ * We only need to lock the parent as the only other function that
+ * touches the fields we're about to mess with is apr_sms_destroy
+ */
+ apr_lock_acquire(pms->sms_lock);
+
if ((mem_sys->sibling_mem_sys = pms->child_mem_sys) != NULL)
mem_sys->sibling_mem_sys->ref_mem_sys =
&mem_sys->sibling_mem_sys;
mem_sys->ref_mem_sys = &pms->child_mem_sys;
pms->child_mem_sys = mem_sys;
+
+ apr_lock_release(pms->sms_lock);
}
/* XXX - This should eventually be removed */
apr_pool_create(&mem_sys->pool, pms ? pms->pool : NULL);
+ /* Create the lock we'll use to protect cleanups and child lists */
+ apr_lock_create(&mem_sys->sms_lock, APR_MUTEX, APR_LOCKALL, NULL,
+ mem_sys->pool);
+
return APR_SUCCESS;
}
@@ -298,9 +310,13 @@
APR_DECLARE(apr_status_t) apr_sms_reset(apr_sms_t *mem_sys)
{
+ apr_status_t rv;
+
if (!mem_sys->reset_fn)
return APR_ENOTIMPL;
+ apr_lock_acquire(mem_sys->sms_lock);
+
/*
* Run the cleanups of all child memory systems _including_
* the accounting memory system.
@@ -323,16 +339,23 @@
mem_sys->accounting_mem_sys = mem_sys;
/* Let the memory system handle the actual reset */
- return mem_sys->reset_fn(mem_sys);
+ rv = mem_sys->reset_fn(mem_sys);
+
+ apr_lock_release(mem_sys->sms_lock);
+
+ return rv;
}
APR_DECLARE(apr_status_t) apr_sms_destroy(apr_sms_t *mem_sys)
{
apr_sms_t *child_mem_sys;
apr_sms_t *sibling_mem_sys;
+ apr_sms_t *pms;
struct apr_sms_cleanup *cleanup;
struct apr_sms_cleanup *next_cleanup;
+ apr_lock_acquire(mem_sys->sms_lock);
+
if (apr_sms_is_tracking(mem_sys)) {
/*
* Run the cleanups of all child memory systems _including_
@@ -415,17 +438,27 @@
}
}
+ pms = mem_sys->parent_mem_sys;
+
/* Remove the memory system from the parent memory systems child list */
+ if (pms)
+ apr_lock_acquire(pms->sms_lock);
+
if (mem_sys->sibling_mem_sys)
mem_sys->sibling_mem_sys->ref_mem_sys = mem_sys->ref_mem_sys;
if (mem_sys->ref_mem_sys)
*mem_sys->ref_mem_sys = mem_sys->sibling_mem_sys;
+ if (pms)
+ apr_lock_release(pms->sms_lock);
+
/* Call the pre-destroy if present */
if (mem_sys->pre_destroy_fn)
mem_sys->pre_destroy_fn(mem_sys);
+ apr_lock_destroy(mem_sys->sms_lock);
+
/* XXX - This should eventually be removed */
apr_pool_destroy(mem_sys->pool);
@@ -506,20 +539,27 @@
if (!cleanup_fn)
return APR_ENOTIMPL;
-
+
+ apr_lock_acquire(mem_sys->sms_lock);
+
cleanup = (struct apr_sms_cleanup *)
apr_sms_malloc(mem_sys->accounting_mem_sys,
sizeof(struct apr_sms_cleanup));
- if (!cleanup)
+ if (!cleanup){
+ apr_lock_release(mem_sys->sms_lock);
return APR_ENOMEM;
+ }
cleanup->data = data;
cleanup->type = type;
cleanup->cleanup_fn = cleanup_fn;
+
cleanup->next = mem_sys->cleanups;
mem_sys->cleanups = cleanup;
+ apr_lock_release(mem_sys->sms_lock);
+
return APR_SUCCESS;
}
@@ -531,7 +571,10 @@
{
struct apr_sms_cleanup *cleanup;
struct apr_sms_cleanup **cleanup_ref;
-
+ apr_status_t rv = APR_EINVAL;
+
+ apr_lock_acquire(mem_sys->sms_lock);
+
cleanup = mem_sys->cleanups;
cleanup_ref = &mem_sys->cleanups;
while (cleanup) {
@@ -539,18 +582,22 @@
cleanup->data == data && cleanup->cleanup_fn == cleanup_fn) {
*cleanup_ref = cleanup->next;
+ apr_lock_release(mem_sys->sms_lock);
+
mem_sys = mem_sys->accounting_mem_sys;
- if (mem_sys->free_fn != NULL)
+ if (mem_sys->free_fn)
apr_sms_free(mem_sys, cleanup);
- return APR_SUCCESS;
+ rv = APR_SUCCESS;
}
cleanup_ref = &cleanup->next;
cleanup = cleanup->next;
}
+ apr_lock_release(mem_sys->sms_lock);
+
/* The cleanup function must have been registered previously */
return APR_EINVAL;
}
@@ -562,6 +609,8 @@
struct apr_sms_cleanup **cleanup_ref;
apr_status_t rv = APR_EINVAL;
+ apr_lock_acquire(mem_sys->sms_lock);
+
cleanup = mem_sys->cleanups;
cleanup_ref = &mem_sys->cleanups;
mem_sys = mem_sys->accounting_mem_sys;
@@ -581,6 +630,8 @@
}
}
+ apr_lock_release(mem_sys->sms_lock);
+
/* The cleanup function must have been registered previously */
return rv;
}
@@ -605,8 +656,10 @@
{
struct apr_sms_cleanup *cleanup;
struct apr_sms_cleanup **cleanup_ref;
- apr_status_t rv = APR_ENOTIMPL;
-
+ apr_status_t rv = APR_EINVAL;
+
+ apr_lock_acquire(mem_sys->sms_lock);
+
cleanup = mem_sys->cleanups;
cleanup_ref = &mem_sys->cleanups;
mem_sys = mem_sys->accounting_mem_sys;
@@ -627,6 +680,8 @@
cleanup = cleanup->next;
}
}
+
+ apr_lock_release(mem_sys->sms_lock);
/* The cleanup function should have been registered previously */
return rv;