1
1

Fix a confusing situation, and eliminate a potential memory leak.

MPI-1 does not say whether an errorhandler obtained via
MPI_ERRHANDLER_GET (or MPI_COMM_GET_ERRHANDLER or ...) needs to be
ERRHANDLER_FREE'd or not.  I don't think it does, but some users will
probably disagree.  So per the lengthy comment in
src/mpi/c/comm_get_errhandler.c, we increment the refcount whenever
GET is invoked.

This can lead to a memory leak in FINALIZE if the user GET's some
intrinsic error handlers -- we'll increment the refcount, which means
that it will never get to 0 during FINALIZE like it should.  So add a
little extra logic to ensure that they are OMPI_OBJ_DESTROY'ed during
FINALIZE like they should be.

This commit was SVN r3661.
Этот коммит содержится в:
Jeff Squyres 2004-11-26 22:11:22 +00:00
родитель 102a18ff6f
Коммит 5cbf975955

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

@ -44,6 +44,16 @@ ompi_errhandler_t ompi_mpi_errhandler_null;
ompi_errhandler_t ompi_mpi_errors_are_fatal;
ompi_errhandler_t ompi_mpi_errors_return;
/*
* Local state to know when the three intrinsics have been freed; see
* the errhandler destructor for more info.
*/
static bool null_freed = false;
static bool fatal_freed = false;
static bool return_freed = false;
/*
* Initialize OMPI errhandler infrastructure
*/
@ -105,13 +115,34 @@ int ompi_errhandler_init(void)
*/
int ompi_errhandler_finalize(void)
{
/* Remove errhandler F2C table */
OBJ_RELEASE(ompi_errhandler_f_to_c_table);
/* All done */
/* Forcibly release the intrinsic error handlers because in order
to be safe, we increase the refcount on error handlers in
MPI_*_GET_ERRHANDLER and MPI_ERRHANDLER_GET. If these handles
are never ERRHANDLER_FREEd, then the refcount will not be
decremented and they will not naturally get to 0 during
FINALIZE. Hence, we RELEASE on the intrinsics until they are
freed. */
return OMPI_SUCCESS;
while (!null_freed) {
OBJ_DESTRUCT(&ompi_mpi_errhandler_null);
}
while (!fatal_freed) {
OBJ_DESTRUCT(&ompi_mpi_errors_are_fatal);
}
while (!return_freed) {
OBJ_DESTRUCT(&ompi_mpi_errors_return);
}
/* JMS Add stuff here checking for unreleased errorhandlers,
similar to communicators, info handles, etc. */
/* Remove errhandler F2C table */
OBJ_RELEASE(ompi_errhandler_f_to_c_table);
/* All done */
return OMPI_SUCCESS;
}
@ -206,6 +237,15 @@ static void ompi_errhandler_destruct(ompi_errhandler_t *errhandler)
ompi_pointer_array_set_item(ompi_errhandler_f_to_c_table,
errhandler->eh_f_to_c_index, NULL);
}
/* Reset the static state if we're releasing one of the
intrinsics */
if (&ompi_mpi_errhandler_null == errhandler) {
null_freed = true;
} else if (&ompi_mpi_errors_are_fatal == errhandler) {
fatal_freed = true;
} else if (&ompi_mpi_errors_return == errhandler) {
return_freed = true;
}
}