Skip to content

Commit a019095

Browse files
committed
pmix2x/class: correctly handle concurrent class initialization
(back-ported from upstream commit openpmix/openpmix@ceedbd6) Signed-off-by: Gilles Gouaillardet <[email protected]>
1 parent 15b6eaf commit a019095

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

opal/mca/pmix/pmix2x/pmix/src/class/pmix_object.c

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
* Copyright (c) 2004-2005 The Regents of the University of California.
1111
* All rights reserved.
1212
* Copyright (c) 2014-2016 Intel, Inc. All rights reserved.
13+
* Copyright (c) 2016 Research Organization for Information Science
14+
* and Technology (RIST). All rights reserved.
1315
* $COPYRIGHT$
1416
*
1517
* Additional copyrights may follow
@@ -28,6 +30,7 @@
2830

2931

3032
#include <stdio.h>
33+
#include <pthread.h>
3134

3235
#include "src/class/pmix_object.h"
3336

@@ -48,9 +51,12 @@ pmix_class_t pmix_object_t_class = {
4851
sizeof(pmix_object_t) /* size of the pmix object */
4952
};
5053

54+
int pmix_class_init_epoch = 1;
55+
5156
/*
5257
* Local variables
5358
*/
59+
static pthread_mutex_t class_mutex = PTHREAD_MUTEX_INITIALIZER;
5460
static void** classes = NULL;
5561
static int num_classes = 0;
5662
static int max_classes = 0;
@@ -81,7 +87,17 @@ void pmix_class_initialize(pmix_class_t *cls)
8187
/* Check to see if anyone initialized
8288
this class before we got a chance to */
8389

84-
if (1 == cls->cls_initialized) {
90+
if (pmix_class_init_epoch == cls->cls_initialized) {
91+
return;
92+
}
93+
pthread_mutex_lock(&class_mutex);
94+
95+
/* If another thread initializing this same class came in at
96+
roughly the same time, it may have gotten the lock and
97+
initialized. So check again. */
98+
99+
if (pmix_class_init_epoch == cls->cls_initialized) {
100+
pthread_mutex_unlock(&class_mutex);
85101
return;
86102
}
87103

@@ -141,10 +157,12 @@ void pmix_class_initialize(pmix_class_t *cls)
141157
}
142158
*cls_destruct_array = NULL; /* end marker for the destructors */
143159

144-
cls->cls_initialized = 1;
160+
cls->cls_initialized = pmix_class_init_epoch;
145161
save_class(cls);
146162

147163
/* All done */
164+
165+
pthread_mutex_unlock(&class_mutex);
148166
}
149167

150168

@@ -155,6 +173,12 @@ int pmix_class_finalize(void)
155173
{
156174
int i;
157175

176+
if (INT_MAX == pmix_class_init_epoch) {
177+
pmix_class_init_epoch = 1;
178+
} else {
179+
pmix_class_init_epoch++;
180+
}
181+
158182
if (NULL != classes) {
159183
for (i = 0; i < num_classes; ++i) {
160184
if (NULL != classes[i]) {

opal/mca/pmix/pmix2x/pmix/src/class/pmix_object.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
* All rights reserved.
1313
* Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
1414
* Copyright (c) 2013-2016 Intel, Inc. All rights reserved.
15+
* Copyright (c) 2016 Research Organization for Information Science
16+
* and Technology (RIST). All rights reserved.
1517
* $COPYRIGHT$
1618
*
1719
* Additional copyrights may follow
@@ -163,6 +165,8 @@ struct pmix_class_t {
163165
size_t cls_sizeof; /**< size of an object instance */
164166
};
165167

168+
extern int pmix_class_init_epoch;
169+
166170
/**
167171
* For static initializations of OBJects.
168172
*
@@ -347,7 +351,7 @@ do { \
347351
#define PMIX_CONSTRUCT_INTERNAL(object, type) \
348352
do { \
349353
PMIX_SET_MAGIC_ID((object), PMIX_OBJ_MAGIC_ID); \
350-
if (0 == (type)->cls_initialized) { \
354+
if (pmix_class_init_epoch != (type)->cls_initialized) { \
351355
pmix_class_initialize((type)); \
352356
} \
353357
((pmix_object_t *) (object))->obj_class = (type); \
@@ -467,7 +471,7 @@ static inline pmix_object_t *pmix_obj_new(pmix_class_t * cls)
467471
assert(cls->cls_sizeof >= sizeof(pmix_object_t));
468472

469473
object = (pmix_object_t *) malloc(cls->cls_sizeof);
470-
if (0 == cls->cls_initialized) {
474+
if (pmix_class_init_epoch != cls->cls_initialized) {
471475
pmix_class_initialize(cls);
472476
}
473477
if (NULL != object) {

0 commit comments

Comments
 (0)