pmix2x/class: correctly handle concurrent class initialization
(back-ported from upstream commit pmix/master@ceedbd67fd) Signed-off-by: Gilles Gouaillardet <gilles@rist.or.jp>
Этот коммит содержится в:
родитель
15b6eaf2d4
Коммит
a019095b84
@ -10,6 +10,8 @@
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2014-2016 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2016 Research Organization for Information Science
|
||||
* and Technology (RIST). All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
@ -28,6 +30,7 @@
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "src/class/pmix_object.h"
|
||||
|
||||
@ -48,9 +51,12 @@ pmix_class_t pmix_object_t_class = {
|
||||
sizeof(pmix_object_t) /* size of the pmix object */
|
||||
};
|
||||
|
||||
int pmix_class_init_epoch = 1;
|
||||
|
||||
/*
|
||||
* Local variables
|
||||
*/
|
||||
static pthread_mutex_t class_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static void** classes = NULL;
|
||||
static int num_classes = 0;
|
||||
static int max_classes = 0;
|
||||
@ -81,7 +87,17 @@ void pmix_class_initialize(pmix_class_t *cls)
|
||||
/* Check to see if anyone initialized
|
||||
this class before we got a chance to */
|
||||
|
||||
if (1 == cls->cls_initialized) {
|
||||
if (pmix_class_init_epoch == cls->cls_initialized) {
|
||||
return;
|
||||
}
|
||||
pthread_mutex_lock(&class_mutex);
|
||||
|
||||
/* If another thread initializing this same class came in at
|
||||
roughly the same time, it may have gotten the lock and
|
||||
initialized. So check again. */
|
||||
|
||||
if (pmix_class_init_epoch == cls->cls_initialized) {
|
||||
pthread_mutex_unlock(&class_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -141,10 +157,12 @@ void pmix_class_initialize(pmix_class_t *cls)
|
||||
}
|
||||
*cls_destruct_array = NULL; /* end marker for the destructors */
|
||||
|
||||
cls->cls_initialized = 1;
|
||||
cls->cls_initialized = pmix_class_init_epoch;
|
||||
save_class(cls);
|
||||
|
||||
/* All done */
|
||||
|
||||
pthread_mutex_unlock(&class_mutex);
|
||||
}
|
||||
|
||||
|
||||
@ -155,6 +173,12 @@ int pmix_class_finalize(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (INT_MAX == pmix_class_init_epoch) {
|
||||
pmix_class_init_epoch = 1;
|
||||
} else {
|
||||
pmix_class_init_epoch++;
|
||||
}
|
||||
|
||||
if (NULL != classes) {
|
||||
for (i = 0; i < num_classes; ++i) {
|
||||
if (NULL != classes[i]) {
|
||||
|
@ -12,6 +12,8 @@
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2013-2016 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2016 Research Organization for Information Science
|
||||
* and Technology (RIST). All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
@ -163,6 +165,8 @@ struct pmix_class_t {
|
||||
size_t cls_sizeof; /**< size of an object instance */
|
||||
};
|
||||
|
||||
extern int pmix_class_init_epoch;
|
||||
|
||||
/**
|
||||
* For static initializations of OBJects.
|
||||
*
|
||||
@ -347,7 +351,7 @@ do { \
|
||||
#define PMIX_CONSTRUCT_INTERNAL(object, type) \
|
||||
do { \
|
||||
PMIX_SET_MAGIC_ID((object), PMIX_OBJ_MAGIC_ID); \
|
||||
if (0 == (type)->cls_initialized) { \
|
||||
if (pmix_class_init_epoch != (type)->cls_initialized) { \
|
||||
pmix_class_initialize((type)); \
|
||||
} \
|
||||
((pmix_object_t *) (object))->obj_class = (type); \
|
||||
@ -467,7 +471,7 @@ static inline pmix_object_t *pmix_obj_new(pmix_class_t * cls)
|
||||
assert(cls->cls_sizeof >= sizeof(pmix_object_t));
|
||||
|
||||
object = (pmix_object_t *) malloc(cls->cls_sizeof);
|
||||
if (0 == cls->cls_initialized) {
|
||||
if (pmix_class_init_epoch != cls->cls_initialized) {
|
||||
pmix_class_initialize(cls);
|
||||
}
|
||||
if (NULL != object) {
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user