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:
parent
e6bc551e34
commit
0f7874cbfc
|
@ -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.
|
||||
|
|
104
os/connection.c
104
os/connection.c
|
@ -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, ¬ime);
|
||||
if (r < 0)
|
||||
CloseDownClient(clients[ConnectionTranslation[curclient]]);
|
||||
CloseDownClient(clients[GetConnectionTranslation(curclient)]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
2
os/io.c
2
os/io.c
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue
Block a user