Small fixes for the MCA variable interface.
- Make a copy of enumerator data for default enumerators. This will allow the caller to free their data once the enumerator has been created. This is a change from just referencing the values array. - Make mca_base_pvar_notify check if the pvar is valid before calling the notify callback. This fixes a segmentation fault when destroying handles after MPI_Finalize(). cmr=v1.7.4:ticket=trac:3861 This commit was SVN r29512. The following Trac tickets were found above: Ticket 3861 --> https://svn.open-mpi.org/trac/ompi/ticket/3861
Этот коммит содержится в:
родитель
628a109a74
Коммит
f7428fb6a9
@ -375,6 +375,10 @@ int mca_base_pvar_mark_invalid (int index)
|
||||
|
||||
int mca_base_pvar_notify (mca_base_pvar_handle_t *handle, mca_base_pvar_event_t event, int *count)
|
||||
{
|
||||
if (mca_base_pvar_is_invalid (handle->pvar)) {
|
||||
return OPAL_ERR_NOT_BOUND;
|
||||
}
|
||||
|
||||
return handle->pvar->notify (handle->pvar, event, handle->obj_handle, count);
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,7 @@ mca_base_var_enum_t mca_base_var_enum_bool = {
|
||||
};
|
||||
|
||||
|
||||
int mca_base_var_enum_create (char *name, mca_base_var_enum_value_t *values, mca_base_var_enum_t **enumerator)
|
||||
int mca_base_var_enum_create (const char *name, const mca_base_var_enum_value_t *values, mca_base_var_enum_t **enumerator)
|
||||
{
|
||||
mca_base_var_enum_t *new_enum;
|
||||
int i;
|
||||
@ -118,11 +118,21 @@ int mca_base_var_enum_create (char *name, mca_base_var_enum_value_t *values, mca
|
||||
return OPAL_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
|
||||
new_enum->enum_values = values;
|
||||
|
||||
for (i = 0 ; new_enum->enum_values[i].string ; ++i);
|
||||
for (i = 0 ; values[i].string ; ++i);
|
||||
new_enum->enum_value_count = i;
|
||||
|
||||
/* make a copy of the values */
|
||||
new_enum->enum_values = calloc (new_enum->enum_value_count + 1, sizeof (*new_enum->enum_values));
|
||||
if (NULL == new_enum->enum_values) {
|
||||
OBJ_DESTRUCT(new_enum);
|
||||
return OPAL_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
|
||||
for (i = 0 ; i < new_enum->enum_value_count ; ++i) {
|
||||
new_enum->enum_values[i].value = values[i].value;
|
||||
new_enum->enum_values[i].string = strdup (values[i].string);
|
||||
}
|
||||
|
||||
*enumerator = new_enum;
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
@ -141,7 +151,7 @@ static int enum_dump (mca_base_var_enum_t *self, char **out)
|
||||
}
|
||||
|
||||
tmp = NULL;
|
||||
for (i = 0; self->enum_values[i].string ; ++i) {
|
||||
for (i = 0; i < self->enum_value_count && self->enum_values[i].string ; ++i) {
|
||||
ret = asprintf (out, "%s%s%d:\"%s\"", tmp ? tmp : "", tmp ? ", " : "", self->enum_values[i].value,
|
||||
self->enum_values[i].string);
|
||||
if (tmp) free (tmp);
|
||||
@ -256,4 +266,12 @@ static void mca_base_var_enum_destructor (mca_base_var_enum_t *enumerator)
|
||||
if (enumerator->enum_name) {
|
||||
free (enumerator->enum_name);
|
||||
}
|
||||
|
||||
/* release the copy of the values */
|
||||
if (enumerator->enum_values) {
|
||||
for (int i = 0 ; i < enumerator->enum_value_count ; ++i) {
|
||||
free ((void *) enumerator->enum_values[i].string);
|
||||
}
|
||||
free (enumerator->enum_values);
|
||||
}
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ typedef int (*mca_base_var_enum_sfv_fn_t)(mca_base_var_enum_t *self, const int v
|
||||
* integer value is used for the MCA variable.
|
||||
*/
|
||||
struct mca_base_var_enum_value_t {
|
||||
const int value;
|
||||
int value;
|
||||
const char *string;
|
||||
};
|
||||
|
||||
@ -116,13 +116,15 @@ struct mca_base_var_enum_t {
|
||||
valid value return OPAL_ERR_VALUE_OUT_OF_BOUNDS */
|
||||
mca_base_var_enum_vfs_fn_t value_from_string;
|
||||
/** Given an integer return the corresponding string value. If the integer does not
|
||||
mathach a valid value return OPAL_ERR_VALUE_OUT_OF_BOUNDS */
|
||||
match a valid value return OPAL_ERR_VALUE_OUT_OF_BOUNDS */
|
||||
mca_base_var_enum_sfv_fn_t string_from_value;
|
||||
/** Dump a textual representation of the enumerator. The caller is responsible for
|
||||
freeing the string */
|
||||
mca_base_var_enum_dump_fn_t dump;
|
||||
|
||||
int enum_value_count;
|
||||
/** Copy of the enumerators values (used by the default functions). This array and
|
||||
and the strings it contains are freed by the destructor if not NULL. */
|
||||
mca_base_var_enum_value_t *enum_values;
|
||||
};
|
||||
|
||||
@ -152,7 +154,7 @@ OPAL_DECLSPEC OBJ_CLASS_DECLARATION(mca_base_var_enum_t);
|
||||
* been used in a pvar registration, because variables that use the
|
||||
* enumerator will OBJ_RETAIN it.
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_enum_create (char *name, mca_base_var_enum_value_t values[],
|
||||
OPAL_DECLSPEC int mca_base_var_enum_create (const char *name, const mca_base_var_enum_value_t values[],
|
||||
mca_base_var_enum_t **enumerator);
|
||||
|
||||
#endif /* !defined(MCA_BASE_VAR_ENUM_H) */
|
||||
|
Загрузка…
Ссылка в новой задаче
Block a user