| Message ID | 1340132412-22420-1-git-send-email-keithp@keithp.com |
|---|---|
| State | Superseded |
| Headers | show |
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' + * 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);
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 <keithp@keithp.com> > --- > 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 <peter.hutterer@who-t.net> otherwise Cheers, Peter
Peter Hutterer <peter.hutterer@who-t.net> writes: > On Tue, Jun 19, 2012 at 12:00:12PM -0700, Keith Packard wrote: > shouldn't the documentatin for the calls be in the code? looking up git > commits to understand functions doesn't scale too well. Yeah, I started by copying the text from the function definitions. I'll clean those up. > please fix your indentation settings, these should be spaces, not tabs. > Acked-by: Peter Hutterer <peter.hutterer@who-t.net> otherwise Heh. Yeah, I clearly haven't been *writing* a lot of X server code of late :-)
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. 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 <keithp@keithp.com> --- include/os.h | 8 ++++++ os/WaitFor.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 78 insertions(+), 9 deletions(-)