int MPIDI_CH3I_Progress_finalize(void) { int mpi_errno; MPIDI_CH3I_Connection_t *conn = NULL; MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPIDI_CH3I_PROGRESS_FINALIZE); MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPIDI_CH3I_PROGRESS_FINALIZE); /* Shut down the listener */ mpi_errno = MPIDU_CH3I_ShutdownListener(); if (mpi_errno != MPI_SUCCESS) { MPIR_ERR_POP(mpi_errno); } /* Close open connections */ MPIDI_CH3I_Sock_close_open_sockets(MPIDI_CH3I_sock_set,(void**) &conn); while (conn != NULL) { conn->state = CONN_STATE_CLOSING; mpi_errno = MPIDI_CH3_Sockconn_handle_close_event(conn); if (mpi_errno) { MPIR_ERR_POP(mpi_errno); } MPIDI_CH3I_Sock_close_open_sockets(MPIDI_CH3I_sock_set,(void**) &conn); } /* * MT: in a multi-threaded environment, finalize() should signal any * thread(s) blocking on MPIDI_CH3I_Sock_wait() and wait for * those * threads to complete before destroying the progress engine * data structures. */ MPIDI_CH3I_Sock_destroy_set(MPIDI_CH3I_sock_set); MPIDI_CH3I_Sock_finalize(); MPIR_THREAD_CHECK_BEGIN; /* FIXME should be appropriately abstracted somehow */ # if defined(MPICH_IS_THREADED) && (MPICH_THREAD_GRANULARITY == MPICH_THREAD_GRANULARITY__GLOBAL) { int err; MPID_Thread_cond_destroy(&MPIDI_CH3I_progress_completion_cond, &err); MPIR_Assert(err == 0); } # endif MPIR_THREAD_CHECK_END; fn_exit: MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPIDI_CH3I_PROGRESS_FINALIZE); return mpi_errno; fn_fail: goto fn_exit; }
int MPIR_Finalize_async_thread(void) { int mpi_errno = MPI_SUCCESS; #if MPICH_THREAD_LEVEL == MPI_THREAD_MULTIPLE MPIR_Request *request_ptr = NULL; MPI_Request request; MPI_Status status; MPIR_FUNC_TERSE_STATE_DECL(MPID_STATE_MPIR_FINALIZE_ASYNC_THREAD); MPIR_FUNC_TERSE_ENTER(MPID_STATE_MPIR_FINALIZE_ASYNC_THREAD); mpi_errno = MPID_Isend(NULL, 0, MPI_CHAR, 0, WAKE_TAG, progress_comm_ptr, MPIR_CONTEXT_INTRA_PT2PT, &request_ptr); MPIR_Assert(!mpi_errno); request = request_ptr->handle; mpi_errno = MPIR_Wait_impl(&request, &status); MPIR_Assert(!mpi_errno); /* XXX DJG why is this unlock/lock necessary? Should we just YIELD here or later? */ MPID_THREAD_CS_EXIT(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); MPID_Thread_mutex_lock(&progress_mutex, &mpi_errno); MPIR_Assert(!mpi_errno); while (!progress_thread_done) { MPID_Thread_cond_wait(&progress_cond, &progress_mutex, &mpi_errno); MPIR_Assert(!mpi_errno); } MPID_Thread_mutex_unlock(&progress_mutex, &mpi_errno); MPIR_Assert(!mpi_errno); mpi_errno = MPIR_Comm_free_impl(progress_comm_ptr); MPIR_Assert(!mpi_errno); MPID_THREAD_CS_ENTER(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); MPID_Thread_cond_destroy(&progress_cond, &mpi_errno); MPIR_Assert(!mpi_errno); MPID_Thread_mutex_destroy(&progress_mutex, &mpi_errno); MPIR_Assert(!mpi_errno); MPIR_FUNC_TERSE_EXIT(MPID_STATE_MPIR_FINALIZE_ASYNC_THREAD); #endif /* MPICH_THREAD_LEVEL == MPI_THREAD_MULTIPLE */ return mpi_errno; }
int MPIDI_CH3I_Progress_finalize(void) { int mpi_errno; MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3I_PROGRESS_FINALIZE); MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3I_PROGRESS_FINALIZE); /* Shut down the listener */ mpi_errno = MPIDU_CH3I_ShutdownListener(); if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_POP(mpi_errno); } /* FIXME: Cleanly shutdown other socks and free connection structures. (close protocol?) */ /* * MT: in a multi-threaded environment, finalize() should signal any * thread(s) blocking on MPIDU_Sock_wait() and wait for * those * threads to complete before destroying the progress engine * data structures. */ MPIDU_Sock_destroy_set(MPIDI_CH3I_sock_set); MPIDU_Sock_finalize(); MPIU_THREAD_CHECK_BEGIN /* FIXME should be appropriately abstracted somehow */ # if defined(MPICH_IS_THREADED) && (MPIU_THREAD_GRANULARITY == MPIU_THREAD_GRANULARITY_GLOBAL) { int err; MPID_Thread_cond_destroy(&MPIDI_CH3I_progress_completion_cond, &err); MPIU_Assert(err == 0); } # endif MPIU_THREAD_CHECK_END fn_exit: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3I_PROGRESS_FINALIZE); return mpi_errno; fn_fail: goto fn_exit; }