This gets rid of all of the fd_set masks used while the server is running. Signed-off-by: Keith Packard <kei...@keithp.com> --- dix/dispatch.c | 4 ++ include/dixstruct.h | 29 ++++++++ os/WaitFor.c | 1 - os/connection.c | 198 ++++------------------------------------------------ os/io.c | 100 +++++--------------------- os/osdep.h | 16 +---- os/xdmcp.c | 1 - 7 files changed, 66 insertions(+), 283 deletions(-)
diff --git a/dix/dispatch.c b/dix/dispatch.c index e3dc9b2..9ec347a 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); } static 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 ada45bd..ed3abc7 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 */ Mask clientAsMask; short index; unsigned char majorOp, minorOp; @@ -145,6 +146,34 @@ void mark_client_ready(ClientPtr client); /* Client has no requests queued and no data on network */ void mark_client_not_ready(ClientPtr client); +static inline Bool client_is_ready(ClientPtr client) +{ + return !xorg_list_is_empty(&client->ready); +} + +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 eff2f70..a709859 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 diff --git a/os/connection.c b/os/connection.c index edf1764..be82610 100644 --- a/os/connection.c +++ b/os/connection.c @@ -124,19 +124,9 @@ static int lastfdesc; /* maximum file descriptor */ struct pollfd *poll_fds; int poll_fds_num; -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 */ @@ -148,11 +138,6 @@ 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 @@ -402,10 +387,6 @@ CreateWellKnownSockets(void) int partial; poll_fd_init(); - FD_ZERO(&AllSockets); - FD_ZERO(&AllClients); - FD_ZERO(&LastSelectMask); - FD_ZERO(&ClientsWithInput); #if !defined(WIN32) for (i = 0; i < MaxClients; i++) @@ -798,15 +779,6 @@ AllocNewConnection(XtransConnInfo trans_conn, int fd, CARD32 conn_time) poll_fd_add(fd); set_poll_client(client); - if (GrabInProgress) { - FD_SET(fd, &SavedAllClients); - FD_SET(fd, &SavedAllSockets); - } - else { - FD_SET(fd, &AllClients); - FD_SET(fd, &AllSockets); - } - #ifdef DEBUG ErrorF("AllocNewConnection: client index = %d, socket fd = %d\n", client->index, fd); @@ -959,19 +931,6 @@ CloseDownFileDescriptor(OsCommPtr oc) SetConnectionTranslation(connection, 0); #endif poll_fd_remove(connection); - 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); } /***************** @@ -986,53 +945,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 } /***************** @@ -1119,16 +1050,8 @@ SetNotifyFd(int fd, NotifyFdProcPtr notify, int mask, void *data) if (mask & X_NOTIFY_READ) { poll_fd_add(fd); poll_fd_listen(fd, POLLIN); - FD_SET(fd, &NotifyReadFds); - FD_SET(fd, &AllSockets); - if (GrabInProgress) - FD_SET(fd, &SavedAllSockets); } else { poll_fd_mute(fd, POLLIN); - FD_CLR(fd, &AllSockets); - if (GrabInProgress) - FD_CLR(fd, &SavedAllSockets); - FD_CLR(fd, &NotifyReadFds); } } @@ -1136,15 +1059,8 @@ SetNotifyFd(int fd, NotifyFdProcPtr notify, int mask, void *data) if (mask & X_NOTIFY_WRITE) { poll_fd_add(fd); poll_fd_listen(fd, POLLOUT); - FD_SET(fd, &NotifyWriteFds); - if (!NumNotifyWriteFd++) - AnyWritesPending = TRUE; } else { poll_fd_mute(fd, POLLOUT); - FD_CLR(fd, &NotifyWriteFds); - if (!--NumNotifyWriteFd) - if (!XFD_ANYSET(&ClientsWriteBlocked)) - AnyWritesPending = FALSE; } } @@ -1186,22 +1102,6 @@ HandleNotifyFd(int fd, short revents) } } -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 @@ -1215,28 +1115,13 @@ 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(); } @@ -1253,9 +1138,6 @@ 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(); } @@ -1271,7 +1153,6 @@ void IgnoreClient(ClientPtr client) { OsCommPtr oc = (OsCommPtr) client->osPrivate; - int connection = oc->fd; client->ignoreCount++; if (client->ignoreCount > 1) @@ -1282,26 +1163,6 @@ IgnoreClient(ClientPtr client) oc->flags |= OS_COMM_IGNORED; set_poll_client(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); - } } /**************** @@ -1313,7 +1174,6 @@ void AttendClient(ClientPtr client) { OsCommPtr oc = (OsCommPtr) client->osPrivate; - int connection = oc->fd; client->ignoreCount--; if (client->ignoreCount) @@ -1321,23 +1181,8 @@ AttendClient(ClientPtr client) oc->flags &= ~OS_COMM_IGNORED; set_poll_client(client); - - 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); - } + if (listen_to_client(client)) + mark_client_ready(client); } /* make client impervious to grabs; assume only executing client calls this */ @@ -1346,11 +1191,9 @@ void MakeClientGrabImpervious(ClientPtr client) { OsCommPtr oc = (OsCommPtr) client->osPrivate; - int connection = oc->fd; oc->flags |= OS_COMM_GRAB_IMPERVIOUS; - - FD_SET(connection, &GrabImperviousClients); + set_poll_client(client); if (ServerGrabCallback) { ServerGrabInfoRec grabinfo; @@ -1367,21 +1210,10 @@ void MakeClientGrabPervious(ClientPtr client) { OsCommPtr oc = (OsCommPtr) client->osPrivate; - int connection = oc->fd; oc->flags &= ~OS_COMM_GRAB_IMPERVIOUS; set_poll_client(client); - - 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; - } + isItTimeToYield = TRUE; if (ServerGrabCallback) { ServerGrabInfoRec grabinfo; @@ -1467,7 +1299,7 @@ AddClientOnOpenFD(int fd) static int poll_fds_size; -static inline Bool +Bool listen_to_client(ClientPtr client) { OsCommPtr oc = (OsCommPtr) client->osPrivate; diff --git a/os/io.c b/os/io.c index 19a449a..ce49bfb 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,6 @@ static void YieldControlNoInput(int fd) { YieldControl(); - FD_CLR(fd, &ClientsWithInput); } static void @@ -452,24 +450,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 +544,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 +584,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 +606,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 +624,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 +773,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 +786,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 +810,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 +882,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 +944,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 4680850..63df590 100644 --- a/os/osdep.h +++ b/os/osdep.h @@ -177,18 +177,8 @@ extern void HandleNotifyFds(void); extern struct pollfd *poll_fds; extern int poll_fds_num; -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); void poll_fd_init(void); @@ -214,8 +204,6 @@ extern void ClearConnectionTranslation(void); #endif extern Bool NewOutputPending; -extern Bool AnyWritesPending; -extern Bool NumNotifyWriteFd; extern WorkQueuePtr workQueue; 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