Eliminates all of the fd_set mangling in the server main thread Signed-off-by: Keith Packard <kei...@keithp.com> --- dix/dispatch.c | 4 + include/dixstruct.h | 25 ++++ os/WaitFor.c | 157 +++++++------------------ os/connection.c | 333 ++++++++++++++++++++-------------------------------- os/io.c | 101 +++------------- os/osdep.h | 29 ++--- os/osinit.c | 1 - os/xdmcp.c | 1 - 8 files changed, 223 insertions(+), 428 deletions(-)
diff --git a/dix/dispatch.c b/dix/dispatch.c index a61d7a4..51e586f 100644 --- a/dix/dispatch.c +++ b/dix/dispatch.c @@ -242,12 +242,14 @@ void Dispatch(void); static struct xorg_list ready_clients; static struct xorg_list saved_ready_clients; +struct xorg_list output_pending_clients; static void init_client_ready(void) { xorg_list_init(&ready_clients); xorg_list_init(&saved_ready_clients); + xorg_list_init(&output_pending_clients); } Bool @@ -3413,6 +3415,7 @@ CloseDownClient(ClientPtr client) UngrabServer(client); } mark_client_not_ready(client); + xorg_list_del(&client->output_pending); BITCLEAR(grabWaiters, client->index); DeleteClientFromAnySelections(client); ReleaseActiveGrabs(client); @@ -3503,6 +3506,7 @@ InitClient(ClientPtr client, int i, void *ospriv) { client->index = i; xorg_list_init(&client->ready); + xorg_list_init(&client->output_pending); client->clientAsMask = ((Mask) i) << CLIENTOFFSET; client->closeDownMode = i ? DestroyAll : RetainPermanent; client->requestVector = InitialVector; diff --git a/include/dixstruct.h b/include/dixstruct.h index 1f38349..38c649a 100644 --- a/include/dixstruct.h +++ b/include/dixstruct.h @@ -77,6 +77,7 @@ typedef struct _Client { void *requestBuffer; void *osPrivate; /* for OS layer, including scheduler */ struct xorg_list ready; /* List of clients ready to run */ + struct xorg_list output_pending; /* List of clients with output queued */ Mask clientAsMask; short index; unsigned char majorOp, minorOp; @@ -153,6 +154,30 @@ static inline Bool client_is_ready(ClientPtr client) Bool clients_are_ready(void); +extern struct xorg_list output_pending_clients; + +static inline void +output_pending_mark(ClientPtr client) +{ + if (xorg_list_is_empty(&client->output_pending)) + xorg_list_append(&client->output_pending, &output_pending_clients); +} + +static inline void +output_pending_clear(ClientPtr client) +{ + xorg_list_del(&client->output_pending); +} + +static inline Bool any_output_pending(void) { + return !xorg_list_is_empty(&output_pending_clients); +} + +static inline Bool client_output_pending(ClientPtr client) +{ + return !xorg_list_is_empty(&client->output_pending); +} + #define SMART_MAX_PRIORITY (20) #define SMART_MIN_PRIORITY (-20) diff --git a/os/WaitFor.c b/os/WaitFor.c index ef4ebb5..9fdc996 100644 --- a/os/WaitFor.c +++ b/os/WaitFor.c @@ -66,7 +66,6 @@ SOFTWARE. #include "misc.h" #include "osdep.h" -#include <X11/Xpoll.h> #include "dixstruct.h" #include "opaque.h" #ifdef DPMSExtension @@ -146,22 +145,20 @@ Bool WaitForSomething(Bool are_ready) { int i; - struct timeval waittime, *wt; int timeout; - fd_set clientsReadable; - fd_set clientsWritable; - int curclient; - int selecterr; - static int nready; + int pollerr; + static Bool were_ready; + Bool timer_is_running; CARD32 now = 0; - Bool someNotifyWriteReady = FALSE; - FD_ZERO(&clientsReadable); - FD_ZERO(&clientsWritable); + timer_is_running = were_ready; - if (nready) + if (were_ready && !are_ready) { + timer_is_running = FALSE; SmartScheduleStopTimer(); - nready = 0; + } + + were_ready = FALSE; #ifdef BUSFAULT busfault_check(); @@ -176,8 +173,6 @@ WaitForSomething(Bool are_ready) if (are_ready) { timeout = 0; - XFD_COPYSET(&AllSockets, &LastSelectMask); - XFD_UNSET(&LastSelectMask, &ClientsWithInput); } else { timeout = -1; @@ -195,57 +190,39 @@ WaitForSomething(Bool are_ready) timeout = 0; } } - XFD_COPYSET(&AllSockets, &LastSelectMask); } BlockHandler(&timeout); - if (timeout < 0) - wt = NULL; - else { - waittime.tv_sec = timeout / MILLI_PER_SECOND; - waittime.tv_usec = (timeout % MILLI_PER_SECOND) * - (1000000 / MILLI_PER_SECOND); - wt = &waittime; - } if (NewOutputPending) FlushAllOutput(); /* keep this check close to select() call to minimize race */ if (dispatchException) i = -1; - else if (AnyWritesPending) { - XFD_COPYSET(&ClientsWriteBlocked, &LastSelectWriteMask); - XFD_ORSET(&LastSelectWriteMask, &NotifyWriteFds, &LastSelectWriteMask); - i = Select(MaxClients, &LastSelectMask, &LastSelectWriteMask, NULL, wt); - } - else { - i = Select(MaxClients, &LastSelectMask, NULL, NULL, wt); - } - selecterr = GetErrno(); + else + i = ospoll_wait(server_poll, timeout); + pollerr = GetErrno(); WakeupHandler(i); if (i <= 0) { /* An error or timeout occurred */ if (dispatchException) return FALSE; if (i < 0) { - if (selecterr == EBADF) { /* Some client disconnected */ + if (pollerr == EBADF) { /* Some client disconnected */ CheckConnections(); - if (!XFD_ANYSET(&AllClients)) - return FALSE; + return FALSE; } - else if (selecterr == EINVAL) { - FatalError("WaitForSomething(): select: %s\n", - strerror(selecterr)); + else if (pollerr == EINVAL) { + FatalError("WaitForSomething(): poll: %s\n", + strerror(pollerr)); } - else if (selecterr != EINTR && selecterr != EAGAIN) { - ErrorF("WaitForSomething(): select: %s\n", - strerror(selecterr)); + else if (pollerr != EINTR && pollerr != EAGAIN) { + ErrorF("WaitForSomething(): poll: %s\n", + strerror(pollerr)); } } else if (are_ready) { /* * If no-one else is home, bail quickly */ - XFD_COPYSET(&ClientsWithInput, &LastSelectMask); - XFD_COPYSET(&ClientsWithInput, &clientsReadable); break; } if (*checkForInput[0] != *checkForInput[1]) @@ -269,93 +246,39 @@ WaitForSomething(Bool are_ready) } } else { - fd_set tmp_set; - - if (*checkForInput[0] == *checkForInput[1]) { - if (timers) { - int expired = 0; + /* check here for DDXes that queue events during Block/Wakeup */ + if (*checkForInput[0] != *checkForInput[1]) + return FALSE; - now = GetTimeInMillis(); - if ((int) (timers->expires - now) <= 0) - expired = 1; + if (timers) { + int expired = 0; - if (expired) { - OsBlockSignals(); - while (timers && (int) (timers->expires - now) <= 0) - DoTimer(timers, now, &timers); - OsReleaseSignals(); + now = GetTimeInMillis(); + if ((int) (timers->expires - now) <= 0) + expired = 1; - return FALSE; - } - } - } + if (expired) { + OsBlockSignals(); + while (timers && (int) (timers->expires - now) <= 0) + DoTimer(timers, now, &timers); + OsReleaseSignals(); - if (AnyWritesPending) { - XFD_ANDSET(&clientsWritable, &LastSelectWriteMask, &ClientsWriteBlocked); - if (XFD_ANYSET(&clientsWritable)) { - NewOutputPending = TRUE; - XFD_ORSET(&OutputPending, &clientsWritable, &OutputPending); - XFD_UNSET(&ClientsWriteBlocked, &clientsWritable); - if (!XFD_ANYSET(&ClientsWriteBlocked) && NumNotifyWriteFd == 0) - AnyWritesPending = FALSE; - } - if (NumNotifyWriteFd != 0) { - XFD_ANDSET(&tmp_set, &LastSelectWriteMask, &NotifyWriteFds); - if (XFD_ANYSET(&tmp_set)) - someNotifyWriteReady = TRUE; + return FALSE; } } - XFD_ANDSET(&clientsReadable, &LastSelectMask, &AllClients); - - XFD_ANDSET(&tmp_set, &LastSelectMask, &NotifyReadFds); - if (XFD_ANYSET(&tmp_set) || someNotifyWriteReady) - HandleNotifyFds(); - - if (are_ready || XFD_ANYSET(&clientsReadable)) + are_ready = clients_are_ready(); + if (are_ready) break; - - /* check here for DDXes that queue events during Block/Wakeup */ - if (*checkForInput[0] != *checkForInput[1]) - return FALSE; } } - nready = 0; - if (XFD_ANYSET(&clientsReadable)) { -#ifndef WIN32 - for (i = 0; i < howmany(XFD_SETSIZE, NFDBITS); i++) { - while (clientsReadable.fds_bits[i]) { - int client_index; - - curclient = mffs(clientsReadable.fds_bits[i]) - 1; - client_index = /* raphael: modified */ - ConnectionTranslation[curclient + - (i * (sizeof(fd_mask) * 8))]; -#else - fd_set savedClientsReadable; - - XFD_COPYSET(&clientsReadable, &savedClientsReadable); - for (i = 0; i < XFD_SETCOUNT(&savedClientsReadable); i++) { - int client_priority, client_index; - - curclient = XFD_FD(&savedClientsReadable, i); - client_index = GetConnectionTranslation(curclient); -#endif - nready++; - mark_client_ready(clients[client_index]); -#ifndef WIN32 - clientsReadable.fds_bits[i] &= ~(((fd_mask) 1L) << curclient); - } -#else - FD_CLR(curclient, &clientsReadable); -#endif - } + if (are_ready) { + were_ready = TRUE; + if (!timer_is_running) + SmartScheduleStartTimer(); } - if (nready) - SmartScheduleStartTimer(); - return TRUE; } diff --git a/os/connection.c b/os/connection.c index d4e367a..1ae50b1 100644 --- a/os/connection.c +++ b/os/connection.c @@ -120,20 +120,10 @@ SOFTWARE. #include "probes.h" static int lastfdesc; /* maximum file descriptor */ +struct ospoll *server_poll; -fd_set NotifyReadFds; /* mask for other file descriptors */ -fd_set NotifyWriteFds; /* mask for other write file descriptors */ -fd_set AllSockets; /* select on this */ -fd_set AllClients; /* available clients */ -fd_set LastSelectMask; /* mask returned from last select call */ -fd_set LastSelectWriteMask; /* mask returned from last select call */ -fd_set ClientsWithInput; /* clients with FULL requests in buffer */ -fd_set ClientsWriteBlocked; /* clients who cannot receive output */ -fd_set OutputPending; /* clients with reply/event data ready to go */ int MaxClients = 0; -int NumNotifyWriteFd; /* Number of NotifyFd members with write set */ Bool NewOutputPending; /* not yet attempted to write some new output */ -Bool AnyWritesPending; /* true if some client blocked on write or NotifyFd with write */ Bool NoListenAll; /* Don't establish any listening sockets */ static Bool RunFromSmartParent; /* send SIGUSR1 to parent process */ @@ -145,16 +135,17 @@ static Pid_t ParentProcess; static Bool debug_conns = FALSE; -fd_set IgnoredClientsWithInput; -static fd_set GrabImperviousClients; -static fd_set SavedAllClients; -static fd_set SavedAllSockets; -static fd_set SavedClientsWithInput; int GrabInProgress = 0; static void QueueNewConnections(int curconn, int ready, void *data); +static void +set_poll_client(ClientPtr client); + +static void +set_poll_clients(void); + #if !defined(WIN32) int *ConnectionTranslation = NULL; #else @@ -392,10 +383,9 @@ CreateWellKnownSockets(void) int i; int partial; - FD_ZERO(&AllSockets); - FD_ZERO(&AllClients); - FD_ZERO(&LastSelectMask); - FD_ZERO(&ClientsWithInput); + server_poll = ospoll_create(); + if (!server_poll) + FatalError("failed to allocate poll structure"); #if !defined(WIN32) for (i = 0; i < MaxClients; i++) @@ -751,6 +741,21 @@ ClientAuthorized(ClientPtr client, return ((char *) NULL); } +static void +ClientReady(int fd, short revents, void *data) +{ + ClientPtr client = data; + + if (revents & ~(POLLIN|POLLOUT)) { + CloseDownClient(client); + return; + } + if (revents & POLLIN) + mark_client_ready(client); + if (revents & POLLOUT) + NewOutputPending = TRUE; +} + static ClientPtr AllocNewConnection(XtransConnInfo trans_conn, int fd, CARD32 conn_time) { @@ -774,6 +779,7 @@ AllocNewConnection(XtransConnInfo trans_conn, int fd, CARD32 conn_time) oc->output = (ConnectionOutputPtr) NULL; oc->auth_id = None; oc->conn_time = conn_time; + oc->flags = 0; if (!(client = NextAvailableClient((void *) oc))) { free(oc); return NullClient; @@ -784,14 +790,11 @@ AllocNewConnection(XtransConnInfo trans_conn, int fd, CARD32 conn_time) #else SetConnectionTranslation(fd, client->index); #endif - if (GrabInProgress) { - FD_SET(fd, &SavedAllClients); - FD_SET(fd, &SavedAllSockets); - } - else { - FD_SET(fd, &AllClients); - FD_SET(fd, &AllSockets); - } + ospoll_add(server_poll, fd, + ospoll_trigger_edge, + ClientReady, + client); + set_poll_client(client); #ifdef DEBUG ErrorF("AllocNewConnection: client index = %d, socket fd = %d\n", @@ -940,19 +943,7 @@ CloseDownFileDescriptor(OsCommPtr oc) #else SetConnectionTranslation(connection, 0); #endif - FD_CLR(connection, &AllSockets); - FD_CLR(connection, &AllClients); - FD_CLR(connection, &ClientsWithInput); - FD_CLR(connection, &GrabImperviousClients); - if (GrabInProgress) { - FD_CLR(connection, &SavedAllSockets); - FD_CLR(connection, &SavedAllClients); - FD_CLR(connection, &SavedClientsWithInput); - } - FD_CLR(connection, &ClientsWriteBlocked); - if (!XFD_ANYSET(&ClientsWriteBlocked) && NumNotifyWriteFd == 0) - AnyWritesPending = FALSE; - FD_CLR(connection, &OutputPending); + ospoll_remove(server_poll, connection); } /***************** @@ -967,53 +958,25 @@ CloseDownFileDescriptor(OsCommPtr oc) void CheckConnections(void) { -#ifndef WIN32 - fd_mask mask; -#endif - fd_set tmask; - int curclient, curoff; int i; - struct timeval notime; int r; -#ifdef WIN32 - fd_set savedAllClients; -#endif + for (i = 1; i < currentMaxClients; i++) { + ClientPtr client = clients[i]; + if (!client->clientGone) { + OsCommPtr oc = (OsCommPtr) client->osPrivate; + struct pollfd poll_fd; - notime.tv_sec = 0; - notime.tv_usec = 0; + poll_fd.fd = oc->fd; + poll_fd.events = POLLIN|POLLOUT; -#ifndef WIN32 - for (i = 0; i < howmany(XFD_SETSIZE, NFDBITS); i++) { - mask = AllClients.fds_bits[i]; - while (mask) { - curoff = mffs(mask) - 1; - curclient = curoff + (i * (sizeof(fd_mask) * 8)); - FD_ZERO(&tmask); - FD_SET(curclient, &tmask); do { - r = Select(curclient + 1, &tmask, NULL, NULL, ¬ime); + r = poll(&poll_fd, 1, 0); } while (r < 0 && (errno == EINTR || errno == EAGAIN)); if (r < 0) - if (ConnectionTranslation[curclient] > 0) - CloseDownClient(clients[ConnectionTranslation[curclient]]); - mask &= ~((fd_mask) 1 << curoff); + CloseDownClient(client); } } -#else - XFD_COPYSET(&AllClients, &savedAllClients); - for (i = 0; i < XFD_SETCOUNT(&savedAllClients); i++) { - curclient = XFD_FD(&savedAllClients, i); - FD_ZERO(&tmask); - FD_SET(curclient, &tmask); - do { - r = Select(curclient + 1, &tmask, NULL, NULL, ¬ime); - } while (r < 0 && (errno == EINTR || errno == EAGAIN)); - if (r < 0) - if (GetConnectionTranslation(curclient) > 0) - CloseDownClient(clients[GetConnectionTranslation(curclient)]); - } -#endif } /***************** @@ -1043,28 +1006,28 @@ CloseDownConnection(ClientPtr client) } struct notify_fd { - struct xorg_list list; - int fd; int mask; NotifyFdProcPtr notify; void *data; }; -static struct xorg_list notify_fds; +/***************** + * HandleNotifyFd + * A poll callback to be called when the registered + * file descriptor is ready. + *****************/ -void -InitNotifyFds(void) +static void +HandleNotifyFd(int fd, short revents, void *data) { - struct notify_fd *s, *next; - static int been_here; - - if (been_here) - xorg_list_for_each_entry_safe(s, next, ¬ify_fds, list) - RemoveNotifyFd(s->fd); - - xorg_list_init(¬ify_fds); - NumNotifyWriteFd = 0; - been_here = 1; + struct notify_fd *n = data; + int ready = 0; + if (n->mask & X_NOTIFY_READ && (revents & POLLIN)) + ready |= X_NOTIFY_READ; + if (n->mask & X_NOTIFY_WRITE && (revents & POLLOUT)) + ready |= X_NOTIFY_WRITE; + if (ready != 0) + n->notify(fd, ready, n->data); } /***************** @@ -1079,52 +1042,40 @@ SetNotifyFd(int fd, NotifyFdProcPtr notify, int mask, void *data) struct notify_fd *n; int changes; - xorg_list_for_each_entry(n, ¬ify_fds, list) - if (n->fd == fd) - break; - - if (&n->list == ¬ify_fds) { + n = ospoll_data(server_poll, fd); + if (!n) { if (mask == 0) return TRUE; n = calloc(1, sizeof (struct notify_fd)); if (!n) return FALSE; - n->fd = fd; - xorg_list_add(&n->list, ¬ify_fds); + ospoll_add(server_poll, fd, + ospoll_trigger_level, + HandleNotifyFd, + n); } changes = n->mask ^ mask; if (changes & X_NOTIFY_READ) { if (mask & X_NOTIFY_READ) { - FD_SET(fd, &NotifyReadFds); - FD_SET(fd, &AllSockets); - if (GrabInProgress) - FD_SET(fd, &SavedAllSockets); + ospoll_listen(server_poll, fd, POLLIN); } else { - FD_CLR(fd, &AllSockets); - if (GrabInProgress) - FD_CLR(fd, &SavedAllSockets); - FD_CLR(fd, &NotifyReadFds); + ospoll_mute(server_poll, fd, POLLIN); } } if (changes & X_NOTIFY_WRITE) { if (mask & X_NOTIFY_WRITE) { - FD_SET(fd, &NotifyWriteFds); - if (!NumNotifyWriteFd++) - AnyWritesPending = TRUE; + ospoll_listen(server_poll, fd, POLLOUT); } else { - FD_CLR(fd, &NotifyWriteFds); - if (!--NumNotifyWriteFd) - if (!XFD_ANYSET(&ClientsWriteBlocked)) - AnyWritesPending = FALSE; + ospoll_mute(server_poll, fd, POLLOUT); } } if (mask == 0) { - xorg_list_del(&n->list); + ospoll_remove(server_poll, fd); free(n); } else { n->mask = mask; @@ -1136,28 +1087,6 @@ SetNotifyFd(int fd, NotifyFdProcPtr notify, int mask, void *data) } /***************** - * HandlNotifyFds - * A WorkProc to be called when any of the registered - * file descriptors are readable. - *****************/ - -void -HandleNotifyFds(void) -{ - struct notify_fd *n, *next; - - xorg_list_for_each_entry_safe(n, next, ¬ify_fds, list) { - int ready = 0; - if ((n->mask & X_NOTIFY_READ) && FD_ISSET(n->fd, &LastSelectMask)) - ready |= X_NOTIFY_READ; - if ((n->mask & X_NOTIFY_WRITE) & FD_ISSET(n->fd, &LastSelectWriteMask)) - ready |= X_NOTIFY_WRITE; - if (ready != 0) - n->notify(n->fd, ready, n->data); - } -} - -/***************** * OnlyListenToOneClient: * Only accept requests from one client. Continue to handle new * connections, but don't take any protocol requests from the new @@ -1170,30 +1099,17 @@ HandleNotifyFds(void) int OnlyListenToOneClient(ClientPtr client) { - OsCommPtr oc = (OsCommPtr) client->osPrivate; - int rc, connection = oc->fd; + int rc; rc = XaceHook(XACE_SERVER_ACCESS, client, DixGrabAccess); if (rc != Success) return rc; if (!GrabInProgress) { - XFD_COPYSET(&ClientsWithInput, &SavedClientsWithInput); - XFD_ANDSET(&ClientsWithInput, - &ClientsWithInput, &GrabImperviousClients); - if (FD_ISSET(connection, &SavedClientsWithInput)) { - FD_CLR(connection, &SavedClientsWithInput); - FD_SET(connection, &ClientsWithInput); - } - XFD_UNSET(&SavedClientsWithInput, &GrabImperviousClients); - XFD_COPYSET(&AllSockets, &SavedAllSockets); - XFD_COPYSET(&AllClients, &SavedAllClients); - XFD_UNSET(&AllSockets, &AllClients); - XFD_ANDSET(&AllClients, &AllClients, &GrabImperviousClients); - FD_SET(connection, &AllClients); - XFD_ORSET(&AllSockets, &AllSockets, &AllClients); GrabInProgress = client->index; + set_poll_clients(); } + return rc; } @@ -1206,10 +1122,8 @@ void ListenToAllClients(void) { if (GrabInProgress) { - XFD_ORSET(&AllSockets, &AllSockets, &SavedAllSockets); - XFD_ORSET(&AllClients, &AllClients, &SavedAllClients); - XFD_ORSET(&ClientsWithInput, &ClientsWithInput, &SavedClientsWithInput); GrabInProgress = 0; + set_poll_clients(); } } @@ -1223,7 +1137,6 @@ void IgnoreClient(ClientPtr client) { OsCommPtr oc = (OsCommPtr) client->osPrivate; - int connection = oc->fd; client->ignoreCount++; if (client->ignoreCount > 1) @@ -1231,25 +1144,9 @@ IgnoreClient(ClientPtr client) isItTimeToYield = TRUE; mark_client_not_ready(client); - if (!GrabInProgress || FD_ISSET(connection, &AllClients)) { - if (FD_ISSET(connection, &ClientsWithInput)) - FD_SET(connection, &IgnoredClientsWithInput); - else - FD_CLR(connection, &IgnoredClientsWithInput); - FD_CLR(connection, &ClientsWithInput); - FD_CLR(connection, &AllSockets); - FD_CLR(connection, &AllClients); - FD_CLR(connection, &LastSelectMask); - } - else { - if (FD_ISSET(connection, &SavedClientsWithInput)) - FD_SET(connection, &IgnoredClientsWithInput); - else - FD_CLR(connection, &IgnoredClientsWithInput); - FD_CLR(connection, &SavedClientsWithInput); - FD_CLR(connection, &SavedAllSockets); - FD_CLR(connection, &SavedAllClients); - } + + oc->flags |= OS_COMM_IGNORED; + set_poll_client(client); } /**************** @@ -1261,28 +1158,15 @@ void AttendClient(ClientPtr client) { OsCommPtr oc = (OsCommPtr) client->osPrivate; - int connection = oc->fd; client->ignoreCount--; if (client->ignoreCount) return; - if (!GrabInProgress || GrabInProgress == client->index || - FD_ISSET(connection, &GrabImperviousClients)) { - FD_SET(connection, &AllClients); - FD_SET(connection, &AllSockets); - FD_SET(connection, &LastSelectMask); - if (FD_ISSET(connection, &IgnoredClientsWithInput)) { - FD_SET(connection, &ClientsWithInput); - mark_client_ready(client); - } - } - else { - FD_SET(connection, &SavedAllClients); - FD_SET(connection, &SavedAllSockets); - if (FD_ISSET(connection, &IgnoredClientsWithInput)) - FD_SET(connection, &SavedClientsWithInput); - } + oc->flags &= ~OS_COMM_IGNORED; + set_poll_client(client); + if (listen_to_client(client)) + mark_client_ready(client); } /* make client impervious to grabs; assume only executing client calls this */ @@ -1291,9 +1175,9 @@ void MakeClientGrabImpervious(ClientPtr client) { OsCommPtr oc = (OsCommPtr) client->osPrivate; - int connection = oc->fd; - FD_SET(connection, &GrabImperviousClients); + oc->flags |= OS_COMM_GRAB_IMPERVIOUS; + set_poll_client(client); if (ServerGrabCallback) { ServerGrabInfoRec grabinfo; @@ -1310,18 +1194,10 @@ void MakeClientGrabPervious(ClientPtr client) { OsCommPtr oc = (OsCommPtr) client->osPrivate; - int connection = oc->fd; - FD_CLR(connection, &GrabImperviousClients); - if (GrabInProgress && (GrabInProgress != client->index)) { - if (FD_ISSET(connection, &ClientsWithInput)) { - FD_SET(connection, &SavedClientsWithInput); - FD_CLR(connection, &ClientsWithInput); - } - FD_CLR(connection, &AllSockets); - FD_CLR(connection, &AllClients); - isItTimeToYield = TRUE; - } + oc->flags &= ~OS_COMM_GRAB_IMPERVIOUS; + set_poll_client(client); + isItTimeToYield = TRUE; if (ServerGrabCallback) { ServerGrabInfoRec grabinfo; @@ -1404,3 +1280,46 @@ AddClientOnOpenFD(int fd) return TRUE; } + +Bool +listen_to_client(ClientPtr client) +{ + OsCommPtr oc = (OsCommPtr) client->osPrivate; + + if (oc->flags & OS_COMM_IGNORED) + return FALSE; + + if (!GrabInProgress) + return TRUE; + + if (client->index == GrabInProgress) + return TRUE; + + if (oc->flags & OS_COMM_GRAB_IMPERVIOUS) + return TRUE; + + return FALSE; +} + +static void +set_poll_client(ClientPtr client) +{ + OsCommPtr oc = (OsCommPtr) client->osPrivate; + + if (listen_to_client(client)) + ospoll_listen(server_poll, oc->fd, POLLIN); + else + ospoll_mute(server_poll, oc->fd, POLLIN); +} + +static void +set_poll_clients(void) +{ + int i; + + for (i = 1; i < currentMaxClients; i++) { + ClientPtr client = clients[i]; + if (client && !client->clientGone) + set_poll_client(client); + } +} diff --git a/os/io.c b/os/io.c index d04ebd8..75fe6e3 100644 --- a/os/io.c +++ b/os/io.c @@ -74,7 +74,6 @@ SOFTWARE. #include <X11/Xproto.h> #include "os.h" #include "osdep.h" -#include <X11/Xpoll.h> #include "opaque.h" #include "dixstruct.h" #include "misc.h" @@ -202,7 +201,7 @@ static void YieldControlNoInput(int fd) { YieldControl(); - FD_CLR(fd, &ClientsWithInput); + ospoll_reset_events(server_poll, fd); } static void @@ -452,24 +451,8 @@ ReadRequestFromClient(ClientPtr client) */ gotnow -= needed; - if (gotnow >= sizeof(xReq)) { - request = (xReq *) (oci->bufptr + needed); - if (gotnow >= (result = (get_req_len(request, client) << 2)) - && (result || - (client->big_requests && - (gotnow >= sizeof(xBigReq) && - gotnow >= (get_big_req_len(request, client) << 2)))) - ) - FD_SET(fd, &ClientsWithInput); - else { - FD_CLR(fd, &ClientsWithInput); - } - } - else { - if (!gotnow) - AvailableInput = oc; - FD_CLR(fd, &ClientsWithInput); - } + if (!gotnow) + AvailableInput = oc; if (move_header) { request = (xReq *) oci->bufptr; oci->bufptr += (sizeof(xBigReq) - sizeof(xReq)); @@ -562,7 +545,7 @@ InsertFakeRequest(ClientPtr client, char *data, int count) gotnow += count; if ((gotnow >= sizeof(xReq)) && (gotnow >= (int) (get_req_len((xReq *) oci->bufptr, client) << 2))) - FD_SET(fd, &ClientsWithInput); + mark_client_ready(client); else YieldControlNoInput(fd); return TRUE; @@ -602,12 +585,8 @@ ResetCurrentRequest(ClientPtr client) } } if (gotnow >= (needed << 2)) { - if (FD_ISSET(fd, &AllClients)) { - FD_SET(fd, &ClientsWithInput); - } - else { - FD_SET(fd, &IgnoredClientsWithInput); - } + if (listen_to_client(client)) + mark_client_ready(client); YieldControl(); } else @@ -628,16 +607,10 @@ ResetCurrentRequest(ClientPtr client) void FlushAllOutput(void) { - register int index, base; - register fd_mask mask; /* raphael */ OsCommPtr oc; - register ClientPtr client; + register ClientPtr client, tmp; Bool newoutput = NewOutputPending; -#if defined(WIN32) - fd_set newOutputPending; -#endif - if (FlushCallback) CallCallbacks(&FlushCallback, NULL); @@ -652,48 +625,14 @@ FlushAllOutput(void) CriticalOutputPending = FALSE; NewOutputPending = FALSE; -#ifndef WIN32 - for (base = 0; base < howmany(XFD_SETSIZE, NFDBITS); base++) { - mask = OutputPending.fds_bits[base]; - OutputPending.fds_bits[base] = 0; - while (mask) { - index = ffs(mask) - 1; - mask &= ~lowbit(mask); - if ((index = - ConnectionTranslation[(base * (sizeof(fd_mask) * 8)) + - index]) == 0) - continue; - client = clients[index]; - if (client->clientGone) - continue; - oc = (OsCommPtr) client->osPrivate; - if (FD_ISSET(oc->fd, &ClientsWithInput)) { - FD_SET(oc->fd, &OutputPending); /* set the bit again */ - NewOutputPending = TRUE; - } - else - (void) FlushClient(client, oc, (char *) NULL, 0); - } - } -#else /* WIN32 */ - FD_ZERO(&newOutputPending); - for (base = 0; base < XFD_SETCOUNT(&OutputPending); base++) { - index = XFD_FD(&OutputPending, base); - if ((index = GetConnectionTranslation(index)) == 0) - continue; - client = clients[index]; + xorg_list_for_each_entry_safe(client, tmp, &output_pending_clients, output_pending) { if (client->clientGone) continue; - oc = (OsCommPtr) client->osPrivate; - if (FD_ISSET(oc->fd, &ClientsWithInput)) { - FD_SET(oc->fd, &newOutputPending); /* set the bit again */ - NewOutputPending = TRUE; - } - else + if (!client_is_ready(client)) { + oc = (OsCommPtr) client->osPrivate; (void) FlushClient(client, oc, (char *) NULL, 0); + } } - XFD_COPYSET(&newOutputPending, &OutputPending); -#endif /* WIN32 */ } void @@ -835,8 +774,8 @@ WriteToClient(ClientPtr who, int count, const void *__buf) } #endif if (oco->count == 0 || oco->count + count + padBytes > oco->size) { - FD_CLR(oc->fd, &OutputPending); - if (!XFD_ANYSET(&OutputPending)) { + output_pending_clear(who); + if (!any_output_pending()) { CriticalOutputPending = FALSE; NewOutputPending = FALSE; } @@ -848,7 +787,7 @@ WriteToClient(ClientPtr who, int count, const void *__buf) } NewOutputPending = TRUE; - FD_SET(oc->fd, &OutputPending); + output_pending_mark(who); memmove((char *) oco->buf + oco->count, buf, count); oco->count += count; if (padBytes) { @@ -872,7 +811,6 @@ int FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount) { ConnectionOutputPtr oco = oc->output; - int connection = oc->fd; XtransConnInfo trans_conn = oc->trans_conn; struct iovec iov[3]; static char padBuffer[3]; @@ -945,8 +883,7 @@ FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount) /* If we've arrived here, then the client is stuffed to the gills and not ready to accept more. Make a note of it and buffer the rest. */ - FD_SET(connection, &ClientsWriteBlocked); - AnyWritesPending = TRUE; + output_pending_mark(who); if (written < oco->count) { if (written > 0) { @@ -1008,12 +945,8 @@ FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount) /* everything was flushed out */ oco->count = 0; - /* check to see if this client was write blocked */ - if (AnyWritesPending) { - FD_CLR(oc->fd, &ClientsWriteBlocked); - if (!XFD_ANYSET(&ClientsWriteBlocked) && NumNotifyWriteFd == 0) - AnyWritesPending = FALSE; - } + output_pending_clear(who); + if (oco->size > BUFWATERMARK) { free(oco->buf); free(oco); diff --git a/os/osdep.h b/os/osdep.h index 3dc2daf..d44df76 100644 --- a/os/osdep.h +++ b/os/osdep.h @@ -63,6 +63,8 @@ SOFTWARE. #undef _POSIX_SOURCE #endif +#include <poll.h> + #ifndef OPEN_MAX #ifdef SVR4 #define OPEN_MAX 512 @@ -148,8 +150,12 @@ typedef struct _osComm { XID auth_id; /* authorization id */ CARD32 conn_time; /* timestamp if not established, else 0 */ struct _XtransConnInfo *trans_conn; /* transport connection object */ + int flags; } OsCommRec, *OsCommPtr; +#define OS_COMM_GRAB_IMPERVIOUS 1 +#define OS_COMM_IGNORED 2 + extern int FlushClient(ClientPtr /*who */ , OsCommPtr /*oc */ , const void * /*extraBuf */ , @@ -159,24 +165,13 @@ extern int FlushClient(ClientPtr /*who */ , extern void FreeOsBuffers(OsCommPtr /*oc */ ); -extern void InitNotifyFds(void); - -extern void HandleNotifyFds(void); - #include "dix.h" +#include "ospoll.h" + +extern struct ospoll *server_poll; -extern fd_set AllSockets; -extern fd_set AllClients; -extern fd_set LastSelectMask; -extern fd_set LastSelectWriteMask; -extern fd_set WellKnownConnections; -extern fd_set EnabledDevices; -extern fd_set NotifyReadFds; -extern fd_set NotifyWriteFds; -extern fd_set ClientsWithInput; -extern fd_set ClientsWriteBlocked; -extern fd_set OutputPending; -extern fd_set IgnoredClientsWithInput; +Bool +listen_to_client(ClientPtr client); #if !defined(WIN32) || defined(__CYGWIN__) extern int *ConnectionTranslation; @@ -187,8 +182,6 @@ extern void ClearConnectionTranslation(void); #endif extern Bool NewOutputPending; -extern Bool AnyWritesPending; -extern Bool NumNotifyWriteFd; extern WorkQueuePtr workQueue; diff --git a/os/osinit.c b/os/osinit.c index 54b39a0..6ec2f11 100644 --- a/os/osinit.c +++ b/os/osinit.c @@ -314,7 +314,6 @@ OsInit(void) LockServer(); been_here = TRUE; } - InitNotifyFds(); TimerInit(); OsVendorInit(); OsResetSignals(); diff --git a/os/xdmcp.c b/os/xdmcp.c index 2cb8d76..906c959 100644 --- a/os/xdmcp.c +++ b/os/xdmcp.c @@ -39,7 +39,6 @@ #include <X11/X.h> #include <X11/Xmd.h> #include "misc.h" -#include <X11/Xpoll.h> #include "osdep.h" #include "input.h" #include "dixstruct.h" -- 2.8.0.rc3 _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel