+static pascal void mactcp_asr(StreamPtr str, unsigned short event, Ptr cookie,
+ unsigned short termin_reason,
+ struct ICMPReport *icmp)
+{
+
+ WakeUpProcess(&mactcp.self);
+}
+
+/*
+ * Called from our event loop if there's work to do.
+ */
+void mactcp_poll(void)
+{
+ Actual_Socket s, next;
+ TCPiopb pb;
+
+ for (s = mactcp.socklist; s != NULL; s = next) {
+ next = s->next;
+ do {
+ pb.ioCRefNum = mactcp.refnum;
+ pb.csCode = TCPStatus;
+ pb.tcpStream = s->s;
+ pb.csParam.status.userDataPtr = (Ptr)s;
+ s->err = PBControlSync((ParmBlkPtr)&pb);
+ if (s->err != noErr)
+ goto next_socket;
+ if (pb.csParam.status.amtUnreadData == 0)
+ break;
+ mactcp_recv(s, pb.csParam.status.amtUnreadData);
+ } while (TRUE);
+ switch (pb.csParam.status.connectionState) {
+ case TCPS_CLOSE_WAIT:
+ /* Remote end has sent us a FIN */
+ plug_closing(s->plug, NULL, 0, 0);
+ }
+ next_socket:
+ ;
+ }
+}
+
+static void mactcp_recv(Actual_Socket s, size_t len)
+{
+ rdsEntry rds[2];
+ TCPiopb pb;
+
+ if (s->frozen) return;
+
+ while (len > 0) {
+ pb.ioCRefNum = mactcp.refnum;
+ pb.csCode = TCPNoCopyRcv;
+ pb.tcpStream = s->s;
+ pb.csParam.receive.commandTimeoutValue = 0;
+ pb.csParam.receive.rdsPtr = (Ptr)rds;
+ pb.csParam.receive.rdsLength = lenof(rds) - 1;
+ pb.csParam.receive.userDataPtr = (Ptr)s;
+ s->err = PBControlSync((ParmBlkPtr)&pb);
+ if (s->err != noErr)
+ return;
+ plug_receive(s->plug, 0, rds[0].ptr, rds[0].length);
+ len -= rds[0].length;
+ pb.csCode = TCPRcvBfrReturn;
+ s->err = PBControlSync((ParmBlkPtr)&pb);
+ if (s->err != noErr)
+ return;
+ }
+}
+