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 DoSPCommand(Session *sess, ASPCommandRec *commandRec);
static void DoSPWrite(Session *sess, ASPWriteRec *commandRec); static void DoSPWrite(Session *sess, ASPWriteRec *commandRec);
static void CompleteASPCommand(SPCommandRec *commandRec, Word result);
Session sessionTbl[MAX_SESSIONS]; Session sessionTbl[MAX_SESSIONS];
@ -71,14 +72,15 @@ LongWord DispatchASPCommand(SPCommandRec *commandRec) {
break; break;
} }
if (i == MAX_SESSIONS) { if (i == MAX_SESSIONS) {
CompleteASPCommand(sess, aspTooManySessions); CompleteASPCommand(commandRec, aspTooManySessions);
goto ret; goto ret;
} }
sess = &sessionTbl[i]; sess = &sessionTbl[i];
sess->spCommandRec = commandRec; sess->spCommandRec = commandRec;
sess->commandPending = TRUE;
if (!StartTCPConnection(sess)) { if ((i = StartTCPConnection(sess)) != 0) {
FlagFatalError(sess, commandRec->result); FlagFatalError(sess, i);
goto ret; goto ret;
} }
sess->dsiStatus = awaitingHeader; sess->dsiStatus = awaitingHeader;
@ -99,24 +101,24 @@ LongWord DispatchASPCommand(SPCommandRec *commandRec) {
if ((commandRec->async & AT_ASYNC) if ((commandRec->async & AT_ASYNC)
&& commandRec->command == aspCommandCommand) && commandRec->command == aspCommandCommand)
{ {
commandRec->result = atSyncErr; CompleteASPCommand(commandRec, atSyncErr);
CallCompletionRoutine((void*)commandRec->completionPtr);
goto ret; goto ret;
} }
i = commandRec->refNum - SESSION_NUM_START; sess = &sessionTbl[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) {
if (sess->commandPending) { if (sess->commandPending) {
CompleteASPCommand(sess, aspSessNumErr); if (commandRec->command != aspCloseSessionCommand) {
goto ret; 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) { switch (commandRec->command) {
@ -145,6 +147,8 @@ LongWord DispatchASPCommand(SPCommandRec *commandRec) {
// if we're here, the call is synchronous -- we must complete it // if we're here, the call is synchronous -- we must complete it
if (commandRec->command == aspCloseSessionCommand) { if (commandRec->command == aspCloseSessionCommand) {
/* We don't wait for a reply to close */
memset(&sess->reply, 0, sizeof(sess->reply));
FinishASPCommand(sess); FinishASPCommand(sess);
} else { } else {
while (sess->commandPending) { while (sess->commandPending) {
@ -317,7 +321,7 @@ void FlagFatalError(Session *sess, Word errorCode) {
} }
if (sess->commandPending) { if (sess->commandPending) {
CompleteASPCommand(sess, errorCode); CompleteCurrentASPCommand(sess, errorCode);
} }
EndSession(sess, aspAttenTimeout); EndSession(sess, aspAttenTimeout);
@ -332,8 +336,8 @@ void FinishASPCommand(Session *sess) {
if (dataLength > 0xFFFF) { if (dataLength > 0xFFFF) {
// The IIgs ASP interfaces can't represent lengths over 64k. // The IIgs ASP interfaces can't represent lengths over 64k.
// This should be detected as an error earlier, but let's make sure. // This should be detected as an error earlier, but let's make sure.
sess->spCommandRec->result = aspSizeErr; CompleteCurrentASPCommand(sess, aspSizeErr);
goto complete; return;
} }
switch(sess->spCommandRec->command) { switch(sess->spCommandRec->command) {
@ -361,11 +365,11 @@ void FinishASPCommand(Session *sess) {
} }
complete: complete:
CompleteASPCommand(sess, 0); CompleteCurrentASPCommand(sess, 0);
} }
/* Actions to complete a command, whether successful or not */ /* Actions to complete a command, whether successful or not */
void CompleteASPCommand(Session *sess, Word result) { void CompleteCurrentASPCommand(Session *sess, Word result) {
SPCommandRec *commandRec; SPCommandRec *commandRec;
commandRec = sess->spCommandRec; 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) { static void EndSession(Session *sess, Byte attentionCode) {
if (attentionCode != 0) { if (attentionCode != 0) {

View File

@ -15,7 +15,7 @@
extern Session sessionTbl[MAX_SESSIONS]; extern Session sessionTbl[MAX_SESSIONS];
LongWord DispatchASPCommand(SPCommandRec *commandRec); LongWord DispatchASPCommand(SPCommandRec *commandRec);
void CompleteASPCommand(Session *sess, Word result); void CompleteCurrentASPCommand(Session *sess, Word result);
void FinishASPCommand(Session *sess); void FinishASPCommand(Session *sess);
void FlagFatalError(Session *sess, Word errorCode); void FlagFatalError(Session *sess, Word errorCode);
void PollAllSessions(void); void PollAllSessions(void);

2
dsi.c
View File

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

View File

@ -11,10 +11,10 @@
/* Make a TCP connection to the address mapped to the specified AT address. /* Make a TCP connection to the address mapped to the specified AT address.
* sess->spCommandRec should be an SPGetStatus or SPOpenSession command. * sess->spCommandRec should be an SPGetStatus or SPOpenSession command.
* *
* On success, returns TRUE and sets sess->ipid. * On success, returns 0 and sets sess->ipid.
* On failure, returns FALSE and sets commandRec->result to an error code. * On failure, returns an ASP error code.
*/ */
BOOLEAN StartTCPConnection(Session *sess) { Word StartTCPConnection(Session *sess) {
Word tcperr; Word tcperr;
ASPOpenSessionRec *commandRec; ASPOpenSessionRec *commandRec;
srBuff mySRBuff; srBuff mySRBuff;
@ -26,28 +26,22 @@ BOOLEAN StartTCPConnection(Session *sess) {
if (TCPIPGetConnectStatus() == FALSE) { if (TCPIPGetConnectStatus() == FALSE) {
TCPIPConnect(NULL); TCPIPConnect(NULL);
if (toolerror()) { if (toolerror())
commandRec->result = aspNetworkErr; return aspNetworkErr;
return FALSE;
}
} }
sess->ipid = sess->ipid =
TCPIPLogin(userid(), atipMapping.ipAddr, atipMapping.port, 0, 0x40); TCPIPLogin(userid(), atipMapping.ipAddr, atipMapping.port, 0, 0x40);
if (toolerror()) { if (toolerror())
commandRec->result = aspNetworkErr; return aspNetworkErr;
return FALSE;
}
tcperr = TCPIPOpenTCP(sess->ipid); tcperr = TCPIPOpenTCP(sess->ipid);
if (toolerror()) { if (toolerror()) {
TCPIPLogout(sess->ipid); TCPIPLogout(sess->ipid);
commandRec->result = aspNetworkErr; return aspNetworkErr;
return FALSE;
} else if (tcperr != tcperrOK) { } else if (tcperr != tcperrOK) {
TCPIPLogout(sess->ipid); TCPIPLogout(sess->ipid);
commandRec->result = aspNoRespErr; return aspNoRespErr;
return FALSE;
} }
initialTime = GetTick(); initialTime = GetTick();
@ -58,12 +52,11 @@ BOOLEAN StartTCPConnection(Session *sess) {
if (mySRBuff.srState != TCPSESTABLISHED) { if (mySRBuff.srState != TCPSESTABLISHED) {
TCPIPAbortTCP(sess->ipid); TCPIPAbortTCP(sess->ipid);
TCPIPLogout(sess->ipid); TCPIPLogout(sess->ipid);
commandRec->result = aspNoRespErr; return aspNoRespErr;
return FALSE;
} }
sess->tcpLoggedIn = TRUE; sess->tcpLoggedIn = TRUE;
return TRUE; return 0;
} }
void EndTCPConnection(Session *sess) { void EndTCPConnection(Session *sess) {

View File

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