Fixes related to error handling and asynchronous command support.

This commit is contained in:
Stephen Heumann 2017-04-16 15:17:55 -05:00
parent 9d6dad03b4
commit 5b5295fd40
5 changed files with 48 additions and 42 deletions

View File

@ -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,23 +101,23 @@ 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;
}
sess = &sessionTbl[commandRec->refNum - SESSION_NUM_START];
// TODO properly handle all cases of getting a command while
// one is in progress
if (commandRec->command != aspCloseSessionCommand) {
if (sess->commandPending) {
CompleteASPCommand(sess, aspSessNumErr);
if (commandRec->command != aspCloseSessionCommand) {
CompleteASPCommand(commandRec, aspSessNumErr);
goto ret;
} else {
CompleteCurrentASPCommand(sess, aspSessionClosed);
}
}
sess->spCommandRec = commandRec;
if (commandRec->command != aspCloseSessionCommand)
sess->commandPending = TRUE;
}
@ -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) {

View File

@ -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);

2
dsi.c
View File

@ -142,7 +142,7 @@ top:
// Maybe we should do something with them?
FinishASPCommand(sess);
} else {
CompleteASPCommand(sess, aspBufErr);
CompleteCurrentASPCommand(sess, aspBufErr);
}
} else {
FinishASPCommand(sess);

View File

@ -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) {

View File

@ -3,7 +3,7 @@
#include "session.h"
BOOLEAN StartTCPConnection(Session *sess);
Word StartTCPConnection(Session *sess);
void EndTCPConnection(Session *sess);
#endif