From 761d74a6805e1030f2206a50834b36d807e8e107 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 9 Feb 2017 23:33:44 +0000 Subject: os: Implement support for NotifyFd X_NOTIFY_WRITE and removal of AddEnabledDevices/RemoveEnabledDevices Backported from X.org: commit be5a513fee6cbf29ef7570e57eb0436d70fbd88c Author: Keith Packard Date: Mon Dec 7 15:12:14 2015 -0800 Remove AddEnabledDevice and AddGeneralSocket APIs All uses of these interfaces should instead be using the NotifyFd API instead. Signed-off-by: Keith Packard Reviewed-by: Adam Jackson commit 4020aacd1fc5b9c63369f011aeb9120af9c55218 Author: Keith Packard Date: Wed Nov 11 22:02:03 2015 -0800 os: Implement support for NotifyFd X_NOTIFY_WRITE This adds the ability to be notified when a file descriptor is available for writing. Reviewed-by: Adam Jackson Signed-off-by: Keith Packard Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/include/os.h | 4 -- nx-X11/programs/Xserver/os/WaitFor.c | 35 +++++++++------- nx-X11/programs/Xserver/os/connection.c | 72 ++++++++++++++++++--------------- nx-X11/programs/Xserver/os/io.c | 9 +++-- nx-X11/programs/Xserver/os/osdep.h | 5 ++- 5 files changed, 69 insertions(+), 56 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/include/os.h b/nx-X11/programs/Xserver/include/os.h index dfcc639d3..99003922f 100644 --- a/nx-X11/programs/Xserver/include/os.h +++ b/nx-X11/programs/Xserver/include/os.h @@ -143,10 +143,6 @@ extern void CheckConnections(void); extern void CloseDownConnection(ClientPtr /*client*/); -extern void AddEnabledDevice(int /*fd*/); - -extern void RemoveEnabledDevice(int /*fd*/); - typedef void (*NotifyFdProcPtr)(int fd, int ready, void *data); #define X_NOTIFY_NONE 0 diff --git a/nx-X11/programs/Xserver/os/WaitFor.c b/nx-X11/programs/Xserver/os/WaitFor.c index d94ada1d5..3ac2e1c7e 100644 --- a/nx-X11/programs/Xserver/os/WaitFor.c +++ b/nx-X11/programs/Xserver/os/WaitFor.c @@ -188,9 +188,9 @@ WaitForSomething(int *pClientsReady) int curclient; int selecterr; int nready; - fd_set devicesReadable; CARD32 now = 0; Bool someReady = FALSE; + Bool someNotifyWriteReady = FALSE; #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) fprintf(stderr, "WaitForSomething: Got called.\n"); @@ -338,7 +338,7 @@ WaitForSomething(int *pClientsReady) if (dispatchException) i = -1; #endif - else if (AnyClientsWriteBlocked) + else if (AnyWritesPending) { #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) if (wt == NULL) @@ -353,8 +353,9 @@ WaitForSomething(int *pClientsReady) wt -> tv_sec, wt -> tv_usec); } #endif - XFD_COPYSET(&ClientsWriteBlocked, &clientsWritable); - i = Select (MaxClients, &LastSelectMask, &clientsWritable, NULL, wt); + XFD_COPYSET(&ClientsWriteBlocked, &LastSelectWriteMask); + XFD_ORSET(&LastSelectWriteMask, &NotifyWriteFds, &LastSelectWriteMask); + i = Select(MaxClients, &LastSelectMask, &LastSelectWriteMask, NULL, wt); } else { @@ -489,16 +490,22 @@ WaitForSomething(int *pClientsReady) } if (someReady) XFD_ORSET(&LastSelectMask, &ClientsWithInput, &LastSelectMask); - if (AnyClientsWriteBlocked && XFD_ANYSET (&clientsWritable)) - { - NewOutputPending = TRUE; - XFD_ORSET(&OutputPending, &clientsWritable, &OutputPending); - XFD_UNSET(&ClientsWriteBlocked, &clientsWritable); - if (! XFD_ANYSET(&ClientsWriteBlocked)) - AnyClientsWriteBlocked = FALSE; + 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; + } } - XFD_ANDSET(&devicesReadable, &LastSelectMask, &EnabledDevices); XFD_ANDSET(&clientsReadable, &LastSelectMask, &AllClients); XFD_ANDSET(&tmp_set, &LastSelectMask, &WellKnownConnections); if (XFD_ANYSET(&tmp_set)) @@ -506,10 +513,10 @@ WaitForSomething(int *pClientsReady) (void *)&LastSelectMask); XFD_ANDSET(&tmp_set, &LastSelectMask, &NotifyReadFds); - if (XFD_ANYSET(&tmp_set)) + if (XFD_ANYSET(&tmp_set) || someNotifyWriteReady) HandleNotifyFds(); - if (XFD_ANYSET (&devicesReadable) || XFD_ANYSET (&clientsReadable)) + if (XFD_ANYSET (&clientsReadable)) break; #ifdef WIN32 /* Windows keyboard and mouse events are added to the input queue diff --git a/nx-X11/programs/Xserver/os/connection.c b/nx-X11/programs/Xserver/os/connection.c index 23df49883..966fe208d 100644 --- a/nx-X11/programs/Xserver/os/connection.c +++ b/nx-X11/programs/Xserver/os/connection.c @@ -48,8 +48,8 @@ SOFTWARE. * Stuff to create connections --- OS dependent * * EstablishNewConnections, CreateWellKnownSockets, ResetWellKnownSockets, - * CloseDownConnection, CheckConnections, AddEnabledDevice, - * RemoveEnabledDevice, OnlyListToOneClient, + * CloseDownConnection, CheckConnections, + * OnlyListToOneClient, * ListenToAllClients, * * (WaitForSomething is in its own file) @@ -123,18 +123,19 @@ SOFTWARE. int lastfdesc; /* maximum file descriptor */ fd_set WellKnownConnections; /* Listener mask */ -fd_set EnabledDevices; /* mask for input devices that are on */ 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 AnyClientsWriteBlocked; /* true if some client blocked on write */ - +Bool AnyWritesPending; /* true if some client blocked on write or NotifyFd with write */ Bool RunFromSmartParent; /* send SIGUSR1 to parent process */ Bool PartialNetwork; /* continue even if unable to bind all addrs */ static Pid_t ParentProcess; @@ -913,8 +914,8 @@ CloseDownFileDescriptor(OsCommPtr oc) FD_CLR(connection, &SavedClientsWithInput); } FD_CLR(connection, &ClientsWriteBlocked); - if (!XFD_ANYSET(&ClientsWriteBlocked)) - AnyClientsWriteBlocked = FALSE; + if (!XFD_ANYSET(&ClientsWriteBlocked) && NumNotifyWriteFd == 0) + AnyWritesPending = FALSE; FD_CLR(connection, &OutputPending); } @@ -997,24 +998,6 @@ CloseDownConnection(ClientPtr client) AuditF("client %d disconnected\n", client->index); } -void -AddEnabledDevice(int fd) -{ - FD_SET(fd, &EnabledDevices); - FD_SET(fd, &AllSockets); - if (GrabInProgress) - FD_SET(fd, &SavedAllSockets); -} - -void -RemoveEnabledDevice(int fd) -{ - FD_CLR(fd, &EnabledDevices); - FD_CLR(fd, &AllSockets); - if (GrabInProgress) - FD_CLR(fd, &SavedAllSockets); -} - struct notify_fd { struct xorg_list list; int fd; @@ -1036,6 +1019,7 @@ InitNotifyFds(void) RemoveNotifyFd(s->fd); xorg_list_init(¬ify_fds); + NumNotifyWriteFd = 0; been_here = 1; } @@ -1071,12 +1055,30 @@ SetNotifyFd(int fd, NotifyFdProcPtr notify, int mask, void *data) if (changes & X_NOTIFY_READ) { if (mask & X_NOTIFY_READ) { FD_SET(fd, &NotifyReadFds); - AddGeneralSocket(fd); + FD_SET(fd, &AllSockets); + if (GrabInProgress) + FD_SET(fd, &SavedAllSockets); } else { - RemoveGeneralSocket(fd); + FD_CLR(fd, &AllSockets); + if (GrabInProgress) + FD_CLR(fd, &SavedAllSockets); FD_CLR(fd, &NotifyReadFds); } } + + if (changes & X_NOTIFY_WRITE) { + if (mask & X_NOTIFY_WRITE) { + FD_SET(fd, &NotifyWriteFds); + if (!NumNotifyWriteFd++) + AnyWritesPending = TRUE; + } else { + FD_CLR(fd, &NotifyWriteFds); + if (!--NumNotifyWriteFd) + if (!XFD_ANYSET(&ClientsWriteBlocked)) + AnyWritesPending = FALSE; + } + } + if (mask == 0) { xorg_list_del(&n->list); free(n); @@ -1098,12 +1100,16 @@ SetNotifyFd(int fd, NotifyFdProcPtr notify, int mask, void *data) void HandleNotifyFds(void) { - struct notify_fd *s, *next; - - xorg_list_for_each_entry_safe(s, next, ¬ify_fds, list) { - if (FD_ISSET(s->fd, &LastSelectMask)) { - s->notify(s->fd, X_NOTIFY_READ, s->data); - } + 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); } } diff --git a/nx-X11/programs/Xserver/os/io.c b/nx-X11/programs/Xserver/os/io.c index 87739cfb1..92a3f0476 100644 --- a/nx-X11/programs/Xserver/os/io.c +++ b/nx-X11/programs/Xserver/os/io.c @@ -1062,7 +1062,7 @@ FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount) and not ready to accept more. Make a note of it and buffer the rest. */ FD_SET(connection, &ClientsWriteBlocked); - AnyClientsWriteBlocked = TRUE; + AnyWritesPending = TRUE; if (written < oco->count) { @@ -1134,11 +1134,12 @@ 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 (AnyClientsWriteBlocked) + if (AnyWritesPending) { FD_CLR(oc->fd, &ClientsWriteBlocked); - if (! XFD_ANYSET(&ClientsWriteBlocked)) - AnyClientsWriteBlocked = FALSE; + if (!XFD_ANYSET(&ClientsWriteBlocked) && NumNotifyWriteFd == 0) + AnyWritesPending = FALSE; + } if (oco->size > BUFWATERMARK) { diff --git a/nx-X11/programs/Xserver/os/osdep.h b/nx-X11/programs/Xserver/os/osdep.h index dce44e612..6ac9d860e 100644 --- a/nx-X11/programs/Xserver/os/osdep.h +++ b/nx-X11/programs/Xserver/os/osdep.h @@ -201,9 +201,11 @@ extern ConnectionOutputPtr AllocateOutputBuffer(void); 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; @@ -218,7 +220,8 @@ extern void ClearConnectionTranslation(); #endif extern Bool NewOutputPending; -extern Bool AnyClientsWriteBlocked; +extern Bool AnyWritesPending; +extern Bool NumNotifyWriteFd; extern Bool CriticalOutputPending; extern int timesThisConnection; -- cgit v1.2.3