Add code to close the sessions when the system is shutting down.

This only works if our init is loaded before Marinetti’s, because otherwise Marinetti’s shutdown notification procedure gets control first and shuts down the connection.
This commit is contained in:
Stephen Heumann 2017-04-16 00:37:57 -05:00
parent e5c1cd4465
commit 7d2c225d2f
4 changed files with 70 additions and 23 deletions

View File

@ -18,6 +18,7 @@ extern Word *unloadFlagPtr;
FSTInfoRecGS fstInfoRec;
void pollTask(void);
void notificationProc(void);
static struct RunQRec {
Long reserved1;
@ -28,6 +29,17 @@ static struct RunQRec {
void (*proc)(void);
} runQRec;
static struct NotificationProcRec {
Long reserved1;
Word reserved2;
Word Signature;
Long Event_flags;
Long Event_code;
Byte jml;
void (*proc)(void);
} notificationProcRec;
NotifyProcRecGS addNotifyProcRec;
void setUnloadFlag(void) {
if (*unloadFlagPtr == 0)
@ -83,6 +95,14 @@ int main(void) {
runQRec.proc = pollTask;
AddToRunQ((Pointer)&runQRec);
notificationProcRec.Signature = 0xA55A;
notificationProcRec.Event_flags = 0x20; /* shutdown */
notificationProcRec.jml = 0x5C;
notificationProcRec.proc = notificationProc;
addNotifyProcRec.pCount = 1;
addNotifyProcRec.procPointer = (ProcPtr)&notificationProcRec;
AddNotifyProcGS(&addNotifyProcRec);
return;
error:
@ -105,3 +125,24 @@ void pollTask(void) {
DecBusyFlag();
}
#pragma databank 0
/*
* Notification procedure called at shutdown time.
* We try to notify the servers that we're closing the connections.
* This only works if Marinetti is still active, i.e. if its own
* shutdown notification procedure hasn't run yet.
*/
#pragma databank 1
void notificationProc(void) {
Word stateReg;
IncBusyFlag();
stateReg = ForceRomIn();
CloseAllSessions(0);
RestoreStateReg(stateReg);
DecBusyFlag();
}
#pragma databank 0

View File

@ -33,11 +33,11 @@ static Byte loginBuf[100];
static const Byte afp20VersionStr[] = "\pAFPVersion 2.0";
static const Byte afp22VersionStr[] = "\pAFP2.2";
static void EndSession(Session *sess, Boolean callAttnRoutine);
static void EndSession(Session *sess, Byte attentionCode);
static void DoSPGetStatus(Session *sess, ASPGetStatusRec *commandRec);
static void DoSPOpenSession(Session *sess, ASPOpenSessionRec *commandRec);
static void DoSPCloseSession(Session *sess, ASPCloseSessionRec *commandRec);
static void DoSPOpenSession(Session *sess);
static void DoSPCloseSession(Session *sess);
static void DoSPCommand(Session *sess, ASPCommandRec *commandRec);
static void DoSPWrite(Session *sess, ASPWriteRec *commandRec);
@ -120,10 +120,10 @@ LongWord DispatchASPCommand(SPCommandRec *commandRec) {
DoSPGetStatus(sess, (ASPGetStatusRec *)commandRec);
break;
case aspOpenSessionCommand:
DoSPOpenSession(sess, (ASPOpenSessionRec *)commandRec);
DoSPOpenSession(sess);
break;
case aspCloseSessionCommand:
DoSPCloseSession(sess, (ASPCloseSessionRec *)commandRec);
DoSPCloseSession(sess);
break;
case aspCommandCommand:
DoSPCommand(sess, (ASPCommandRec *)commandRec);
@ -171,7 +171,7 @@ static void DoSPGetStatus(Session *sess, ASPGetStatusRec *commandRec) {
SendDSIMessage(sess, &sess->request, &kFPGetSrvrInfo, NULL);
}
static void DoSPOpenSession(Session *sess, ASPOpenSessionRec *commandRec) {
static void DoSPOpenSession(Session *sess) {
sess->request.flags = DSI_REQUEST;
sess->request.command = DSIOpenSession;
sess->request.requestID = htons(sess->nextRequestID++);
@ -183,7 +183,7 @@ static void DoSPOpenSession(Session *sess, ASPOpenSessionRec *commandRec) {
SendDSIMessage(sess, &sess->request, NULL, NULL);
}
static void DoSPCloseSession(Session *sess, ASPCloseSessionRec *commandRec) {
static void DoSPCloseSession(Session *sess) {
sess->request.flags = DSI_REQUEST;
sess->request.command = DSICloseSession;
sess->request.requestID = htons(sess->nextRequestID++);
@ -316,7 +316,7 @@ void FlagFatalError(Session *sess, Word errorCode) {
CompleteASPCommand(sess, errorCode);
}
EndSession(sess, TRUE);
EndSession(sess, aspAttenTimeout);
}
@ -369,7 +369,7 @@ void CompleteASPCommand(Session *sess, Word result) {
if (sess->spCommandRec->command == aspGetStatusCommand
|| sess->spCommandRec->command == aspCloseSessionCommand)
{
EndSession(sess, FALSE);
EndSession(sess, 0);
} else {
sess->commandPending = FALSE;
if (sess->dsiStatus != error) {
@ -386,8 +386,8 @@ void CompleteASPCommand(Session *sess, Word result) {
}
static void EndSession(Session *sess, Boolean callAttnRoutine) {
if (callAttnRoutine) {
static void EndSession(Session *sess, Byte attentionCode) {
if (attentionCode != 0) {
// TODO call the attention routine to report end of session
}
@ -404,3 +404,18 @@ void PollAllSessions(void) {
}
}
}
/* Close all sessions -- used when we're shutting down */
void CloseAllSessions(Byte attentionCode) {
unsigned int i;
Session *sess;
for (i = 0; i < MAX_SESSIONS; i++) {
sess = &sessionTbl[i];
if (sess->dsiStatus != unused) {
DoSPCloseSession(sess);
EndSession(sess, attentionCode);
}
}
}

View File

@ -19,5 +19,6 @@ void CompleteASPCommand(Session *sess, Word result);
void FinishASPCommand(Session *sess);
void FlagFatalError(Session *sess, Word errorCode);
void PollAllSessions(void);
void CloseAllSessions(Byte attentionCode);
#endif

View File

@ -67,19 +67,9 @@ BOOLEAN StartTCPConnection(Session *sess) {
}
void EndTCPConnection(Session *sess) {
srBuff mySRBuff;
LongWord initialTime;
if (sess->tcpLoggedIn) {
initialTime = GetTick();
do {
TCPIPPoll();
} while (TCPIPStatusTCP(sess->ipid, &mySRBuff) == tcperrOK
&& !toolerror()
&& mySRBuff.srState == TCPSESTABLISHED
&& mySRBuff.srSndQueued > 0
&& GetTick()-initialTime < 15*60);
TCPIPCloseTCP(sess->ipid);
TCPIPPoll();
TCPIPAbortTCP(sess->ipid);
TCPIPLogout(sess->ipid);
sess->tcpLoggedIn = FALSE;