ESMF_CplCompServiceLoop Subroutine

public recursive subroutine ESMF_CplCompServiceLoop(cplcomp, keywordEnforcer, importState, exportState, clock, syncflag, port, timeout, timeoutFlag, rc)

Arguments

Type IntentOptional Attributes Name
type(ESMF_CplComp), intent(inout) :: cplcomp
type(ESMF_KeywordEnforcer), optional :: keywordEnforcer
type(ESMF_State), intent(inout), optional :: importState
type(ESMF_State), intent(inout), optional :: exportState
type(ESMF_Clock), intent(inout), optional :: clock
type(ESMF_Sync_Flag), intent(in), optional :: syncflag
integer, intent(in), optional :: port
integer, intent(in), optional :: timeout
logical, intent(out), optional :: timeoutFlag
integer, intent(out), optional :: rc

Source Code

  recursive subroutine ESMF_CplCompServiceLoop(cplcomp, keywordEnforcer, &
    importState, exportState, clock, syncflag, port, timeout, timeoutFlag, rc)
!
! !ARGUMENTS:
    type(ESMF_CplComp),   intent(inout)           :: cplcomp
type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below
    type(ESMF_State),     intent(inout), optional :: importState
    type(ESMF_State),     intent(inout), optional :: exportState
    type(ESMF_Clock),     intent(inout), optional :: clock
    type(ESMF_Sync_Flag), intent(in),    optional :: syncflag
    integer,              intent(in),    optional :: port
    integer,              intent(in),    optional :: timeout
    logical,              intent(out),   optional :: timeoutFlag
    integer,              intent(out),   optional :: rc
!
! !DESCRIPTION:
! Call the ServiceLoop routine for an {\tt ESMF\_CplComp}.
! This tries to establish a "component tunnel" between the {\em actual}
! Component (calling this routine) and a {\tt dual} Component connecting to it
! through a matching SetServices call.
!
! The arguments are:
! \begin{description}
! \item[cplcomp]
!   {\tt ESMF\_CplComp} to call service loop routine for.
! \item[{[importState]}]
!   {\tt ESMF\_State} containing import data for coupling. If not present, a dummy
!   argument will be passed to the user-supplied routine.  The
!   importState argument in the user code cannot be optional.
! \item[{[exportState]}]
!   {\tt ESMF\_State} containing export data for coupling. If not present, a dummy
!   argument will be passed to the user-supplied routine.  The
!   exportState argument in the user code cannot be optional.
! \item[{[clock]}]
!   External {\tt ESMF\_Clock} for passing in time information.
!   This is generally the parent component's clock, and will be treated
!   as read-only by the child component.  The child component can maintain
!   a private clock for its own internal time computations. If not present, a dummy
!   argument will be passed to the user-supplied routine.  The
!   clock argument in the user code cannot be optional.
! \item[{[syncflag]}]
!   Blocking behavior of this method call. See section \ref{const:sync}
!   for a list of valid blocking options. Default option is
!   {\tt ESMF\_SYNC\_VASBLOCKING} which blocks PETs and their spawned off threads
!   across each VAS but does not synchronize PETs that run in different VASs.
! \item[{[port]}]
!   In case a port number is provided, the "component tunnel" is established
!   using sockets. The actual component side, i.e. the side that calls into
!   {\tt ESMF\_CplCompServiceLoop()}, starts to listen on the specified port
!   as the server. The valid port range is [1024, 65535].
!   In case the {\tt port} argument is {\em not} specified, the "component
!   tunnel" is established within the same executable using local communication
!   methods (e.g. MPI).
! \item[{[timeout]}]
!   The maximum period in seconds that this call will wait for communications
!   with the dual component, before returning with a timeout condition.
!   The default is 3600, i.e. 1 hour.
!   (NOTE: Currently this option is only available for socket based component
!   tunnels.)
! \item[{[timeoutFlag]}]
!   Returns {\tt .true.} if the timeout was reached, {\tt .false.} otherwise.
!   If {\tt timeoutFlag} was {\em not} provided, a timeout condition will lead
!   to a return code of {\tt rc \textbackslash = ESMF\_SUCCESS}. Otherwise the
!   return value of {\tt timeoutFlag} is the sole indicator of a timeout
!   condition.
! \item[{[rc]}]
!   Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
!EOP
!------------------------------------------------------------------------------
    integer :: localrc                        ! local return code
    integer :: localrc2                       ! local return code
    integer :: timeoutArg

    ! initialize return code; assume routine not implemented
    if (present(rc)) rc = ESMF_RC_NOT_IMPL
    localrc = ESMF_RC_NOT_IMPL

    ESMF_INIT_CHECK_DEEP(ESMF_CplCompGetInit,cplcomp,rc)

    if (.not.present(port).and.(present(timeout))) then
      call ESMF_LogSetError(ESMF_RC_ARG_INCOMP, &
        msg="Currently the 'timeout' argument requires the 'port' argument", &
        ESMF_CONTEXT, rcToReturn=rc)
      return  ! bail out
    endif

    timeoutArg = ESMF_DEFAULT_TIMEOUT ! default 1h
    if (present(timeout)) timeoutArg = timeout

    ! call Comp method
    call ESMF_CompExecute(cplcomp%compp, method=ESMF_METHOD_SERVICELOOP, &
      importState=importState, exportState=exportState, clock=clock, &
      syncflag=syncflag, port=port, timeout=timeoutArg, userRc=localrc2, &
      rc=localrc)
    if (ESMF_LogFoundError(localrc, &
      ESMF_ERR_PASSTHRU, &
      ESMF_CONTEXT, rcToReturn=rc)) return
    ! ESMF_METHOD_SERVICELOOP is a framework internal method, therefore
    ! the code returned in userRc is a framework internal return code and must
    ! be treated as such. However, the treatment of RC_TIMEOUT depends
    ! on the presence/absence of timeoutFlag.
    if (present(timeoutFlag)) then
      timeoutFlag = .false. ! initialize
      if ((localrc2==ESMF_RC_TIMEOUT).or.(localrc2==ESMC_RC_TIMEOUT)) then
        timeoutFlag = .true.      ! indicate timeout through flag argument
        localrc2 = ESMF_SUCCESS   ! do not raise error condition on user level
      endif
    endif
    if (ESMF_LogFoundError(localrc2, &
      ESMF_ERR_PASSTHRU, &
      ESMF_CONTEXT, rcToReturn=rc)) return

    ! return successfully
    if (present(rc)) rc = ESMF_SUCCESS
  end subroutine ESMF_CplCompServiceLoop