Use a simple hashtable as ConnectionTranslation instead of a plain array on

Windows because socket fds are not sequential and do not start at 0
This commit is contained in:
Alexander Gottwald 2004-11-22 13:23:25 +00:00
parent e6bc551e34
commit 0f7874cbfc
5 changed files with 111 additions and 11 deletions

View File

@ -376,7 +376,7 @@ WaitForSomething(int *pClientsReady)
int client_priority, client_index;
curclient = XFD_FD(&savedClientsReadable, i);
client_index = ConnectionTranslation[curclient];
client_index = GetConnectionTranslation(curclient);
#endif
#ifdef XSYNC
/* We implement "strict" priorities.

View File

@ -194,19 +194,97 @@ static fd_set SavedAllSockets;
static fd_set SavedClientsWithInput;
int GrabInProgress = 0;
#if !defined(WIN32)
int *ConnectionTranslation = NULL;
#if defined(WIN32)
/* SPAM ALERT !!!
#else
/*
* On NT fds are not between 0 and MAXSOCKS, they are unrelated, and there is
* not even a known maximum value, so use something quite arbitrary for now.
* This is clearly boggus and another form of storage which doesn't use the fd
* as a direct index should really be implemented for NT.
* Do storage is a hash table of size 256. Collisions are handled in a linked
* list.
*/
#undef MAXSOCKS
#define MAXSOCKS 500
#undef MAXSELECT
#define MAXSELECT 500
#define MAXFD 500
struct _ct_node {
struct _ct_node *next;
int key;
int value;
};
struct _ct_node *ct_head[256];
void InitConnectionTranslation(void)
{
bzero(ct_head, sizeof(ct_head));
}
int GetConnectionTranslation(int conn)
{
struct _ct_node *node = ct_head[conn & 0xff];
while (node != NULL)
{
if (node->key == conn)
return node->value;
node = node->next;
}
return 0;
}
void SetConnectionTranslation(int conn, int client)
{
struct _ct_node **node = ct_head + (conn & 0xff);
if (client == 0) /* remove entry */
{
while (*node != NULL)
{
if ((*node)->key == conn)
{
struct _ct_node *temp = *node;
*node = (*node)->next;
free(temp);
return;
}
node = &((*node)->next);
}
return;
} else
{
while (*node != NULL)
{
if ((*node)->key == conn)
{
(*node)->value = client;
return;
}
node = &((*node)->next);
}
*node = (struct _ct_node*)xalloc(sizeof(struct _ct_node));
(*node)->next = NULL;
(*node)->key = conn;
(*node)->value = client;
return;
}
}
void ClearConnectionTranslation(void)
{
unsigned i;
for (i = 0; i < 256; i++)
{
struct _ct_node *node = ct_head[i];
while (node != NULL)
{
struct _ct_node *temp = node;
node = node->next;
xfree(temp);
}
}
}
#endif
XtransConnInfo *ListenTransConns = NULL;
@ -290,7 +368,7 @@ InitConnectionLimits(void)
#if !defined(WIN32)
ConnectionTranslation = (int *)xnfalloc(sizeof(int)*(lastfdesc + 1));
#else
ConnectionTranslation = (int *)xnfalloc(sizeof(int)*(MAXFD));
InitConnectionTranslation();
#endif
}
@ -316,7 +394,7 @@ CreateWellKnownSockets(void)
#if !defined(WIN32)
for (i=0; i<MaxClients; i++) ConnectionTranslation[i] = 0;
#else
for (i=0; i<MAXFD; i++) ConnectionTranslation[i] = 0;
ClearConnectionTranslation();
#endif
FD_ZERO (&WellKnownConnections);
@ -759,7 +837,11 @@ AllocNewConnection (XtransConnInfo trans_conn, int fd, CARD32 conn_time)
if (trans_conn)
#endif
{
#if !defined(WIN32)
ConnectionTranslation[fd] = client->index;
#else
SetConnectionTranslation(fd, client->index);
#endif
if (GrabInProgress)
{
FD_SET(fd, &SavedAllClients);
@ -880,7 +962,11 @@ EstablishNewConnections(ClientPtr clientUnused, pointer closure)
if (newconn < lastfdesc)
{
int clientid;
#if !defined(WIN32)
clientid = ConnectionTranslation[newconn];
#else
clientid = GetConnectionTranslation(newconn);
#endif
if(clientid && (client = clients[clientid]))
CloseDownClient(client);
}
@ -982,7 +1068,11 @@ CloseDownFileDescriptor(OsCommPtr oc)
FreeOsBuffers(oc);
xfree(oc);
#endif
#ifndef WIN32
ConnectionTranslation[connection] = 0;
#else
SetConnectionTranslation(connection, 0);
#endif
FD_CLR(connection, &AllSockets);
FD_CLR(connection, &AllClients);
FD_CLR(connection, &ClientsWithInput);
@ -1051,7 +1141,7 @@ CheckConnections(void)
FD_SET(curclient, &tmask);
r = Select (curclient + 1, &tmask, NULL, NULL, &notime);
if (r < 0)
CloseDownClient(clients[ConnectionTranslation[curclient]]);
CloseDownClient(clients[GetConnectionTranslation(curclient)]);
}
#endif
}

View File

@ -864,7 +864,7 @@ FlushAllOutput(void)
for (base = 0; base < XFD_SETCOUNT(&OutputPending); base++)
{
index = XFD_FD(&OutputPending, base);
if ((index = ConnectionTranslation[index]) == 0)
if ((index = GetConnectionTranslation(index)) == 0)
continue;
client = clients[index];
if (client->clientGone)

View File

@ -100,8 +100,12 @@ void
SwitchClientInput (ClientPtr client, Bool pending)
{
OsCommPtr oc = (OsCommPtr)client->osPrivate;
#ifndef WIN32
ConnectionTranslation[oc->fd] = client->index;
#else
SetConnectionTranslation(oc->fd, client->index);
#endif
if (pending)
FD_SET(oc->fd, &ClientsWithInput);
else

View File

@ -245,8 +245,14 @@ extern fd_set ClientsWithInput;
extern fd_set ClientsWriteBlocked;
extern fd_set OutputPending;
extern fd_set IgnoredClientsWithInput;
#ifndef WIN32
extern int *ConnectionTranslation;
#else
extern int GetConnectionTranslation(int conn);
extern void SetConnectionTranslation(int conn, int client);
extern void ClearConnectionTranslation();
#endif
extern Bool NewOutputPending;
extern Bool AnyClientsWriteBlocked;