On Tue, Jun 19, 2012 at 12:00:12PM -0700, Keith Packard wrote: > This adds API support for waking the server when an fd becomes > writable. > > void AddWriteSocket(int fd); > > Add an FD to the select write mask; the server will wake when > this fd is writable. > > void RemoveWriteSocket(int fd); > > Remove the FD from the select write mask. > > Note that there is no automated mechanism for emptying the set of > fds. The caller is responsible for removing the fd whenever > appropriate, including when the fd is closed, and when the > user no longer has pending write data. > > Bool CheckWriteSocket(int fd); > > Checks if the last select call marked this fd as > writable. This value persists until select is called again. > > This patch also adds a helper function for sockets used for reading: > > Bool CheckReadSocket(int fd); > > A matching function that checks for fds marked as readable > that have been added with AddGeneralSocket or > AddEnabledDevice.
shouldn't the documentatin for the calls be in the code? looking up git commits to understand functions doesn't scale too well. > The mechanism used is to keep a separate fd_set of write sockets, and > OR that with the client write mask to create a global select write > mask. The only other change necessary in WaitFor is to mask out the > resulting non-client fds when checking for unblocked client sockets. > > Signed-off-by: Keith Packard <[email protected]> > --- > include/os.h | 8 ++++++ > os/WaitFor.c | 79 > +++++++++++++++++++++++++++++++++++++++++++++++++++------- > 2 files changed, 78 insertions(+), 9 deletions(-) > > diff --git a/include/os.h b/include/os.h > index 276eb52..efb2b65 100644 > --- a/include/os.h > +++ b/include/os.h > @@ -157,6 +157,14 @@ extern _X_EXPORT void MakeClientGrabImpervious(ClientPtr > /*client */ ); > > extern _X_EXPORT void MakeClientGrabPervious(ClientPtr /*client */ ); > > +extern _X_EXPORT void AddWriteSocket(int fd); > + > +extern _X_EXPORT void RemoveWriteSocket(int fd); > + > +extern _X_EXPORT Bool CheckWriteSocket(int fd); > + > +extern _X_EXPORT Bool CheckReadSocket(int fd); > + > #ifdef XQUARTZ > extern void ListenOnOpenFD(int /* fd */ , int /* noxauth */ ); > #endif > diff --git a/os/WaitFor.c b/os/WaitFor.c > index 393890f..bf03273 100644 > --- a/os/WaitFor.c > +++ b/os/WaitFor.c > @@ -123,6 +123,62 @@ struct _OsTimerRec { > static void DoTimer(OsTimerPtr timer, CARD32 now, OsTimerPtr *prev); > static void CheckAllTimers(void); > static OsTimerPtr timers = NULL; > +static fd_set WriteSelectMask; > +static Bool AnyWriteSelectMask; > +static fd_set LastSelectWriteMask; > + > +/***************** > + * AddWriteSocket: > + * Add 'fd' to the list of write descriptors that will > + * wake the server from select. > + */ > + > +void > +AddWriteSocket(int fd) > +{ > + FD_SET(fd, &WriteSelectMask); > + AnyWriteSelectMask = TRUE; > +} > + > +/***************** > + * RemoveWriteSocket: > + * Remove 'fd' from the list of write descriptors that will > + * wake the server from select. > + */ > + > +void > +RemoveWriteSocket(int fd) > +{ > + FD_CLR(fd, &WriteSelectMask); > + AnyWriteSelectMask = XFD_ANYSET(&WriteSelectMask); > +} > + > +/***************** > + * CheckWriteSocket: > + * Called from a WakeupHandler to check of 'fd' > + * was marked as writable during the last select > + * call > + */ > + > +Bool > +CheckWriteSocket(int fd) > +{ > + return AnyWriteSelectMask && FD_ISSET(fd, &LastSelectWriteMask); > +} > + > +/***************** > + * CheckReadSocket: > + * Called from a WakeupHandler to check of 'fd' s/of/if/ > + * was marked as readable during the last select > + * call > + */ > + > +Bool > +CheckReadSocket(int fd) > +{ > + return FD_ISSET(fd, &LastSelectMask); > +} > + > > /***************** > * WaitForSomething: > @@ -213,9 +269,11 @@ WaitForSomething(int *pClientsReady) > /* keep this check close to select() call to minimize race */ > if (dispatchException) > i = -1; > - else if (AnyClientsWriteBlocked) { > - XFD_COPYSET(&ClientsWriteBlocked, &clientsWritable); > - i = Select(MaxClients, &LastSelectMask, &clientsWritable, NULL, > wt); > + else if (AnyClientsWriteBlocked || AnyWriteSelectMask) { > + XFD_COPYSET(&ClientsWriteBlocked, &LastSelectWriteMask); > + if (AnyWriteSelectMask) > + XFD_ORSET(&LastSelectWriteMask, &WriteSelectMask, > &LastSelectWriteMask); > + i = Select(MaxClients, &LastSelectMask, &LastSelectWriteMask, > NULL, wt); > } > else { > i = Select(MaxClients, &LastSelectMask, NULL, NULL, wt); > @@ -285,12 +343,15 @@ 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 (AnyClientsWriteBlocked) { > + XFD_ANDSET(&clientsWritable, &LastSelectWriteMask, > &ClientsWriteBlocked); > + if (XFD_ANYSET(&clientsWritable)) { > + NewOutputPending = TRUE; > + XFD_ORSET(&OutputPending, &clientsWritable, &OutputPending); > + XFD_UNSET(&ClientsWriteBlocked, &clientsWritable); > + if (!XFD_ANYSET(&ClientsWriteBlocked)) > + AnyClientsWriteBlocked = FALSE; > + } > } > > XFD_ANDSET(&devicesReadable, &LastSelectMask, &EnabledDevices); > -- > 1.7.10 please fix your indentation settings, these should be spaces, not tabs. Acked-by: Peter Hutterer <[email protected]> otherwise Cheers, Peter _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
