recursive subroutine ESMF_CompDestruct(compp, interCompComm, fullShutdown, &
timeout, timeoutFlag, rc)
!
! !ARGUMENTS:
type(ESMF_CompClass), pointer :: compp
logical, intent(in), optional :: interCompComm
logical, intent(in), optional :: fullShutdown
integer, intent(in), optional :: timeout
logical, intent(out), optional :: timeoutFlag
integer, intent(out), optional :: rc
!
! !DESCRIPTION:
! Destroys an {\tt ESMF\_Component}, releasing the resources associated
! with the object.
!
! The arguments are:
! \begin{description}
! \item[compp]
! Component internal structure to be freed.
! \item[{[interCompComm]}]
! Participate in inter-component wrap up communication. May require that
! this call be not collective! Default is {\tt .true.}.
! \item[{[fullShutdown]}]
! Fully shut down everything, including the component's VM. Depending on
! the MPI implementation this may make this call collective.
! Default is {\tt .true.}.
! \item[{[timeout]}]
! The maximum period in seconds that this call will wait for any
! communication with the actual component, before returning with a timeout
! condition. The default is 3600, i.e. 1 hour.
! \item[{[timeoutFlag]}]
! Returns {\tt .true.} if the timeout was reached, {\tt .false.} otherwise.
! If {\tt timeoutFlag} was not provided a timeout condition will lead to
! an {\tt rc \\= ESMF\_SUCCESS}, otherwise the return value of
! {\tt timeoutFlag} is the indicator whether timeout was reached or not.
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
!EOPI
!------------------------------------------------------------------------------
integer :: localrc ! local return code
type(ESMF_Status) :: baseStatus
integer :: timeoutArg
logical :: interCompCommArg
logical :: fullShutdownArg
! Assume not implemented until success
if (present(rc)) rc = ESMF_RC_NOT_IMPL
localrc = ESMF_RC_NOT_IMPL
! Test incoming compp object
if (.not.associated(compp)) then
call ESMF_LogSetError(ESMF_RC_OBJ_BAD, &
msg="Not a valid pointer to ESMF Component object", &
ESMF_CONTEXT, rcToReturn=rc)
return
endif
! Set defaults
if (present(timeoutFlag)) then
timeoutFlag = .false. ! initialize in any case
endif
interCompCommArg = .true.
if (present(interCompComm)) interCompCommArg = interCompComm
fullShutdownArg = .true.
if (present(fullShutdown)) fullShutdownArg = fullShutdown
! Now deal with garbage collection
call ESMF_BaseGetStatus(compp%base, baseStatus, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
if (baseStatus == ESMF_STATUS_READY) then
! dual component must terminate the service loop of the actual component
if (interCompCommArg .and. &
(compp%compTunnel%this /= ESMF_NULL_POINTER)) then
! this is indeed a dual component with an open component tunnel
timeoutArg = ESMF_DEFAULT_TIMEOUT ! default 1h timeout !!!!!!!!!!!
if (present(timeout)) timeoutArg = timeout
call ESMF_CompExecute(compp, method=ESMF_METHOD_NONE, &
timeout=timeoutArg, rc=localrc) ! disregard userRc - invalid here!
if (present(timeoutFlag)) then
timeoutFlag = .false. ! initialize
if ((localrc==ESMF_RC_TIMEOUT).or.(localrc==ESMC_RC_TIMEOUT)) then
timeoutFlag = .true. ! indicate timeout through flag argument
localrc = ESMF_SUCCESS ! do not raise error condition on user level
endif
endif
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! call the tunnel destructor
call c_ESMC_CompTunnelDestroy(compp%compTunnel, localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
if (fullShutdownArg) then
if (compp%vm_info /= ESMF_NULL_POINTER) then
! shut down this component's VM
#if 0
block
character(160):: msg, compName
call ESMF_GetName(compp%base, compName, rc=localrc)
write(msg,*) "ESMF_CompDestruct() calling ESMF_VMShutdown() for: ",&
trim(compName)
call ESMF_LogWrite(msg, logMsgFlag=ESMF_LOGMSG_DEBUG, rc=rc)
end block
#endif
call ESMF_VMShutdown(vm=compp%vm_parent, vmplan=compp%vmplan, &
vm_info=compp%vm_info, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
! destruct the VMPlan
call ESMF_VMPlanDestruct(vmplan=compp%vmplan, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! deallocate space held for petlist
deallocate(compp%petlist, stat=localrc)
if (ESMF_LogFoundDeallocError(localrc, msg="local petlist", &
ESMF_CONTEXT, rcToReturn=rc)) return
! deallocate space held for devlist
deallocate(compp%devlist, stat=localrc)
if (ESMF_LogFoundDeallocError(localrc, msg="local devlist", &
ESMF_CONTEXT, rcToReturn=rc)) return
! call C++ to release function and data pointer tables.
call c_ESMC_FTableDestroy(compp%ftable, localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! Release attributes on config
if(compp%configFile /= "uninitialized" ) then !TODO use is present here
call ESMF_ConfigDestroy(compp%config, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
! destroy the methodTable object
call c_ESMC_MethodTableDestroy(compp%methodTable, localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
endif
! Return successfully
if (present(rc)) rc = ESMF_SUCCESS
end subroutine ESMF_CompDestruct