-- Stub file PDInterpControlRpcBinderImpl.mesa was translated on 17-Nov-83
    -- 16:30:29 PST by Lupine of 18-Feb-83 11:25:52 PST.

-- Source interface PDInterpControl came from file PDInterpControl.bcd,
    -- which was created on 17-Nov-83 16:29:50 PST with version stamp 143#147#26343705132
    -- from source of 16-Nov-83 14:49:41 PST.

-- The RPC stub modules for PDInterpControl are:
    -- PDInterpControlRpcControl.mesa;
    -- PDInterpControlRpcClientImpl.mesa;
    -- PDInterpControlRpcBinderImpl.mesa;
    -- PDInterpControlRpcServerImpl.mesa.

-- The parameters for this translation are:
    -- Target language = Mesa;
    -- Default parameter passing = VALUE;
    -- Deallocate server heap arguments = TRUE;
    -- Inline RpcServerImpl dispatcher stubs = TRUE;
    -- Maximum number of dynamic heap NEWs = 50, MDS NEWs = 50;
    -- Acceptable parameter protocols = VersionRange[1,1].

-- NOTE: Discard this module unless you use dynamic client binding.


DIRECTORY
  PDInterpControlRpcControl USING [InterfaceRecord, InterfaceRecordObject],
  PDInterpControlRpcClientImpl,
  MesaRPC USING [InterfaceName, Zones],
  Heap USING [systemZone];


PDInterpControlRpcBinderImpl: MONITOR
  IMPORTS ClientPrototype: PDInterpControlRpcClientImpl, Heap
  EXPORTS PDInterpControlRpcControl
  SHARES  PDInterpControlRpcControl
  = BEGIN OPEN RpcControl: PDInterpControlRpcControl, RpcPublic: MesaRPC;


-- Dynamic instantiation and binding routines.

  ImportNewInterface: PUBLIC PROCEDURE [
        interfaceName: RpcPublic.InterfaceName,
        parameterStorage: RpcPublic.Zones ]
      RETURNS [interfaceRecord: RpcControl.InterfaceRecord] =
    BEGIN
    interfaceRecord ← NewInterface[];
    LupineDetails[interfaceRecord].module.ImportInterface [
        interfaceName: interfaceName,
        parameterStorage: parameterStorage
      ! UNWIND => FreeInterface[interfaceRecord] ];
    END;

  UnimportNewInterface: PUBLIC PROCEDURE [
      interfaceRecord: RpcControl.InterfaceRecord ] =
    BEGIN
    LupineDetails[interfaceRecord].module.UnimportInterface[];
    FreeInterface[interfaceRecord];
    END;


-- Utility routines for interface instantiation and caching.

  ConcreteLupineDetails: TYPE = LONG POINTER TO LupineDetailsObject;

  LupineDetailsObject:  PUBLIC TYPE = RECORD [
	module: ClientModule←NIL,
	list: RpcControl.InterfaceRecord←NIL, --package reference
	next: RpcControl.InterfaceRecord←NIL --free list -- ];

  LupineDetails: PROCEDURE [abstractInterface: RpcControl.InterfaceRecord]
      RETURNS [ConcreteLupineDetails] =
    INLINE {RETURN[abstractInterface.lupineDetails]};

  ClientModule: TYPE = POINTER TO FRAME[PDInterpControlRpcClientImpl];


  clientInterfaceCache: RpcControl.InterfaceRecord ← NIL; -- free interface
      -- records
  clientInterfaceList: RpcControl.InterfaceRecord ← NIL; -- all interface
      -- records

  NewInterfaceRecord: PUBLIC PROCEDURE
    RETURNS [interfaceRecord: RpcControl.InterfaceRecord] =
    BEGIN
    interfaceRecord ← Heap.systemZone.NEW[RpcControl.InterfaceRecordObject];
    END;

  NewInterface: PROCEDURE RETURNS [interface: RpcControl.InterfaceRecord]=
    BEGIN
    GetCachedInterface: ENTRY PROCEDURE
        RETURNS [cachedIR: RpcControl.InterfaceRecord] =
      INLINE BEGIN ENABLE UNWIND => NULL;
      IF (cachedIR←clientInterfaceCache) # NIL
        THEN clientInterfaceCache ← LupineDetails[clientInterfaceCache].next;
      END;
    IF (interface ← GetCachedInterface[]) = NIL
      THEN BEGIN
        ChainNewInterface: ENTRY PROCEDURE =
          INLINE BEGIN ENABLE UNWIND => NULL;
          interface.lupineDetails ← Heap.systemZone.NEW[
            LupineDetailsObject ← [module: module, list: clientInterfaceList]];
          clientInterfaceList ← interface;
          END; -- ChainNewInterface.
        module: ClientModule = NEW ClientPrototype;
        interface ← NewInterfaceRecord[];
        interface↑ ← [
	    RequestService: module.RequestService];
        ChainNewInterface[];
        END;
    END;

  FreeInterface: ENTRY PROCEDURE [interface: RpcControl.InterfaceRecord]=
    INLINE BEGIN ENABLE UNWIND => NULL;
    LupineDetails[interface].next ← clientInterfaceCache;
    clientInterfaceCache ← interface;
    END;

   
-- No module initialization.


  END.  -- PDInterpControlRpcBinderImpl.