From 5b5295fd40844f5f8b8c181071392031d8b0ad96 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Sun, 16 Apr 2017 15:17:55 -0500 Subject: [PATCH] Fixes related to error handling and asynchronous command support. --- aspinterface.c | 55 ++++++++++++++++++++++++++++++------------------- aspinterface.h | 2 +- dsi.c | 2 +- tcpconnection.c | 29 ++++++++++---------------- tcpconnection.h | 2 +- 5 files changed, 48 insertions(+), 42 deletions(-) diff --git a/aspinterface.c b/aspinterface.c index e3656cb..f33ff35 100644 --- a/aspinterface.c +++ b/aspinterface.c @@ -41,6 +41,7 @@ static void DoSPCloseSession(Session *sess); static void DoSPCommand(Session *sess, ASPCommandRec *commandRec); static void DoSPWrite(Session *sess, ASPWriteRec *commandRec); +static void CompleteASPCommand(SPCommandRec *commandRec, Word result); Session sessionTbl[MAX_SESSIONS]; @@ -71,14 +72,15 @@ LongWord DispatchASPCommand(SPCommandRec *commandRec) { break; } if (i == MAX_SESSIONS) { - CompleteASPCommand(sess, aspTooManySessions); + CompleteASPCommand(commandRec, aspTooManySessions); goto ret; } sess = &sessionTbl[i]; sess->spCommandRec = commandRec; + sess->commandPending = TRUE; - if (!StartTCPConnection(sess)) { - FlagFatalError(sess, commandRec->result); + if ((i = StartTCPConnection(sess)) != 0) { + FlagFatalError(sess, i); goto ret; } sess->dsiStatus = awaitingHeader; @@ -99,24 +101,24 @@ LongWord DispatchASPCommand(SPCommandRec *commandRec) { if ((commandRec->async & AT_ASYNC) && commandRec->command == aspCommandCommand) { - commandRec->result = atSyncErr; - CallCompletionRoutine((void*)commandRec->completionPtr); + CompleteASPCommand(commandRec, atSyncErr); goto ret; } - i = commandRec->refNum - SESSION_NUM_START; - sess = &sessionTbl[i]; - sess->spCommandRec = commandRec; - } - - // TODO properly handle all cases of getting a command while - // one is in progress - if (commandRec->command != aspCloseSessionCommand) { + sess = &sessionTbl[commandRec->refNum - SESSION_NUM_START]; + if (sess->commandPending) { - CompleteASPCommand(sess, aspSessNumErr); - goto ret; + if (commandRec->command != aspCloseSessionCommand) { + CompleteASPCommand(commandRec, aspSessNumErr); + goto ret; + } else { + CompleteCurrentASPCommand(sess, aspSessionClosed); + } } - sess->commandPending = TRUE; + + sess->spCommandRec = commandRec; + if (commandRec->command != aspCloseSessionCommand) + sess->commandPending = TRUE; } switch (commandRec->command) { @@ -145,6 +147,8 @@ LongWord DispatchASPCommand(SPCommandRec *commandRec) { // if we're here, the call is synchronous -- we must complete it if (commandRec->command == aspCloseSessionCommand) { + /* We don't wait for a reply to close */ + memset(&sess->reply, 0, sizeof(sess->reply)); FinishASPCommand(sess); } else { while (sess->commandPending) { @@ -317,7 +321,7 @@ void FlagFatalError(Session *sess, Word errorCode) { } if (sess->commandPending) { - CompleteASPCommand(sess, errorCode); + CompleteCurrentASPCommand(sess, errorCode); } EndSession(sess, aspAttenTimeout); @@ -332,8 +336,8 @@ void FinishASPCommand(Session *sess) { if (dataLength > 0xFFFF) { // The IIgs ASP interfaces can't represent lengths over 64k. // This should be detected as an error earlier, but let's make sure. - sess->spCommandRec->result = aspSizeErr; - goto complete; + CompleteCurrentASPCommand(sess, aspSizeErr); + return; } switch(sess->spCommandRec->command) { @@ -361,11 +365,11 @@ void FinishASPCommand(Session *sess) { } complete: - CompleteASPCommand(sess, 0); + CompleteCurrentASPCommand(sess, 0); } /* Actions to complete a command, whether successful or not */ -void CompleteASPCommand(Session *sess, Word result) { +void CompleteCurrentASPCommand(Session *sess, Word result) { SPCommandRec *commandRec; commandRec = sess->spCommandRec; @@ -389,6 +393,15 @@ void CompleteASPCommand(Session *sess, Word result) { } } +/* For use in error cases not involving the session's current command */ +static void CompleteASPCommand(SPCommandRec *commandRec, Word result) { + commandRec->result = result; + + if ((commandRec->async & AT_ASYNC) && commandRec->completionPtr != NULL) { + CallCompletionRoutine((void *)commandRec->completionPtr); + } +} + static void EndSession(Session *sess, Byte attentionCode) { if (attentionCode != 0) { diff --git a/aspinterface.h b/aspinterface.h index c97f63f..0d17c59 100644 --- a/aspinterface.h +++ b/aspinterface.h @@ -15,7 +15,7 @@ extern Session sessionTbl[MAX_SESSIONS]; LongWord DispatchASPCommand(SPCommandRec *commandRec); -void CompleteASPCommand(Session *sess, Word result); +void CompleteCurrentASPCommand(Session *sess, Word result); void FinishASPCommand(Session *sess); void FlagFatalError(Session *sess, Word errorCode); void PollAllSessions(void); diff --git a/dsi.c b/dsi.c index 983a6a7..18c3afa 100644 --- a/dsi.c +++ b/dsi.c @@ -142,7 +142,7 @@ top: // Maybe we should do something with them? FinishASPCommand(sess); } else { - CompleteASPCommand(sess, aspBufErr); + CompleteCurrentASPCommand(sess, aspBufErr); } } else { FinishASPCommand(sess); diff --git a/tcpconnection.c b/tcpconnection.c index 7cdbf3e..91c7793 100644 --- a/tcpconnection.c +++ b/tcpconnection.c @@ -11,10 +11,10 @@ /* Make a TCP connection to the address mapped to the specified AT address. * sess->spCommandRec should be an SPGetStatus or SPOpenSession command. * - * On success, returns TRUE and sets sess->ipid. - * On failure, returns FALSE and sets commandRec->result to an error code. + * On success, returns 0 and sets sess->ipid. + * On failure, returns an ASP error code. */ -BOOLEAN StartTCPConnection(Session *sess) { +Word StartTCPConnection(Session *sess) { Word tcperr; ASPOpenSessionRec *commandRec; srBuff mySRBuff; @@ -26,28 +26,22 @@ BOOLEAN StartTCPConnection(Session *sess) { if (TCPIPGetConnectStatus() == FALSE) { TCPIPConnect(NULL); - if (toolerror()) { - commandRec->result = aspNetworkErr; - return FALSE; - } + if (toolerror()) + return aspNetworkErr; } sess->ipid = TCPIPLogin(userid(), atipMapping.ipAddr, atipMapping.port, 0, 0x40); - if (toolerror()) { - commandRec->result = aspNetworkErr; - return FALSE; - } + if (toolerror()) + return aspNetworkErr; tcperr = TCPIPOpenTCP(sess->ipid); if (toolerror()) { TCPIPLogout(sess->ipid); - commandRec->result = aspNetworkErr; - return FALSE; + return aspNetworkErr; } else if (tcperr != tcperrOK) { TCPIPLogout(sess->ipid); - commandRec->result = aspNoRespErr; - return FALSE; + return aspNoRespErr; } initialTime = GetTick(); @@ -58,12 +52,11 @@ BOOLEAN StartTCPConnection(Session *sess) { if (mySRBuff.srState != TCPSESTABLISHED) { TCPIPAbortTCP(sess->ipid); TCPIPLogout(sess->ipid); - commandRec->result = aspNoRespErr; - return FALSE; + return aspNoRespErr; } sess->tcpLoggedIn = TRUE; - return TRUE; + return 0; } void EndTCPConnection(Session *sess) { diff --git a/tcpconnection.h b/tcpconnection.h index e993673..5e6933f 100644 --- a/tcpconnection.h +++ b/tcpconnection.h @@ -3,7 +3,7 @@ #include "session.h" -BOOLEAN StartTCPConnection(Session *sess); +Word StartTCPConnection(Session *sess); void EndTCPConnection(Session *sess); #endif