From ad62411a15d3b64d8c54366d89e509919c5c66ff Mon Sep 17 00:00:00 2001 From: Brian Barrett Date: Wed, 28 Sep 2005 16:40:19 +0000 Subject: [PATCH] * fix deadlock in memory code that occurs if OBJ_NEW calls realloc to expand it's class list array by pre-allocating the callback item before we obtain the lock (we free it if we ended up not needing it) This commit was SVN r7533. --- opal/memory/memory.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/opal/memory/memory.c b/opal/memory/memory.c index 89b92bc5fa..677b6833a5 100644 --- a/opal/memory/memory.c +++ b/opal/memory/memory.c @@ -154,7 +154,7 @@ int opal_mem_free_register_handler(opal_mem_free_unpin_fn_t *func, void *cbdata) { opal_list_item_t *item; - callback_list_item_t *cbitem; + callback_list_item_t *cbitem, *new_cbitem; int ret = OMPI_SUCCESS; if (!have_free_support) return OMPI_ERR_NOT_SUPPORTED; @@ -165,6 +165,15 @@ opal_mem_free_register_handler(opal_mem_free_unpin_fn_t *func, void *cbdata) run_callbacks = true; opal_atomic_mb(); + /* pre-allocate a callback item on the assumption it won't be + found. We can't call OBJ_NEW inside the lock because it might + call realloc */ + new_cbitem = OBJ_NEW(callback_list_item_t); + if (NULL == new_cbitem) { + ret = OMPI_ERR_OUT_OF_RESOURCE; + goto done; + } + opal_atomic_lock(&callback_lock); /* make sure the callback isn't already in the list */ @@ -179,18 +188,16 @@ opal_mem_free_register_handler(opal_mem_free_unpin_fn_t *func, void *cbdata) } } - cbitem = OBJ_NEW(callback_list_item_t); - if (NULL == cbitem) { - ret = OMPI_ERR_OUT_OF_RESOURCE; - goto done; - } + new_cbitem->cbfunc = func; + new_cbitem->cbdata = cbdata; - cbitem->cbfunc = func; - cbitem->cbdata = cbdata; - - opal_list_append(&callback_list, (opal_list_item_t*) cbitem); + opal_list_append(&callback_list, (opal_list_item_t*) new_cbitem); done: + if (OMPI_EXISTS == rc && NULL != new_cbitem) { + OBJ_RELEASE(new_cbitem); + } + opal_atomic_unlock(&callback_lock); return ret; }