summaryrefslogtreecommitdiff
path: root/os
diff options
context:
space:
mode:
Diffstat (limited to 'os')
-rw-r--r--os/WaitFor.c2
-rw-r--r--os/connection.c104
-rw-r--r--os/io.c2
-rw-r--r--os/lbxio.c6
-rw-r--r--os/osdep.h8
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, &notime);
if (r < 0)
- CloseDownClient(clients[ConnectionTranslation[curclient]]);
+ CloseDownClient(clients[GetConnectionTranslation(curclient)]);
}
#endif
}
diff --git a/os/io.c b/os/io.c
index 75aebcb5e..1da494254 100644
--- a/os/io.c
+++ b/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)
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;