ESMF_CompDestruct Subroutine

public recursive subroutine ESMF_CompDestruct(compp, interCompComm, fullShutdown, timeout, timeoutFlag, rc)

Arguments

Type IntentOptional Attributes Name
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

Source Code

  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