(FILECREATED "16-Apr-85 15:36:13" {ERIS}<LISPNEW>INTERMEZZO>PATCHES>SPPPATCH.;1 4945   

      changes to:  (VARS SPPPATCHCOMS))


(* Copyright (c) 1985 by Xerox Corporation. All rights reserved.)

(PRETTYCOMPRINT SPPPATCHCOMS)

(RPAQQ SPPPATCHCOMS ((FNS \GETSPP \SPP.SENDPKT)))
(DEFINEQ

(\GETSPP
  [LAMBDA (CON TIMEOUT PEEKFLG)                              (* bvm: "16-Apr-85 13:10")

          (* Obtains the next packet on this SPP connection. If TIMEOUT is specified and expires before a packet arrives, 
	  returns NIL. Also returns NIL if the connection is terminated. If PEEKFLG is true, returns the next packet without 
	  removing it from queue.)


    (WITH.MONITOR (fetch SPPLOCK of CON)
		  (bind (EPKT ← NIL)
			(TIMER ←(AND TIMEOUT (SETUPTIMER TIMEOUT)))
		     do (COND
			  ((AND (SETQ EPKT (\QUEUEHEAD (fetch SPPINPUTQ of CON)))
				(ILESSP (fetch (SPPXIP SEQNO) of EPKT)
					(fetch SPPACKNO of CON)))
                                                             (* This is the packet we've been waiting for.
							     The ACKNO field has already been incremented in 
							     \SPP.HANDLE.DATA)
			    [COND
			      ((NOT PEEKFLG)
				(UNINTERRUPTABLY
                                    (\DEQUEUE (fetch SPPINPUTQ of CON))
				    (add (fetch SPPACCEPTNO of CON)
					 1))
				(COND
				  ((AND (fetch SPPINPUTBLOCKED of CON)
					(GREATERP (fetch SPPACCEPTNO of CON)
						  (fetch SPPACKNO of CON)))

          (* Partner was waiting to be able to transmit again, so allow it now. Don't send this gratuitous ack the moment we 
	  open up; wait for the window to at least get a couple of packets wide)


				    (\SPP.SENDPKT CON (\SPP.SYSPKT CON]
			    (RETURN EPKT))
			  ((OR (AND TIMEOUT (TIMEREXPIRED? TIMER))
			       (fetch SPPTERMINATEDP of CON))
			    (RETURN NIL))
			  (T (MONITOR.AWAIT.EVENT (fetch SPPLOCK of CON)
						  (fetch SPPINPUTEVENT of CON)
						  TIMER T])

(\SPP.SENDPKT
  [LAMBDA (CON EPKT RETRANSMITP)                             (* bvm: "16-Apr-85 13:03")

          (* This function makes sure the variable connection information in the packet is current, and actually sends the 
	  packet. If the packet is to be retransmitted, the connection must be locked when this function is called.
	  Note that the sequence number is NOT updated; it was allocated once and for all by \SENDSPP)


    (PROG ((ACK# (fetch SPPACKNO of CON))
	   (ALLOC# (fetch SPPACCEPTNO of CON))
	   (BASE (fetch XIPCONTENTS of EPKT))
	   SEQNO)
          (AND RETRANSMITP (HELP "RETRANSMITP on"))
          (replace (SPPHEAD ACKNO) of BASE with ACK#)
          (replace (SPPHEAD ALLOCNO) of BASE with ALLOC#)
          (replace SPPINPUTBLOCKED of CON with (IGREATERP ACK# ALLOC#))
                                                             (* If ACK# > ALLOC# then partner cannot send more data 
							     until we eat some of what we have)
          [COND
	    ((fetch (SPPHEAD SENDACK) of BASE)

          (* We start a timer when we send an Ack request, and turn it off when the next packet arrives 
	  (in \SPPINPUTWORK.) If the timer expires, we assume that the connection is wedged. Otherwise, the elapsed time will 
	  be used to update our estimate of the round trip delay. The timer will go off after the user-level timeout, or twice
	  the round trip delay, whichever is longer.)


	      (SETQ SEQNO (fetch (SPPHEAD SEQNO) of BASE))
	      (COND
		((OR (NOT (fetch SPPACKREQUESTED of CON))
		     (IGREATERP SEQNO (fetch SPPACKREQUESTED of CON)))
		  (replace SPPACKREQUESTED of CON with SEQNO)
		  (replace SPPACKREQTIMEOUT of CON with (SETUPTIMER (MAX SPP.USER.TIMEOUT
									 (UNFOLD (fetch 
										 SPPROUNDTRIPTIME
										    of CON)
										 4))
								    (fetch SPPACKREQTIMEOUT
								       of CON)))
		  (replace SPPACKREQTIME of CON with (SETUPTIMER 0 (fetch SPPACKREQTIME of CON]
          (replace SPPACKPENDING of CON with NIL)            (* If partner asked for an ack, this will satisfy it)
          (SENDXIP (fetch SPPMYNSOCKET of CON)
		   EPKT)
          (replace SPPRETRANSMITTIMER of CON with (SETUPTIMER (COND
								((fetch SPPRETRANSMITTING
								    of CON)
								  SPP.MIN.TIMEOUT)
								(T (UNFOLD (fetch SPPROUNDTRIPTIME
									      of CON)
									   2)))
							      (fetch SPPRETRANSMITTIMER of CON])
)
(PUTPROPS SPPPATCH COPYRIGHT ("Xerox Corporation" 1985))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (289 4866 (\GETSPP 299 . 2149) (\SPP.SENDPKT 2151 . 4864)))))
STOP