From db3a51f8c8a8ce87bb81a62e3be4f58b5603233f Mon Sep 17 00:00:00 2001 From: Nathan Hjelm Date: Thu, 9 Apr 2015 09:45:02 -0600 Subject: [PATCH] opal/class: enable use of opal classes after opal_class_finalize This commit enables the use of opal classes after a call to opal_class_finalize. This is needed to support re-initializing opal after calling opal_finalize_util (). This is needed to support the following without leaking: MPI_T_init_thread (); MPI_T_finalize (); MPI_Init (); MPI_Finalize (); Before this commit the above code would crash in MPI_Init because the constructor array for some class was freed by opal_class_finalize (). The fix is to turn the cls_initialized member of opal_class_t into an init epoch identifier and compare it against opal_class_init_epoch instead of 1. On each call to opal_class_finalize the opal_class_init_epoch counter is incremented forcing re-initialization of classes after finalize. Signed-off-by: Nathan Hjelm --- opal/class/opal_object.c | 17 ++++++++++++++--- opal/class/opal_object.h | 11 ++++++++--- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/opal/class/opal_object.c b/opal/class/opal_object.c index 24a07131906..2d946f0fca6 100644 --- a/opal/class/opal_object.c +++ b/opal/class/opal_object.c @@ -1,3 +1,4 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ /* * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana * University Research and Technology @@ -9,6 +10,8 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. + * Copyright (c) 2015 Los Alamos National Security, LLC. All rights + * reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -47,6 +50,8 @@ opal_class_t opal_object_t_class = { sizeof(opal_object_t) /* size of the opal object */ }; +int opal_class_init_epoch = 1; + /* * Local variables */ @@ -81,7 +86,7 @@ void opal_class_initialize(opal_class_t *cls) /* Check to see if any other thread got in here and initialized this class before we got a chance to */ - if (1 == cls->cls_initialized) { + if (opal_class_init_epoch == cls->cls_initialized) { return; } opal_atomic_lock(&class_lock); @@ -90,7 +95,7 @@ void opal_class_initialize(opal_class_t *cls) roughly the same time, it may have gotten the lock and initialized. So check again. */ - if (1 == cls->cls_initialized) { + if (opal_class_init_epoch == cls->cls_initialized) { opal_atomic_unlock(&class_lock); return; } @@ -151,7 +156,7 @@ void opal_class_initialize(opal_class_t *cls) } *cls_destruct_array = NULL; /* end marker for the destructors */ - cls->cls_initialized = 1; + cls->cls_initialized = opal_class_init_epoch; save_class(cls); /* All done */ @@ -167,6 +172,12 @@ int opal_class_finalize(void) { int i; + if (INT_MAX == opal_class_init_epoch) { + opal_class_init_epoch = 1; + } else { + opal_class_init_epoch++; + } + if (NULL != classes) { for (i = 0; i < num_classes; ++i) { if (NULL != classes[i]) { diff --git a/opal/class/opal_object.h b/opal/class/opal_object.h index 79470d586eb..6a375855407 100644 --- a/opal/class/opal_object.h +++ b/opal/class/opal_object.h @@ -1,3 +1,4 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ /* * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana * University Research and Technology @@ -10,6 +11,8 @@ * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2007-2014 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2015 Los Alamos National Security, LLC. All rights + * reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -161,6 +164,8 @@ struct opal_class_t { size_t cls_sizeof; /**< size of an object instance */ }; +extern int opal_class_init_epoch; + /** * For static initializations of OBJects. * @@ -344,8 +349,8 @@ do { \ #define OBJ_CONSTRUCT_INTERNAL(object, type) \ do { \ - OBJ_SET_MAGIC_ID((object), OPAL_OBJ_MAGIC_ID); \ - if (0 == (type)->cls_initialized) { \ + OBJ_SET_MAGIC_ID((object), OPAL_OBJ_MAGIC_ID); \ + if (opal_class_init_epoch != (type)->cls_initialized) { \ opal_class_initialize((type)); \ } \ ((opal_object_t *) (object))->obj_class = (type); \ @@ -469,7 +474,7 @@ static inline opal_object_t *opal_obj_new(opal_class_t * cls) #else object = (opal_object_t *) malloc(cls->cls_sizeof); #endif - if (0 == cls->cls_initialized) { + if (opal_class_init_epoch != cls->cls_initialized) { opal_class_initialize(cls); } if (NULL != object) {