1
1

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
Этот коммит содержится в:
Nathan Hjelm 2013-10-24 19:27:06 +00:00
родитель 628a109a74
Коммит f7428fb6a9
3 изменённых файлов: 32 добавлений и 8 удалений

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

@ -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) */