diff options
author | Alexander Gottwald <alexander.gottwald@s1999.tu-chemnitz.de> | 2004-11-22 13:23:25 +0000 |
---|---|---|
committer | Alexander Gottwald <alexander.gottwald@s1999.tu-chemnitz.de> | 2004-11-22 13:23:25 +0000 |
commit | 0f7874cbfc01da339cc6be221351ddffdb37805d (patch) | |
tree | c3586ae46745ae4ec477113cb3b604c498459605 /os | |
parent | e6bc551e3451efe4fcbb55475d6d0ff53fcc9807 (diff) |
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
Diffstat (limited to 'os')
-rw-r--r-- | os/WaitFor.c | 2 | ||||
-rw-r--r-- | os/connection.c | 104 | ||||
-rw-r--r-- | os/io.c | 2 | ||||
-rw-r--r-- | os/lbxio.c | 6 | ||||
-rw-r--r-- | os/osdep.h | 8 |
5 files changed, 111 insertions, 11 deletions
diff --git a/os/WaitFor.c b/os/WaitFor.c index 20a8b6c38..e854049ec 100644 --- a/os/WaitFor.c +++ b/os/WaitFor.c @@ -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. diff --git a/os/connection.c b/os/connection.c index 9948ce80c..3ec64c099 100644 --- a/os/connection.c +++ b/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 } @@ -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) diff --git a/os/lbxio.c b/os/lbxio.c index ba79040b5..86ed58800 100644 --- a/os/lbxio.c +++ b/os/lbxio.c @@ -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 diff --git a/os/osdep.h b/os/osdep.h index 4ab988057..38c60c661 100644 --- a/os/osdep.h +++ b/os/osdep.h @@ -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; |