kCommandWrite, move logout to separate list.

This commit is contained in:
Kelvin Sherlock 2012-05-06 18:53:36 -04:00
parent 69a5fb0a6b
commit 0353485d98
1 changed files with 91 additions and 31 deletions

122
table.c
View File

@ -12,8 +12,14 @@
#define TABLE_MASK 15 #define TABLE_MASK 15
static struct Entry *table[TABLE_SIZE]; static struct Entry *table[TABLE_SIZE];
// ipids waiting to close + logout.
static struct Entry *dlist;
static void destroy_entry(Entry *e, Boolean abort);
void init_table(void) void init_table(void)
{ {
dlist = NULL;
memset(table, 0, sizeof(table)); memset(table, 0, sizeof(table));
} }
@ -21,6 +27,7 @@ void destroy_table(void)
{ {
Entry *e; Entry *e;
Entry *next;
unsigned i; unsigned i;
for (i = 0; i < TABLE_SIZE; ++i) for (i = 0; i < TABLE_SIZE; ++i)
@ -32,24 +39,32 @@ void destroy_table(void)
while (e) while (e)
{ {
Entry *next;
IncBusy(); IncBusy();
next = e->next; next = e->next;
destroy_entry(e, true);
TCPIPAbortTCP(e->ipid);
TCPIPLogout(e->ipid);
sdelete(e->semaphore);
free(e);
e = next; e = next;
DecBusy(); DecBusy();
} }
} }
e = dlist;
while (e)
{
next = e->next;
destroy_entry(e, true);
e = next;
}
}
static void destroy_entry(Entry *e, Boolean abort)
{
if (abort) TCPIPAbortTCP(e->ipid);
TCPIPLogout(e->ipid);
sdelete(e->semaphore);
free(e);
} }
Entry *find_entry(Word ipid) Entry *find_entry(Word ipid)
@ -151,6 +166,7 @@ void process_table(void)
switch(command) switch(command)
{ {
case kCommandRead: case kCommandRead:
// block until data available.
if (e->sr.srRcvQueued >= e->cookie if (e->sr.srRcvQueued >= e->cookie
|| expired || expired
|| terr) || terr)
@ -159,7 +175,20 @@ void process_table(void)
} }
break; break;
case kCommandWrite:
// block until data sent.
if (e->sr.srSndQueued <= e->cookie
|| expired
|| terr)
{
sig = 1;
}
break;
case kCommandConnect: case kCommandConnect:
// block until connection established.
if (state >= TCPSESTABLISHED || state == TCPSCLOSED) if (state >= TCPSESTABLISHED || state == TCPSCLOSED)
{ {
sig = 1; sig = 1;
@ -171,6 +200,7 @@ void process_table(void)
break; break;
case kCommandDisconnect: case kCommandDisconnect:
// block until connection closed.
if (state == TCPSCLOSED) if (state == TCPSCLOSED)
{ {
sig = 1; sig = 1;
@ -178,29 +208,24 @@ void process_table(void)
break; break;
case kCommandDisconnectAndLogout: case kCommandDisconnectAndLogout:
// logout and remove entry.
if (expired) // move to other list
// since it's no longer a valid fd
if (prev)
{ {
// sweet 16 link layer? prev->next = next;
TCPIPAbortTCP(e->ipid); }
state = TCPSCLOSED; else
{
table[i] = next;
} }
if (state == TCPSCLOSED || state == TCPSTIMEWAIT) // add to the dlist.
{ e->next = dlist;
TCPIPLogout(e->ipid); dlist = e;
sdelete(e->semaphore); e = NULL;
free(e);
e = NULL;
if (prev)
{
prev->next = next;
}
else
{
table[i] = next;
}
}
break; break;
} }
@ -214,11 +239,46 @@ void process_table(void)
DecBusy(); DecBusy();
} // e->command } // e->command
if (e) prev = e;
e = next; e = next;
} }
} }
// now process the disconnect list.
e = dlist;
prev = NULL;
while (e)
{
next = e->next;
IncBusy();
terr = TCPIPStatusTCP(e->ipid, &e->sr);
t = _toolErr;
if (t) terr = t;
DecBusy();
if (e->sr.srState == TCPSCLOSED)
{
destroy_entry(e, false);
e = NULL;
// remove..
if (prev)
{
prev->next = next;
}
else
{
dlist = next;
}
}
if (e) prev = e;
e = next;
}
} }