1
1

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 <hjelmn@lanl.gov>
Этот коммит содержится в:
Nathan Hjelm 2015-04-09 09:45:02 -06:00
родитель acc2c7937c
Коммит db3a51f8c8
2 изменённых файлов: 22 добавлений и 6 удалений

Просмотреть файл

@ -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]) {

Просмотреть файл

@ -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) {