Re: [PATCH xserver] glamor: Cannot use copies when accessing outside of composite source
Michel Dänzerwrites: > You know the details better than I do, but my understanding is that the > region can only be clipped to the destination in general, because > accessing source pictures outside of their boundaries is defined such > that it can change the contents of the destination. Yeah, I didn't remember that the composite operation is supposed to do source clipping as there may be a transform involved. However, we need to make sure the rendered region is inside the source composite clip so that the simple copy will work correctly. > Anyway, the fact is that this patch fixes a fair number of rendercheck > tests. Here's a patch which uses region operations to make sure we don't use copy when the source doesn't contain all of the necessary bits. Note that this just means we'll fall back to the existing (broken) code which doesn't bother to clip against the source either, but at least that's only one bug instead of two? || (op == PictOpOver && source->format == dest->format && !PICT_FORMAT_A(source->format { int dx, dy; x_source += source->pDrawable->x; y_source += source->pDrawable->y; x_dest += dest->pDrawable->x; y_dest += dest->pDrawable->y; dx = x_source - x_dest; dy = y_source - y_dest; /* Align region with source */ pixman_region_translate(region, dx, dy); box = RegionRects(region); nbox = RegionNumRects(region); for (i = 0; i < nbox; i++) if (pixman_region_contains_rectangle(source->pCompositeClip, [i]) != PIXMAN_REGION_IN) break; pixman_region_translate(region, -dx, -dy); if (i == nbox) { /* Re-align region with dest */ glamor_copy(source->pDrawable, dest->pDrawable, NULL, RegionRects(region), RegionNumRects(region), dx, dy, FALSE, FALSE, 0, NULL); ok = TRUE; goto out; } -- -keith signature.asc Description: PGP signature ___ 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
Re: [PATCH xserver 17/23] os: Add ospoll interface
Emil Velikovwrites: > Hi Keith, > > Style question: do you/how many others refer having separate functions for > of ifdeffed code each vs a single with all the ifdeffs. Or in other words > having func_foo_poll and func_foo_epoll as opposed to having it all in > func_foo. I started having separate versions of each function (with the same name), but that seemed bad, so I merged the contents of the separate functions into the single functions you see now. I found it easier to compare the semantics of the different implementations when they were right next to each other. > +#ifndef _OSPOLL_H_ >> +#define _OSPOLL_H_ >> + >> +#include >> + > > This include should be in the C file with proper ifdef guard, right? I'm not sure I understand -- we need on every system as ospoll uses the POLLIN/POLLOUT defines for its arguments. We could use X server specific values, but I think the posix ones are common across all of our supported systems. -- -keith signature.asc Description: PGP signature ___ 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
[PATCH xserver] xfree86: Remove event reading code from xf86Wakeup
Oops. This didn't get removed when xfree86 was converted over to use the input thread. Signed-off-by: Keith Packard <kei...@keithp.com> --- hw/xfree86/common/xf86Events.c | 28 1 file changed, 28 deletions(-) diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c index 7191980..5db0dfb 100644 --- a/hw/xfree86/common/xf86Events.c +++ b/hw/xfree86/common/xf86Events.c @@ -247,34 +247,6 @@ xf86ProcessActionEvent(ActionEvent action, void *arg) void xf86Wakeup(void *blockData, int err, void *pReadmask) { -fd_set *LastSelectMask = (fd_set *) pReadmask; -fd_set devicesWithInput; -InputInfoPtr pInfo; - -if (err >= 0) { - -XFD_ANDSET(, LastSelectMask, ); -if (XFD_ANYSET()) { -pInfo = xf86InputDevs; -while (pInfo) { -if (pInfo->read_input && pInfo->fd >= 0 && -(FD_ISSET(pInfo->fd, ) != 0)) { -input_lock(); - -/* - * Remove the descriptior from the set because more than one - * device may share the same file descriptor. - */ -FD_CLR(pInfo->fd, ); - -pInfo->read_input(pInfo); -input_unlock(); -} -pInfo = pInfo->next; -} -} -} - if (err >= 0) { /* we don't want the handlers called if select() */ IHPtr ih, ih_tmp; /* returned with an error condition, do we? */ -- 2.8.1 ___ 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
[PATCH xserver] dix: Don't update current time in the middle of input event processing
In patch 137ac094e7ab8c871f3b36e40ad826ac797f0e26, Adam moved an expensive call to UpdateCurrentTime out of the main dispatch loop. That's a good change as the original fix from Chase was a bit expensive. However, it breaks grab processing and so a couple of the calls to UpdateCurrenTime need to be removed. Input event processing can generate a stream of events; a button press that activates a grab will send a press followed by a sequence of enter/leave events. All of these should have the same time stamp on the wire as they occur at the 'same' time. More importantly, the grab time recorded in the device is pulled from currentTime after all of the events are delivered, so if currentTime doesn't match the time in the device event, then future grab modifications will fail as the time marked in the device will be 'later' than the grab time known to the client (which is defined as the timestamp from the activating input event). A bit of history here -- it used to be that currentTime was driven *entirely* by input events; those timestamps didn't even have to be related to the system time in any way. Then we started doing ICCCM stuff and people got confused when PropertyNotify events would have the same timestamp even when delivered minutes apart because no input events were delivered. We added code in the server to go update the time, but only if no input events were pending (so that the clock "wouldn't" go backwards). The only places where this is necessary is in request processing which may generate an event with a timestamp, and there only at the very top of the request processing code so that the whole request would be processed at the 'same time', just like events. cc: Chase Douglas <chase.doug...@canonical.com> cc: Peter Hutterer <peter.hutte...@who-t.net> cc: Adam Jackson <a...@redhat.com> Signed-off-by: Keith Packard <kei...@keithp.com> --- dix/enterleave.c | 1 - dix/events.c | 1 - 2 files changed, 2 deletions(-) diff --git a/dix/enterleave.c b/dix/enterleave.c index 0c6c616..1b341f2 100644 --- a/dix/enterleave.c +++ b/dix/enterleave.c @@ -782,7 +782,6 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, DeviceIntPtr mouse; int btlen, len, i; -UpdateCurrentTimeIf(); mouse = IsFloating(dev) ? dev : GetMaster(dev, MASTER_POINTER); /* XI 2 event */ diff --git a/dix/events.c b/dix/events.c index 0404eba..8efdf18 100644 --- a/dix/events.c +++ b/dix/events.c @@ -2242,7 +2242,6 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent this mask is the mask of the grab. */ int type = pEvents->u.u.type; -UpdateCurrentTimeIf(); /* Deliver to window owner */ if ((filter == CantBeFiltered) || core_get_type(pEvents) != 0) { enum EventDeliveryState rc; -- 2.8.1 ___ 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
Re: [PATCH xserver] glamor: Adjust for drawable x/y in composite's copy optimization
Alex Deucher <alexdeuc...@gmail.com> writes: >> Signed-off-by: Keith Packard <kei...@keithp.com> > > Reviewed-by: Alex Deucher <alexander.deuc...@amd.com> Merged. 0d16a0c..8b9b438 master -> master -- -keith signature.asc Description: PGP signature ___ 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
Re: [PATCH xserver] glamor: Cannot use copies when accessing outside of composite source
Michel Dänzerwrites: > From: Michel Dänzer > > Commit b64108fa ("glamor: Check for composite operations which are > equivalent to copies") failed to copy conditions from exaComposite which > ensure that the composite operation doesn't access outside of the source > picture. I'm confused -- the region to be copied should already have been clipped to the source, so there shouldn't be any access outside of the source picture. -- -keith signature.asc Description: PGP signature ___ 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
Re: [PATCH xserver 2/2] xfree86/modes: Don't set xf86_config->cursor if loading the cursor fails
Michel Dänzer <mic...@daenzer.net> writes: > From: Michel Dänzer <michel.daen...@amd.com> > > If xf86_load_cursor_argb returns FALSE, the caller is expected to fall > back to SW cursor, so xf86_config->cursor shouldn't be updated. It doesn't matter -- xf86_config->cursor is supposed to be a temporary field until drivers are converted over to xf86CurrentCursor, which doesn't care whether the cursor is HW or SW. Nacked-by: Keith Packard <kei...@keithp.com> -- -keith signature.asc Description: PGP signature ___ 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
Re: [PATCH xserver 1/2] xfree86/modes: Assign xf86_config->cursor in xf86_load_cursor_image
Michel Dänzer <mic...@daenzer.net> writes: > From: Michel Dänzer <michel.daen...@amd.com> > > Fixes a crash on startup in the radeon driver's drmmode_show_cursor() > due to xf86_config->cursor == NULL, because no CRTC was enabled yet, so > xf86_crtc_load_cursor_image was never called. Good catch! > @@ -507,6 +506,9 @@ xf86_load_cursor_image(ScrnInfoPtr scrn, unsigned char > *src) > return FALSE; > } > } > + > +xf86_config->cursor = xf86CurrentCursor(scrn->pScreen); > + This should probably be at the top of xf86_load_cursor_image instead of the bottom. Otherwise, this patch is Reviewed-by: Keith Packard <kei...@keithp.com> -- -keith signature.asc Description: PGP signature ___ 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
[PATCH xserver] glamor: Adjust for drawable x/y in composite's copy optimization
Patch b64108fa305e956e4edaae9d53071ff0abee268e added a short cut that identifies composite operations that can be performed with a simple copy instead. glamor_copy works in absolute coordinates, so the dx and dy values passed in need to be converted from drawable-relative to absolute by adding the drawable x/y values. Signed-off-by: Keith Packard <kei...@keithp.com> --- glamor/glamor_render.c | 4 1 file changed, 4 insertions(+) diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 9c5cca6..165bced 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -1436,6 +1436,10 @@ glamor_composite_clipped_region(CARD8 op, || (op == PictOpOver && source->format == dest->format && !PICT_FORMAT_A(source->format)) { +x_source += source->pDrawable->x; +y_source += source->pDrawable->y; +x_dest += dest->pDrawable->x; +y_dest += dest->pDrawable->y; glamor_copy(source->pDrawable, dest->pDrawable, NULL, box, nbox, x_source - x_dest, y_source - y_dest, FALSE, FALSE, 0, NULL); -- 2.8.1 ___ 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
Re: [PATCH xserver] os: Increase default client buffer to 16kB
Hans de Goede <hdego...@redhat.com> writes: >> Signed-off-by: Keith Packard <kei...@keithp.com> > > Ack. > > Reviewed-by: Hans de Goede <hdego...@redhat.com> Pushed. 7147361..0d16a0c master -> master -- -keith signature.asc Description: PGP signature ___ 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
Re: [PATCH xserver 1/9] xfree86: Set xf86CrtcConfigRec cursor pointer to NULL in HideCursor
Michel Dänzerwrites: > [ Unknown signature status ] > > The patch is > > Reviewed-by: Michel Dänzer Thanks. Pushed. e69061e..7147361 master -> master -- -keith signature.asc Description: PGP signature ___ 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
Re: xserver: Branch 'master' - 10 commits
Michel Dänzer <mic...@daenzer.net> writes: > On 27.05.2016 08:08, Keith Packard wrote: >> >> commit f84703b50cc908a127f4ad923ebbf56f8f244c0d >> Author: Keith Packard <kei...@keithp.com> >> Date: Tue Dec 8 14:20:21 2015 -0800 >> >> dix: Reallocate touchpoint buffer at input event time [v2] >> >> Now that input is threaded, malloc can be used at event time to resize >> the touchpoint buffer as needed.x >> >> v2: Remove "Need to grow the queue means dropping events." >> from comment as it no longer applies. (Peter Hutterer) >> >> Signed-off-by: Keith Packard <kei...@keithp.com> >> Reviewed-by: Peter Hutterer <peter.hutte...@who-t.net> > > This change broke make check for me, specifically test/touch: > > touch: ../../test/touch.c:62: touch_grow_queue: Assertion > `TouchBeginDDXTouch(, 1234) == ((void *)0)' failed. yeah, that test actually checks for the old (broken) X server behaviour of dropping touch events that overfill the buffer. The X server doesn't drop them anymore as it can call malloc while reading events now. From 85fef2e05775beec41eaecf9ee517bd6ffeef858 Mon Sep 17 00:00:00 2001 From: Keith Packard <kei...@keithp.com> Date: Fri, 27 May 2016 01:56:39 -0700 Subject: [PATCH xserver] test: Make touch test reflect new ability to realloc touch array Threaded input allows the input code to call malloc while processing events. In this case, that's in the middle of processing touch events and needing to resize the touch buffer. This test was expecting the old behaviour where touch points would get dropped if the buffer was full. The fix is to check for the new behaviour instead. Signed-off-by: Keith Packard <kei...@keithp.com> --- test/touch.c | 27 ++- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/test/touch.c b/test/touch.c index 981c694..e0c1bcc 100644 --- a/test/touch.c +++ b/test/touch.c @@ -58,9 +58,8 @@ touch_grow_queue(void) dev.last.touches[i].client_id = i * 2; } -/* no more space, should've scheduled a workproc */ -assert(TouchBeginDDXTouch(, 1234) == NULL); -ProcessWorkQueue(); +/* no more space, should've reallocated and succeeded */ +assert(TouchBeginDDXTouch(, 1234) != NULL); new_size = size + size / 2 + 1; assert(dev.last.num_touches == new_size); @@ -74,8 +73,12 @@ touch_grow_queue(void) assert(t->client_id == i * 2); } +assert(dev.last.touches[size].active == TRUE); +assert(dev.last.touches[size].ddx_id == 1234); +assert(dev.last.touches[size].client_id == 1); + /* make sure those are zero-initialized */ -for (i = size; i < new_size; i++) { +for (i = size + 1; i < new_size; i++) { DDXTouchPointInfoPtr t = [i]; assert(t->active == FALSE); @@ -136,22 +139,20 @@ touch_find_ddxid(void) for (i = 0; i < size; i++) dev.last.touches[i].active = TRUE; -/* Try to create more, fail */ +/* Try to create more, succeed */ ti = TouchFindByDDXID(, 30, TRUE); -assert(ti == NULL); +assert(ti != NULL); ti = TouchFindByDDXID(, 30, TRUE); -assert(ti == NULL); -/* make sure we haven't resized, we're in the signal handler */ -assert(dev.last.num_touches == size); +assert(ti != NULL); +/* make sure we have resized */ +assert(dev.last.num_touches == size + 3); /* stop one touchpoint, try to create, succeed */ dev.last.touches[2].active = FALSE; -ti = TouchFindByDDXID(, 30, TRUE); +ti = TouchFindByDDXID(, 35, TRUE); assert(ti == [2]); -/* but still grow anyway */ -ProcessWorkQueue(); ti = TouchFindByDDXID(, 40, TRUE); -assert(ti == [size]); +assert(ti == [size+1]); free(dev.name); } -- 2.8.1 -- -keith signature.asc Description: PGP signature ___ 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
[PATCH xserver 20/23] os: Use poll(2) for input thread
Replace use of select(2) to avoid fd limits Signed-off-by: Keith Packard <kei...@keithp.com> --- os/inputthread.c | 85 1 file changed, 48 insertions(+), 37 deletions(-) diff --git a/os/inputthread.c b/os/inputthread.c index b6bbf35..3d8e6da 100644 --- a/os/inputthread.c +++ b/os/inputthread.c @@ -35,7 +35,6 @@ #include #include -#include #include "inputstr.h" #include "opaque.h" #include "osdep.h" @@ -62,7 +61,7 @@ typedef struct _InputThreadDevice { typedef struct { pthread_t thread; struct xorg_list devs; -fd_set fds; +struct ospoll *fds; int readPipe; int writePipe; } InputThreadInfo; @@ -126,9 +125,10 @@ InputThreadFillPipe(int writeHead) { int ret; char byte = 0; -fd_set writePipe; +struct pollfd poll_fd; -FD_ZERO(); +poll_fd.fd = writeHead; +poll_fd.events = POLLOUT; while (1) { ret = write(writeHead, , 1); @@ -141,8 +141,7 @@ InputThreadFillPipe(int writeHead) FatalError("input-thread: filling pipe"); DebugF("input-thread: pipe full\n"); -FD_SET(writeHead, ); -Select(writeHead + 1, NULL, , NULL, NULL); +poll(_fd, 1, -1); } } @@ -167,6 +166,18 @@ InputThreadReadPipe(int readHead) return 1; } +static void +InputReady(int fd, short revents, void *data) +{ +InputThreadDevice *dev = data; + +if (revents & POLLIN) { +input_lock(); +dev->readInputProc(fd, X_NOTIFY_READ, dev->readInputArgs); +input_unlock(); +} +} + /** * Register an input device in the threaded input facility * @@ -198,7 +209,11 @@ InputThreadRegisterDev(int fd, xorg_list_add(>node, >devs); -FD_SET(fd, >fds); +ospoll_add(inputThreadInfo->fds, fd, + ospoll_trigger_level, + InputReady, + dev); +ospoll_listen(inputThreadInfo->fds, fd, POLLIN); InputThreadFillPipe(hotplugPipeWrite); DebugF("input-thread: registered device %d\n", fd); @@ -239,7 +254,7 @@ InputThreadUnregisterDev(int fd) xorg_list_del(>node); -FD_CLR(fd, >fds); +ospoll_remove(inputThreadInfo->fds, fd); free(dev); InputThreadFillPipe(hotplugPipeWrite); @@ -248,6 +263,16 @@ InputThreadUnregisterDev(int fd) return 1; } +static void +InputThreadPipeNotify(int fd, short revents, void *data) +{ +/* Empty pending input, shut down if the pipe has been closed */ +if (InputThreadReadPipe(hotplugPipeRead) == 0) { +Bool*running = data; +*running = FALSE; +} +} + /** * The workhorse of threaded input event generation. * @@ -265,51 +290,36 @@ InputThreadUnregisterDev(int fd) static void* InputThreadDoWork(void *arg) { -fd_set readyFds; -InputThreadDevice *dev, *next; +Boolrunning = TRUE; sigset_t set; /* Don't handle any signals on this thread */ sigfillset(); pthread_sigmask(SIG_BLOCK, , NULL); -FD_ZERO(); +ospoll_add(inputThreadInfo->fds, hotplugPipeRead, + ospoll_trigger_level, + InputThreadPipeNotify, + ); -while (1) +while (running) { -XFD_COPYSET(>fds, ); -FD_SET(hotplugPipeRead, ); - DebugF("input-thread: %s waiting for devices\n", __func__); -if (Select(MAXSELECT, , NULL, NULL, NULL) < 0) { +if (ospoll_wait(inputThreadInfo->fds, -1) < 0) { if (errno == EINVAL) FatalError("input-thread: %s (%s)", __func__, strerror(errno)); else if (errno != EINTR) ErrorF("input-thread: %s (%s)\n", __func__, strerror(errno)); } -DebugF("input-thread: %s generating events\n", __func__); - -/* Call the device drivers to generate input events for us */ -xorg_list_for_each_entry_safe(dev, next, >devs, node) { -if (FD_ISSET(dev->fd, ) && dev->readInputProc) { -input_lock(); -dev->readInputProc(dev->fd, X_NOTIFY_READ, dev->readInputArgs); -input_unlock(); -} -} - /* Kick main thread to process the generated input events and drain * events from hotplug pipe */ InputThreadFillPipe(inputThreadInfo->writePipe); - -/* Empty pending input, shut down if the pipe has been closed */ -if (FD_ISSET(hotplugPipeRead, )) { -if (InputThreadReadPipe(hotplugPipeRead) == 0) -break; -} } + +ospoll_remove(inputThreadInfo->fds, hotplugPipeRead); + return NULL; } @@ -343,7 +353,7 @@ InputThreadPreInit(void) inputThreadInfo->thread = 0; xorg_list_init(>devs); -FD_ZERO(>fds); +inputThreadInfo->
[PATCH xserver 17/23] os: Add ospoll interface
This provides a wrapper around poll, epoll or WSAPoll providing a callback-based interface for monitoring activity on a large set of file descriptors. Signed-off-by: Keith Packard <kei...@keithp.com> --- configure.ac| 2 +- include/dix-config.h.in | 9 + os/Makefile.am | 1 + os/ospoll.c | 439 os/ospoll.h | 144 5 files changed, 594 insertions(+), 1 deletion(-) create mode 100644 os/ospoll.c create mode 100644 os/ospoll.h diff --git a/configure.ac b/configure.ac index 1a9aa81..d078190 100644 --- a/configure.ac +++ b/configure.ac @@ -219,7 +219,7 @@ dnl Checks for library functions. AC_CHECK_FUNCS([backtrace ffs geteuid getuid issetugid getresuid \ getdtablesize getifaddrs getpeereid getpeerucred getprogname getzoneid \ mmap posix_fallocate seteuid shmctl64 strncasecmp vasprintf vsnprintf \ - walkcontext setitimer]) + walkcontext setitimer poll epoll_create1 WSAPoll]) AC_REPLACE_FUNCS([reallocarray strcasecmp strcasestr strlcat strlcpy strndup]) AC_CHECK_DECLS([program_invocation_short_name], [], [], [[#include ]]) diff --git a/include/dix-config.h.in b/include/dix-config.h.in index fc7d1a1..11025e0 100644 --- a/include/dix-config.h.in +++ b/include/dix-config.h.in @@ -527,4 +527,13 @@ /* Use input thread */ #undef INPUTTHREAD +/* Have poll() */ +#undef HAVE_POLL + +/* Have epoll_create1() */ +#undef HAVE_EPOLL_CREATE1 + +/* Have WSAPoll() */ +#undef HAVE_WSAPOLL + #endif /* _DIX_CONFIG_H_ */ diff --git a/os/Makefile.am b/os/Makefile.am index fc49a73..6835142 100644 --- a/os/Makefile.am +++ b/os/Makefile.am @@ -20,6 +20,7 @@ libos_la_SOURCES =\ oscolor.c \ osdep.h \ osinit.c\ + ospoll.c\ utils.c \ xdmauth.c \ xsha1.c \ diff --git a/os/ospoll.c b/os/ospoll.c new file mode 100644 index 000..c3e8d5b --- /dev/null +++ b/os/ospoll.c @@ -0,0 +1,439 @@ +/* + * Copyright © 2016 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include "misc.h" /* for typedef of pointer */ +#include "ospoll.h" +#include "list.h" + +#if !HAVE_OSPOLL && HAVE_EPOLL_CREATE1 +#define EPOLL 1 +#define HAVE_OSPOLL 1 +#endif + +#if !HAVE_OSPOLL && HAVE_POLL +#define POLL1 +#define HAVE_OSPOLL 1 +#endif + +#if !HAVE_OSPOLL && HAVE_WSAPOLL +#define WSAPOLL 1 +#define HAVE_OSPOLL 1 +#endif + +#if EPOLL +#include + +/* epoll-based implementation */ +struct ospollfd { +int fd; +short events; +enum ospoll_trigger trigger; +void(*callback)(int fd, short revents, void *data); +void*data; +}; + +struct ospoll { +int epoll_fd; +struct ospollfd **fds; +int num; +int size; +}; + +#endif + +#if WSAPOLL +/* WSAPoll is just like poll, but with a different name (for reasons) */ +#include +#define POLL1 +#define poll(fds, nfds, timeout) WSAPoll(fds, nfds, timeout) +#endif + +#if POLL + +/* poll-based implementation */ +struct ospollfd { +short revents; +enum ospoll_trigger trigger; +void(*callback)(int fd, short revents, void *data); +void*data; +}; + +struct ospoll { +struct pollfd *fds; +struct ospollfd *osfds; +int num; +int size; +}; + +#endif + +/* Binary search for the specified file descriptor + * + * Returns position if found + * Returns -position - 1 if not found + */
[PATCH xserver 22/23] Allow 1024 and 2048 for LimitClients
There's no reason not to offer ridiculous numbers of clients; only a few static data structures are arrays of this length. Signed-off-by: Keith Packard <kei...@keithp.com> --- include/misc.h | 2 +- os/utils.c | 6 -- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/misc.h b/include/misc.h index 006f768..01747fd 100644 --- a/include/misc.h +++ b/include/misc.h @@ -87,7 +87,7 @@ OF THIS SOFTWARE. #ifndef MAXGPUSCREENS #define MAXGPUSCREENS 16 #endif -#define MAXCLIENTS 512 +#define MAXCLIENTS 2048 #define LIMITCLIENTS 256 /* Must be a power of 2 and <= MAXCLIENTS */ #define MAXEXTENSIONS 128 #define MAXFORMATS 8 diff --git a/os/utils.c b/os/utils.c index 4507c9e..325e435 100644 --- a/os/utils.c +++ b/os/utils.c @@ -847,8 +847,10 @@ ProcessCommandLine(int argc, char *argv[]) if (LimitClients != 64 && LimitClients != 128 && LimitClients != 256 && - LimitClients != 512) { - FatalError("maxclients must be one of 64, 128, 256 or 512\n"); + LimitClients != 512 && +LimitClients != 1024 && +LimitClients != 2048) { + FatalError("maxclients must be one of 64, 128, 256, 512, 1024 or 2048\n"); } } else UseMsg(); -- 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
[PATCH xserver 15/23] dix: Intermediate GrabServer state 'GrabKickout' not needed
The intermediate grabState, "GrabKickout", was used to trigger dispatch into going back to WaitForSomething after doing a GrabServer so that the set of ready clients would be recomputed to match what the server should be processing. As we only process one client per WaitForSomething call, we will always hit WaitForSomething after finishing the current client, and so don't need any special case here. Signed-off-by: Keith Packard <kei...@keithp.com> --- dix/dispatch.c | 8 +--- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/dix/dispatch.c b/dix/dispatch.c index f005983..3237883 100644 --- a/dix/dispatch.c +++ b/dix/dispatch.c @@ -151,7 +151,6 @@ static ClientPtr grabClient; #define GrabNone 0 #define GrabActive 1 -#define GrabKickout 2 static int grabState = GrabNone; static long grabWaiters[mskcnt]; CallbackListPtr ServerGrabCallback = NULL; @@ -375,11 +374,6 @@ Dispatch(void) /* KillClient can cause this to happen */ continue; } -/* GrabServer activation can cause this to be true */ -if (grabState == GrabKickout) { -grabState = GrabActive; -break; -} isItTimeToYield = FALSE; start_tick = SmartScheduleTime; @@ -1060,7 +1054,7 @@ ProcGrabServer(ClientPtr client) rc = OnlyListenToOneClient(client); if (rc != Success) return rc; -grabState = GrabKickout; +grabState = GrabActive; grabClient = client; if (ServerGrabCallback) { -- 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
[PATCH xserver 10/23] dmx: Eliminate use of AddEnabledDevice
Use SetNotifyFd instead, with the hope that someday someone will come fix this to be more efficient -- right now, the wakeup handler is doing the event reading, instead of the notify callback. Signed-off-by: Keith Packard <kei...@keithp.com> --- hw/dmx/input/dmxcommon.c | 17 + hw/dmx/input/dmxsigio.c | 9 +++-- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/hw/dmx/input/dmxcommon.c b/hw/dmx/input/dmxcommon.c index 90154ef..c7aed68 100644 --- a/hw/dmx/input/dmxcommon.c +++ b/hw/dmx/input/dmxcommon.c @@ -480,17 +480,26 @@ dmxCommonXSelect(DMXScreenInfo * dmxScreen, void *closure) return NULL; } +static void +dmxCommonFdNotify(int fd, int ready, void *data) +{ +/* This should process input on this fd, but instead all + * of that is delayed until the block and wakeup handlers are called + */ +; +} + static void * dmxCommonAddEnabledDevice(DMXScreenInfo * dmxScreen, void *closure) { -AddEnabledDevice(XConnectionNumber(dmxScreen->beDisplay)); +SetNotifyFd(XConnectionNumber(dmxScreen->beDisplay), dmxCommonFdNotify, X_NOTIFY_READ, closure); return NULL; } static void * dmxCommonRemoveEnabledDevice(DMXScreenInfo * dmxScreen, void *closure) { -RemoveEnabledDevice(XConnectionNumber(dmxScreen->beDisplay)); +RemoveNotifyFd(XConnectionNumber(dmxScreen->beDisplay)); return NULL; } @@ -504,7 +513,7 @@ dmxCommonMouOn(DevicePtr pDev) priv->eventMask |= DMX_POINTER_EVENT_MASK; if (!priv->be) { XSelectInput(priv->display, priv->window, priv->eventMask); -AddEnabledDevice(XConnectionNumber(priv->display)); +SetNotifyFd(XConnectionNumber(priv->display), dmxCommonFdNotify,X_NOTIFY_READ, pDev); } else { dmxPropertyIterate(priv->be, dmxCommonXSelect, priv); @@ -523,7 +532,7 @@ dmxCommonMouOff(DevicePtr pDev) priv->eventMask &= ~DMX_POINTER_EVENT_MASK; if (!priv->be) { -RemoveEnabledDevice(XConnectionNumber(priv->display)); +RemoveNotifyFd(XConnectionNumber(priv->display)); XSelectInput(priv->display, priv->window, priv->eventMask); } else { diff --git a/hw/dmx/input/dmxsigio.c b/hw/dmx/input/dmxsigio.c index ebfd3d9..1fec12b 100644 --- a/hw/dmx/input/dmxsigio.c +++ b/hw/dmx/input/dmxsigio.c @@ -114,6 +114,11 @@ dmxSigioUnhook(void) } static void +dmxSigioFdNotify(int fd, int ready, void *data) +{ +} + +static void dmxSigioAdd(DMXInputInfo * dmxInput) { int flags; @@ -138,7 +143,7 @@ dmxSigioAdd(DMXInputInfo * dmxInput) flags |= O_ASYNC | O_NONBLOCK; fcntl(fd, F_SETFL, flags); -AddEnabledDevice(fd); +SetNotifyFd(fd, dmxSigioFdNotify, X_NOTIFY_READ, NULL); dmxInput->sigioAdded[i] = TRUE; if (++dmxFdCount == 1) @@ -168,7 +173,7 @@ dmxSigioRemove(DMXInputInfo * dmxInput) int fd = dmxInput->sigioFd[i]; dmxInput->sigioAdded[i] = FALSE; -RemoveEnabledDevice(fd); +RemoveNotifyFd(fd); flags = fcntl(fd, F_GETFL); flags &= ~(O_ASYNC | O_NONBLOCK); -- 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
[PATCH xserver 21/23] os: eliminate fd value limits for clients
With no code depending on the range of file descriptors, checking for that can be eliminated. Signed-off-by: Keith Packard <kei...@keithp.com> --- os/connection.c | 81 - os/osdep.h | 43 +- 2 files changed, 23 insertions(+), 101 deletions(-) diff --git a/os/connection.c b/os/connection.c index 1ae50b1..24ad109 100644 --- a/os/connection.c +++ b/os/connection.c @@ -103,7 +103,6 @@ SOFTWARE. #endif /* WIN32 */ #include "misc.h" /* for typedef of pointer */ #include "osdep.h" -#include #include "opaque.h" #include "dixstruct.h" #include "xace.h" @@ -119,7 +118,6 @@ SOFTWARE. #include "probes.h" -static int lastfdesc; /* maximum file descriptor */ struct ospoll *server_poll; int MaxClients = 0; @@ -133,8 +131,6 @@ static char dynamic_display[7]; /* display name */ Bool PartialNetwork;/* continue even if unable to bind all addrs */ static Pid_t ParentProcess; -static Bool debug_conns = FALSE; - int GrabInProgress = 0; static void @@ -148,19 +144,15 @@ set_poll_clients(void); #if !defined(WIN32) int *ConnectionTranslation = NULL; +int ConnectionTranslationSize = 0; #else /* - * On NT fds are not between 0 and MAXSOCKS, they are unrelated, and there is + * On NT fds are not small integers, they are unrelated, and there is * not even a known maximum value, so use something quite arbitrary for now. * Do storage is a hash table of size 256. Collisions are handled in a linked * list. */ -#undef MAXSOCKS -#define MAXSOCKS 512 -#undef MAXSELECT -#define MAXSELECT 512 - struct _ct_node { struct _ct_node *next; int key; @@ -265,47 +257,17 @@ lookup_trans_conn(int fd) void InitConnectionLimits(void) { -lastfdesc = -1; - -#ifndef __CYGWIN__ - -#if !defined(XNO_SYSCONF) && defined(_SC_OPEN_MAX) -lastfdesc = sysconf(_SC_OPEN_MAX) - 1; -#endif - -#ifdef HAVE_GETDTABLESIZE -if (lastfdesc < 0) -lastfdesc = getdtablesize() - 1; -#endif - -#ifdef _NFILE -if (lastfdesc < 0) -lastfdesc = _NFILE - 1; -#endif - -#endif /* __CYGWIN__ */ - -/* This is the fallback */ -if (lastfdesc < 0) -lastfdesc = MAXSOCKS; - -if (lastfdesc > MAXSELECT) -lastfdesc = MAXSELECT; - -if (lastfdesc > MAXCLIENTS) { -lastfdesc = MAXCLIENTS; -if (debug_conns) -ErrorF("REACHED MAXIMUM CLIENTS LIMIT %d\n", LimitClients); -} -MaxClients = lastfdesc; +MaxClients = MAXCLIENTS; #ifdef DEBUG ErrorF("InitConnectionLimits: MaxClients = %d\n", MaxClients); #endif #if !defined(WIN32) -if (!ConnectionTranslation) -ConnectionTranslation = xnfallocarray(lastfdesc + 1, sizeof(int)); +if (!ConnectionTranslation) { +ConnectionTranslation = xnfallocarray(MaxClients, sizeof(int)); +ConnectionTranslationSize = MaxClients; +} #else InitConnectionTranslation(); #endif @@ -388,7 +350,7 @@ CreateWellKnownSockets(void) FatalError("failed to allocate poll structure"); #if !defined(WIN32) -for (i = 0; i < MaxClients; i++) +for (i = 0; i < ConnectionTranslationSize; i++) ConnectionTranslation[i] = 0; #else ClearConnectionTranslation(); @@ -762,14 +724,6 @@ AllocNewConnection(XtransConnInfo trans_conn, int fd, CARD32 conn_time) OsCommPtr oc; ClientPtr client; -if ( -#ifndef WIN32 - fd >= lastfdesc -#else - XFD_SETCOUNT() >= MaxClients -#endif -) -return NullClient; oc = malloc(sizeof(OsCommRec)); if (!oc) return NullClient; @@ -786,6 +740,10 @@ AllocNewConnection(XtransConnInfo trans_conn, int fd, CARD32 conn_time) } client->local = ComputeLocalClient(client); #if !defined(WIN32) +if (fd >= ConnectionTranslationSize) { +ConnectionTranslationSize *= 2; +ConnectionTranslation = xnfreallocarray(ConnectionTranslation, ConnectionTranslationSize, sizeof (int)); +} ConnectionTranslation[fd] = client->index; #else SetConnectionTranslation(fd, client->index); @@ -825,6 +783,7 @@ EstablishNewConnections(ClientPtr clientUnused, void *closure) OsCommPtr oc; XtransConnInfo trans_conn, new_trans_conn; int status; +int clientid; connect_time = GetTimeInMillis(); /* kill off stragglers */ @@ -846,17 +805,9 @@ EstablishNewConnections(ClientPtr clientUnused, void *closure) newconn = _XSERVTransGetConnectionNumber(new_trans_conn); -if (newconn < lastfdesc) { -int clientid; - -#if !defined(WIN32) -clientid = ConnectionTranslation[newconn]; -#else -clientid = GetConnectionTranslation(newconn); -#endif -if (clientid && (client = clients[c
[PATCH xserver 19/23] os: Switch server to poll(2)
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(_clients); xorg_list_init(_ready_clients); +xorg_list_init(_pending_clients); } Bool @@ -3413,6 +3415,7 @@ CloseDownClient(ClientPtr client) UngrabServer(client); } mark_client_not_ready(client); +xorg_list_del(>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(>ready); +xorg_list_init(>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(>output_pending)) +xorg_list_append(>output_pending, _pending_clients); +} + +static inline void +output_pending_clear(ClientPtr client) +{ +xorg_list_del(>output_pending); +} + +static inline Bool any_output_pending(void) { +return !xorg_list_is_empty(_pending_clients); +} + +static inline Bool client_output_pending(ClientPtr client) +{ +return !xorg_list_is_empty(>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 #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(); -FD_ZERO(); +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(, ); -XFD_UNSET(, ); } else { timeout = -1; @@ -195,57 +190,39 @@ WaitForSomething(Bool are_ready) timeout = 0; } } -XFD_COPYSET(, ); } BlockHandler(); -if (timeout < 0) -wt = NULL; -else { -waittime.tv_sec = timeout / MILLI_PER_SECOND; -waittime.tv_usec = (timeout % MILLI_PER_SECOND) * -(100 / MILLI_PER_SECOND); -wt = -} if (NewOutputPending) FlushAllOutput(); /* keep this check close to select() call to minimize race */ if (dispatchException) i = -1; -else if (AnyWritesPending) { -XFD_COPYSET(, ); -XFD_ORSET(, , ); -i = Select(MaxClients, , , NULL, wt); -} -else { -i = Select(MaxClients, , NULL, NULL, wt); -} -selecte
[PATCH xserver 03/23] xfree86: Switch from select(2) to poll(2)
xf86WaitForInput and the xf86 SIGIO handling code. Signed-off-by: Keith Packard <kei...@keithp.com> --- hw/xfree86/common/xf86Events.c | 1 - hw/xfree86/os-support/shared/posix_tty.c | 33 ++--- hw/xfree86/os-support/shared/sigio.c | 63 +--- 3 files changed, 52 insertions(+), 45 deletions(-) diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c index 7191980..5b4fa23 100644 --- a/hw/xfree86/common/xf86Events.c +++ b/hw/xfree86/common/xf86Events.c @@ -54,7 +54,6 @@ #endif #include -#include #include #include #include "misc.h" diff --git a/hw/xfree86/os-support/shared/posix_tty.c b/hw/xfree86/os-support/shared/posix_tty.c index 6e2af00..d5a70ba 100644 --- a/hw/xfree86/os-support/shared/posix_tty.c +++ b/hw/xfree86/os-support/shared/posix_tty.c @@ -57,6 +57,7 @@ #endif #include +#include #include "xf86.h" #include "xf86Priv.h" #include "xf86_OSlib.h" @@ -387,26 +388,19 @@ xf86CloseSerial(int fd) int xf86WaitForInput(int fd, int timeout) { -fd_set readfds; -struct timeval to; int r; +struct pollfd poll_fd; -FD_ZERO(); +poll_fd.fd = fd; +poll_fd.events = POLLIN; if (fd >= 0) { -FD_SET(fd, ); -} - -to.tv_sec = timeout / 100; -to.tv_usec = timeout % 100; - -if (fd >= 0) { -SYSCALL(r = select(FD_SETSIZE, , NULL, NULL, )); +SYSCALL(r = poll(_fd, 1, timeout)); } else { -SYSCALL(r = select(FD_SETSIZE, NULL, NULL, NULL, )); +SYSCALL(r = poll(_fd, 0, timeout)); } -xf86ErrorFVerb(9, "select returned %d\n", r); +xf86ErrorFVerb(9, "poll returned %d\n", r); return r; } @@ -423,8 +417,7 @@ xf86SerialSendBreak(int fd, int duration) int xf86FlushInput(int fd) { -fd_set fds; -struct timeval timeout; +struct pollfd poll_fd; /* this needs to be big enough to flush an evdev event. */ char c[256]; @@ -432,15 +425,11 @@ xf86FlushInput(int fd) if (tcflush(fd, TCIFLUSH) == 0) return 0; -timeout.tv_sec = 0; -timeout.tv_usec = 0; -FD_ZERO(); -FD_SET(fd, ); -while (select(FD_SETSIZE, , NULL, NULL, ) > 0) { +poll_fd.fd = fd; +poll_fd.events = POLLIN; +while (poll(_fd, 1, 0) > 0) { if (read(fd, , sizeof(c)) < 1) return 0; -FD_ZERO(); -FD_SET(fd, ); } return 0; } diff --git a/hw/xfree86/os-support/shared/sigio.c b/hw/xfree86/os-support/shared/sigio.c index 37d35f7..92054b3 100644 --- a/hw/xfree86/os-support/shared/sigio.c +++ b/hw/xfree86/os-support/shared/sigio.c @@ -57,6 +57,7 @@ #endif #include +#include #include "xf86.h" #include "xf86Priv.h" #include "xf86_OSlib.h" @@ -83,8 +84,35 @@ typedef struct _xf86SigIOFunc { static Xf86SigIOFunc xf86SigIOFuncs[MAX_FUNCS]; static int xf86SigIOMax; -static int xf86SigIOMaxFd; -static fd_set xf86SigIOMask; +static struct pollfd *xf86SigIOFds; +static int xf86SigIONum; + +static Bool +xf86SigIOAdd(int fd) +{ +struct pollfd *n; + +n = realloc(xf86SigIOFds, (xf86SigIONum + 1) * sizeof (struct pollfd)); +if (!n) +return FALSE; + +n[xf86SigIONum].fd = fd; +n[xf86SigIONum].events = POLLIN; +xf86SigIOFds = n; +return TRUE; +} + +static void +xf86SigIORemove(int fd) +{ +int i; +for (i = 0; i < xf86SigIONum; i++) +if (xf86SigIOFds[i].fd == fd) { +memmove([i], [i+1], (xf86SigIONum - i - 1) * sizeof (struct pollfd)); +xf86SigIONum--; +break; +} +} /* * SIGIO gives no way of discovering which fd signalled, select @@ -93,24 +121,22 @@ static fd_set xf86SigIOMask; static void xf86SIGIO(int sig) { -int i; -fd_set ready; -struct timeval to; +int i, f; int save_errno = errno; /* do not clobber the global errno */ int r; inSignalContext = TRUE; -ready = xf86SigIOMask; -to.tv_sec = 0; -to.tv_usec = 0; -SYSCALL(r = select(xf86SigIOMaxFd, , 0, 0, )); -for (i = 0; r > 0 && i < xf86SigIOMax; i++) -if (xf86SigIOFuncs[i].f && FD_ISSET(xf86SigIOFuncs[i].fd, )) { -(*xf86SigIOFuncs[i].f) (xf86SigIOFuncs[i].fd, -xf86SigIOFuncs[i].closure); +SYSCALL(r = poll(xf86SigIOFds, xf86SigIONum, 0)); +for (f = 0; r > 0 && f < xf86SigIONum; f++) { +if (xf86SigIOFds[f].revents & POLLIN) { +for (i = 0; i < xf86SigIOMax; i++) +if (xf86SigIOFuncs[i].f && xf86SigIOFuncs[i].fd == xf86SigIOFds[f].fd) +(*xf86SigIOFuncs[i].f) (xf86SigIOFuncs[i].fd, +xf86SigIOFuncs[i].closure); r--; } +} if (r > 0) { xf86Msg(X_ERROR, "SIGIO %d descriptors not
[PATCH xserver 06/23] hw/xfree86: Use NotifyFd for other input fd wakeups
Remove code in xf86Wakeup for dealing with other input and switch to using the new NotifyFd interface. Signed-off-by: Keith Packard <kei...@keithp.com> --- hw/xfree86/common/xf86Events.c | 76 -- 1 file changed, 22 insertions(+), 54 deletions(-) diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c index 5b4fa23..7d3c35f 100644 --- a/hw/xfree86/common/xf86Events.c +++ b/hw/xfree86/common/xf86Events.c @@ -100,8 +100,6 @@ Bool VTSwitchEnabled = TRUE;/* Allows run-time disabling for switches when using the DRI automatic full screen mode.*/ -extern fd_set EnabledDevices; - #ifdef XF86PM extern void (*xf86OSPMClose) (void); #endif @@ -246,45 +244,6 @@ xf86ProcessActionEvent(ActionEvent action, void *arg) void xf86Wakeup(void *blockData, int err, void *pReadmask) { -fd_set *LastSelectMask = (fd_set *) pReadmask; -fd_set devicesWithInput; -InputInfoPtr pInfo; - -if (err >= 0) { - -XFD_ANDSET(, LastSelectMask, ); -if (XFD_ANYSET()) { -pInfo = xf86InputDevs; -while (pInfo) { -if (pInfo->read_input && pInfo->fd >= 0 && -(FD_ISSET(pInfo->fd, ) != 0)) { -input_lock(); - -/* - * Remove the descriptior from the set because more than one - * device may share the same file descriptor. - */ -FD_CLR(pInfo->fd, ); - -pInfo->read_input(pInfo); -input_unlock(); -} -pInfo = pInfo->next; -} -} -} - -if (err >= 0) { /* we don't want the handlers called if select() */ -IHPtr ih, ih_tmp; /* returned with an error condition, do we? */ - -nt_list_for_each_entry_safe(ih, ih_tmp, InputHandlers, next) { -if (ih->enabled && ih->fd >= 0 && ih->ihproc && -(FD_ISSET(ih->fd, ((fd_set *) pReadmask)) != 0)) { -ih->ihproc(ih->fd, ih->data); -} -} -} - if (xf86VTSwitchPending()) xf86VTSwitch(); } @@ -629,6 +588,16 @@ xf86VTSwitch(void) /* Input handler registration */ +static void +xf86InputHandlerNotify(int fd, int ready, void *data) +{ +IHPtr ih = data; + +if (ih->enabled && ih->fd >= 0 && ih->ihproc) { +ih->ihproc(ih->fd, ih->data); +} +} + static void * addInputHandler(int fd, InputHandlerProc proc, void *data) { @@ -646,6 +615,11 @@ addInputHandler(int fd, InputHandlerProc proc, void *data) ih->data = data; ih->enabled = TRUE; +if (!SetNotifyFd(fd, xf86InputHandlerNotify, X_NOTIFY_READ, ih)) { +free(ih); +return NULL; +} + ih->next = InputHandlers; InputHandlers = ih; @@ -657,10 +631,8 @@ xf86AddInputHandler(int fd, InputHandlerProc proc, void *data) { IHPtr ih = addInputHandler(fd, proc, data); -if (ih) { -AddEnabledDevice(fd); +if (ih) ih->is_input = TRUE; -} return ih; } @@ -669,8 +641,6 @@ xf86AddGeneralHandler(int fd, InputHandlerProc proc, void *data) { IHPtr ih = addInputHandler(fd, proc, data); -if (ih) -AddGeneralSocket(fd); return ih; } @@ -700,6 +670,8 @@ removeInputHandler(IHPtr ih) { IHPtr p; +if (ih->fd >= 0) +RemoveNotifyFd(ih->fd); if (ih == InputHandlers) InputHandlers = ih->next; else { @@ -724,8 +696,6 @@ xf86RemoveInputHandler(void *handler) ih = handler; fd = ih->fd; -if (ih->fd >= 0) -RemoveEnabledDevice(ih->fd); removeInputHandler(ih); return fd; @@ -743,8 +713,6 @@ xf86RemoveGeneralHandler(void *handler) ih = handler; fd = ih->fd; -if (ih->fd >= 0) -RemoveGeneralSocket(ih->fd); removeInputHandler(ih); return fd; @@ -761,7 +729,7 @@ xf86DisableInputHandler(void *handler) ih = handler; ih->enabled = FALSE; if (ih->fd >= 0) -RemoveEnabledDevice(ih->fd); +RemoveNotifyFd(ih->fd); } void @@ -775,7 +743,7 @@ xf86DisableGeneralHandler(void *handler) ih = handler; ih->enabled = FALSE; if (ih->fd >= 0) -RemoveGeneralSocket(ih->fd); +RemoveNotifyFd(ih->fd); } void @@ -789,7 +757,7 @@ xf86EnableInputHandler(void *handler) ih = handler; ih->enabled = TRUE; if (ih->fd >= 0) -AddEnabledDevice(ih->fd); +SetNotifyFd(ih->fd, xf86InputHandlerNotify, X_NOTIFY_READ, ih); } void @@ -803,7 +771,7 @@ xf86EnableGeneralHandler(void *handler) ih = handler; ih-&g
[PATCH xserver 16/23] os: Compute timeout in milliseconds instead of struct timeval
The timeout resolution offered in the AdjustWaitForDelay call is only milliseconds, so passing around the timeout as a pointer to a struct timeval is not helpful. Doing everything in milliseconds up to the point of the select call simplifies the code without affecting functionality at all. Signed-off-by: Keith Packard <kei...@keithp.com> --- include/os.h | 3 +-- os/WaitFor.c | 32 ++-- os/utils.c | 21 - 3 files changed, 23 insertions(+), 33 deletions(-) diff --git a/include/os.h b/include/os.h index 51400a9..25e02bf 100644 --- a/include/os.h +++ b/include/os.h @@ -175,8 +175,7 @@ extern _X_EXPORT Bool AddClientOnOpenFD(int /* fd */ ); extern _X_EXPORT CARD32 GetTimeInMillis(void); extern _X_EXPORT CARD64 GetTimeInMicros(void); -extern _X_EXPORT void AdjustWaitForDelay(void *waitTime, - unsigned long newdelay); +extern _X_EXPORT void AdjustWaitForDelay(void *waitTime, int newdelay); typedef struct _OsTimerRec *OsTimerPtr; diff --git a/os/WaitFor.c b/os/WaitFor.c index 26673e4..0ba1d6b 100644 --- a/os/WaitFor.c +++ b/os/WaitFor.c @@ -147,7 +147,7 @@ WaitForSomething(int *pClientsReady) { int i; struct timeval waittime, *wt; -INT32 timeout = 0; +int timeout; fd_set clientsReadable; fd_set clientsWritable; int curclient; @@ -175,17 +175,15 @@ WaitForSomething(int *pClientsReady) if (workQueue) ProcessWorkQueue(); if (XFD_ANYSET()) { +timeout = 0; someReady = TRUE; -waittime.tv_sec = 0; -waittime.tv_usec = 0; -wt = } if (someReady) { XFD_COPYSET(, ); XFD_UNSET(, ); } else { -wt = NULL; +timeout = -1; if (timers) { now = GetTimeInMillis(); timeout = timers->expires - now; @@ -198,16 +196,20 @@ WaitForSomething(int *pClientsReady) timeout = timers->expires - now; if (timeout < 0) timeout = 0; -waittime.tv_sec = timeout / MILLI_PER_SECOND; -waittime.tv_usec = (timeout % MILLI_PER_SECOND) * -(100 / MILLI_PER_SECOND); -wt = } } XFD_COPYSET(, ); } -BlockHandler(); +BlockHandler(); +if (timeout < 0) +wt = NULL; +else { +waittime.tv_sec = timeout / MILLI_PER_SECOND; +waittime.tv_usec = (timeout % MILLI_PER_SECOND) * +(100 / MILLI_PER_SECOND); +wt = +} if (NewOutputPending) FlushAllOutput(); /* keep this check close to select() call to minimize race */ @@ -359,6 +361,16 @@ WaitForSomething(int *pClientsReady) return nready; } +void +AdjustWaitForDelay(void *waitTime, int newdelay) +{ +int *timeoutp = waitTime; +int timeout = *timeoutp; + +if (timeout < 0 || newdelay < timeout) +*timeoutp = newdelay; +} + /* If time has rewound, re-run every affected timer. * Timers might drop out of the list, so we have to restart every time. */ static void diff --git a/os/utils.c b/os/utils.c index 87417e2..4507c9e 100644 --- a/os/utils.c +++ b/os/utils.c @@ -493,27 +493,6 @@ GetTimeInMicros(void) #endif void -AdjustWaitForDelay(void *waitTime, unsigned long newdelay) -{ -static struct timeval delay_val; -struct timeval **wt = (struct timeval **) waitTime; -unsigned long olddelay; - -if (*wt == NULL) { -delay_val.tv_sec = newdelay / 1000; -delay_val.tv_usec = 1000 * (newdelay % 1000); -*wt = _val; -} -else { -olddelay = (*wt)->tv_sec * 1000 + (*wt)->tv_usec / 1000; -if (newdelay < olddelay) { -(*wt)->tv_sec = newdelay / 1000; -(*wt)->tv_usec = 1000 * (newdelay % 1000); -} -} -} - -void UseMsg(void) { ErrorF("use: X [:] [option]\n"); -- 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
[PATCH xserver 18/23] dix: Use list for ready clients
This converts the dispatch loop into using a list of ready clients instead of an array. This changes the WaitForSomething API so that it notifies DIX when a client becomes ready to read, instead of returning the set of ready clients. Signed-off-by: Keith Packard <kei...@keithp.com> --- dix/dispatch.c | 114 +--- include/dixstruct.h | 15 +++ include/os.h| 3 +- os/WaitFor.c| 36 - os/connection.c | 5 ++- 5 files changed, 118 insertions(+), 55 deletions(-) diff --git a/dix/dispatch.c b/dix/dispatch.c index 3237883..a61d7a4 100644 --- a/dix/dispatch.c +++ b/dix/dispatch.c @@ -240,21 +240,76 @@ long SmartLastPrint; void Dispatch(void); -static int -SmartScheduleClient(int *clientReady, int nready) +static struct xorg_list ready_clients; +static struct xorg_list saved_ready_clients; + +static void +init_client_ready(void) +{ +xorg_list_init(_clients); +xorg_list_init(_ready_clients); +} + +Bool +clients_are_ready(void) +{ +return !xorg_list_is_empty(_clients); +} + +/* Client has requests queued or data on the network */ +void +mark_client_ready(ClientPtr client) +{ +if (xorg_list_is_empty(>ready)) +xorg_list_append(>ready, _clients); +} + +/* Client has no requests queued and no data on network */ +void +mark_client_not_ready(ClientPtr client) +{ +xorg_list_del(>ready); +} + +static void +mark_client_grab(ClientPtr grab) +{ +ClientPtr client, tmp; + +xorg_list_for_each_entry_safe(client, tmp, _clients, ready) { +if (client != grab) { +xorg_list_del(>ready); +xorg_list_append(>ready, _ready_clients); +} +} +} + +static void +mark_client_ungrab(void) +{ +ClientPtr client, tmp; + +xorg_list_for_each_entry_safe(client, tmp, _ready_clients, ready) { +xorg_list_del(>ready); +xorg_list_append(>ready, _clients); +} +} + +static ClientPtr +SmartScheduleClient(void) { -int i; -int client; ClientPtr pClient, best = NULL; int bestRobin, robin; long now = SmartScheduleTime; long idle; +int nready = 0; bestRobin = 0; idle = 2 * SmartScheduleSlice; -for (i = 0; i < nready; i++) { -client = clientReady[i]; -pClient = clients[client]; + +xorg_list_for_each_entry(pClient, _clients, ready) { +nready++; + /* Praise clients which haven't run in a while */ if ((now - pClient->smart_stop_tick) >= idle) { if (pClient->smart_priority < 0) @@ -279,12 +334,12 @@ SmartScheduleClient(int *clientReady, int nready) } #ifdef SMART_DEBUG if ((now - SmartLastPrint) >= 5000) -fprintf(stderr, " %2d: %3d", client, pClient->smart_priority); +fprintf(stderr, " %2d: %3d", pClient->index, pClient->smart_priority); #endif } #ifdef SMART_DEBUG if ((now - SmartLastPrint) >= 5000) { -fprintf(stderr, " use %2d\n", best); +fprintf(stderr, " use %2d\n", best->index); SmartLastPrint = now; } #endif @@ -292,9 +347,9 @@ SmartScheduleClient(int *clientReady, int nready) /* * Set current client pointer */ -if (SmartLastClient != pClient) { -pClient->smart_start_tick = now; -SmartLastClient = pClient; +if (SmartLastClient != best) { +best->smart_start_tick = now; +SmartLastClient = best; } /* * Adjust slice @@ -313,7 +368,7 @@ SmartScheduleClient(int *clientReady, int nready) else { SmartScheduleSlice = SmartScheduleInterval; } -return best->index; +return best; } void @@ -336,44 +391,34 @@ DisableLimitedSchedulingLatency(void) void Dispatch(void) { -int *clientReady; /* array of request ready clients */ int result; ClientPtr client; -int nready; HWEventQueuePtr *icheck = checkForInput; long start_tick; nextFreeClientID = 1; nClients = 0; -clientReady = xallocarray(MaxClients, sizeof(int)); -if (!clientReady) -return; - SmartScheduleSlice = SmartScheduleInterval; +init_client_ready(); + while (!dispatchException) { if (*icheck[0] != *icheck[1]) { ProcessInputEvents(); FlushIfCriticalOutputPending(); } -nready = WaitForSomething(clientReady); +if (!WaitForSomething(clients_are_ready())) +continue; -if (nready) { -clientReady[0] = SmartScheduleClient(clientReady, nready); -nready = 1; -} /* * Handle events in round robin fashion, doing input between * each round */ -while (!dispatchException && (--nready >= 0)) { -client = clients[clientReady[nr
[PATCH xserver 08/23] hw/kdrive: Use passed-in fd for kdrive/linux APM monitoring [v2]
This is a cleanup, proposed by Adam Jackson, but wasn't merged with the original NotifyFD changes. Signed-off-by: Keith Packard <kei...@keithp.com> --- hw/kdrive/linux/linux.c | 64 - 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/hw/kdrive/linux/linux.c b/hw/kdrive/linux/linux.c index a52bdef..bc48d8d 100644 --- a/hw/kdrive/linux/linux.c +++ b/hw/kdrive/linux/linux.c @@ -174,41 +174,39 @@ static Bool LinuxApmRunning; static void LinuxApmNotify(int fd, int mask, void *blockData) { -if (LinuxApmFd >= 0) { -apm_event_t event; -Bool running = LinuxApmRunning; -int cmd = APM_IOC_SUSPEND; - -while (read(LinuxApmFd, , sizeof(event)) == sizeof(event)) { -switch (event) { -case APM_SYS_STANDBY: -case APM_USER_STANDBY: -running = FALSE; -cmd = APM_IOC_STANDBY; -break; -case APM_SYS_SUSPEND: -case APM_USER_SUSPEND: -case APM_CRITICAL_SUSPEND: -running = FALSE; -cmd = APM_IOC_SUSPEND; -break; -case APM_NORMAL_RESUME: -case APM_CRITICAL_RESUME: -case APM_STANDBY_RESUME: -running = TRUE; -break; -} -} -if (running && !LinuxApmRunning) { -KdResume(); -LinuxApmRunning = TRUE; -} -else if (!running && LinuxApmRunning) { -KdSuspend(); -LinuxApmRunning = FALSE; -ioctl(LinuxApmFd, cmd, 0); +apm_event_t event; +Bool running = LinuxApmRunning; +int cmd = APM_IOC_SUSPEND; + +while (read(fd, , sizeof(event)) == sizeof(event)) { +switch (event) { +case APM_SYS_STANDBY: +case APM_USER_STANDBY: +running = FALSE; +cmd = APM_IOC_STANDBY; +break; +case APM_SYS_SUSPEND: +case APM_USER_SUSPEND: +case APM_CRITICAL_SUSPEND: +running = FALSE; +cmd = APM_IOC_SUSPEND; +break; +case APM_NORMAL_RESUME: +case APM_CRITICAL_RESUME: +case APM_STANDBY_RESUME: +running = TRUE; +break; } } +if (running && !LinuxApmRunning) { +KdResume(); +LinuxApmRunning = TRUE; +} +else if (!running && LinuxApmRunning) { +KdSuspend(); +LinuxApmRunning = FALSE; +ioctl(fd, cmd, 0); +} } #ifdef FNONBLOCK -- 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
[PATCH xserver 14/23] dix/os: Merge priority computation into SmartScheduleClient
Instead of having scheduling done in two places (one in WaitForSomething, and the other in SmartScheduleClient), just stick all of the scheduling in SmartScheduleClient. Signed-off-by: Keith Packard <kei...@keithp.com> --- dix/dispatch.c | 22 -- os/WaitFor.c | 33 ++--- 2 files changed, 14 insertions(+), 41 deletions(-) diff --git a/dix/dispatch.c b/dix/dispatch.c index 89c0a4e..f005983 100644 --- a/dix/dispatch.c +++ b/dix/dispatch.c @@ -244,15 +244,13 @@ void Dispatch(void); static int SmartScheduleClient(int *clientReady, int nready) { -ClientPtr pClient; int i; int client; -int bestPrio, best = 0; +ClientPtr pClient, best = NULL; int bestRobin, robin; long now = SmartScheduleTime; long idle; -bestPrio = -0x7fff; bestRobin = 0; idle = 2 * SmartScheduleSlice; for (i = 0; i < nready; i++) { @@ -269,11 +267,16 @@ SmartScheduleClient(int *clientReady, int nready) (pClient->index - SmartLastIndex[pClient->smart_priority - SMART_MIN_PRIORITY]) & 0xff; -if (pClient->smart_priority > bestPrio || -(pClient->smart_priority == bestPrio && robin > bestRobin)) { -bestPrio = pClient->smart_priority; + +/* pick the best client */ +if (!best || +pClient->priority > best->priority || +(pClient->priority == best->priority && + (pClient->smart_priority > best->smart_priority || + (pClient->smart_priority == best->smart_priority && robin > bestRobin +{ +best = pClient; bestRobin = robin; -best = client; } #ifdef SMART_DEBUG if ((now - SmartLastPrint) >= 5000) @@ -286,8 +289,7 @@ SmartScheduleClient(int *clientReady, int nready) SmartLastPrint = now; } #endif -pClient = clients[best]; -SmartLastIndex[bestPrio - SMART_MIN_PRIORITY] = pClient->index; +SmartLastIndex[best->smart_priority - SMART_MIN_PRIORITY] = best->index; /* * Set current client pointer */ @@ -312,7 +314,7 @@ SmartScheduleClient(int *clientReady, int nready) else { SmartScheduleSlice = SmartScheduleInterval; } -return best; +return best->index; } void diff --git a/os/WaitFor.c b/os/WaitFor.c index 994edf0..26673e4 100644 --- a/os/WaitFor.c +++ b/os/WaitFor.c @@ -326,17 +326,14 @@ WaitForSomething(int *pClientsReady) if (XFD_ANYSET()) { #ifndef WIN32 for (i = 0; i < howmany(XFD_SETSIZE, NFDBITS); i++) { -int highest_priority = 0; - while (clientsReadable.fds_bits[i]) { -int client_priority, client_index; +int client_index; curclient = mffs(clientsReadable.fds_bits[i]) - 1; client_index = /* raphael: modified */ ConnectionTranslation[curclient + (i * (sizeof(fd_mask) * 8))]; #else -int highest_priority = 0; fd_set savedClientsReadable; XFD_COPYSET(, ); @@ -346,33 +343,7 @@ WaitForSomething(int *pClientsReady) curclient = XFD_FD(, i); client_index = GetConnectionTranslation(curclient); #endif -/* We implement "strict" priorities. - * Only the highest priority client is returned to - * dix. If multiple clients at the same priority are - * ready, they are all returned. This means that an - * aggressive client could take over the server. - * This was not considered a big problem because - * aggressive clients can hose the server in so many - * other ways :) - */ -client_priority = clients[client_index]->priority; -if (nready == 0 || client_priority > highest_priority) { -/* Either we found the first client, or we found - * a client whose priority is greater than all others - * that have been found so far. Either way, we want - * to initialize the list of clients to contain just - * this client. - */ -pClientsReady[0] = client_index; -highest_priority = client_priority; -nready = 1; -} -/* the following if makes sure that multiple same-priority - * clients get batched together - */ -else if (client_priority == highest_priority) { -pClientsReady[nready++] = client_index; -} +pClientsReady[nready++] = client_index; #ifndef WIN32 clientsReadable.fds_bits[i] &= ~(((fd_mask) 1L) << curclient);
[PATCH xserver 11/23] Remove readmask from screen block/wakeup handler
With no users of the interface needing the readmask anymore, we can remove it from the argument passed to these functions. Signed-off-by: Keith Packard <kei...@keithp.com> --- composite/compalloc.c | 4 +-- dix/dixutils.c | 18 -- doc/Xinput.xml | 8 + doc/Xserver-spec.xml| 59 +++-- exa/exa.c | 10 +++--- glamor/glamor.c | 4 +-- hw/kdrive/ephyr/ephyr.c | 4 +-- hw/kdrive/src/kdrive.h | 6 ++-- hw/kdrive/src/kinput.c | 4 +-- hw/xfree86/common/xf86VGAarbiter.c | 10 +++--- hw/xfree86/common/xf86VGAarbiterPriv.h | 6 ++-- hw/xfree86/dri/dri.c| 12 +++ hw/xfree86/dri/dri.h| 7 ++-- hw/xfree86/drivers/modesetting/driver.c | 8 ++--- hw/xfree86/modes/xf86Rotate.c | 5 ++- hw/xquartz/quartzCocoa.m| 8 ++--- hw/xquartz/quartzCommon.h | 5 +-- hw/xwin/win.h | 4 +-- hw/xwin/winwakeup.c | 3 +- include/scrnintstr.h| 11 +++--- mi/misprite.c | 8 ++--- miext/shadow/shadow.c | 4 +-- 22 files changed, 77 insertions(+), 131 deletions(-) diff --git a/composite/compalloc.c b/composite/compalloc.c index 8daded0..e6a203f 100644 --- a/composite/compalloc.c +++ b/composite/compalloc.c @@ -55,13 +55,13 @@ compScreenUpdate(ScreenPtr pScreen) } static void -compBlockHandler(ScreenPtr pScreen, void *pTimeout, void *pReadmask) +compBlockHandler(ScreenPtr pScreen, void *pTimeout) { CompScreenPtr cs = GetCompScreen(pScreen); pScreen->BlockHandler = cs->BlockHandler; compScreenUpdate(pScreen); -(*pScreen->BlockHandler) (pScreen, pTimeout, pReadmask); +(*pScreen->BlockHandler) (pScreen, pTimeout); /* Next damage will restore the block handler */ cs->BlockHandler = NULL; diff --git a/dix/dixutils.c b/dix/dixutils.c index 3d2e7a3..d728929 100644 --- a/dix/dixutils.c +++ b/dix/dixutils.c @@ -385,16 +385,13 @@ BlockHandler(void *pTimeout, void *pReadmask) ++inHandler; for (i = 0; i < numHandlers; i++) if (!handlers[i].deleted) -(*handlers[i].BlockHandler) (handlers[i].blockData, - pTimeout, pReadmask); +(*handlers[i].BlockHandler) (handlers[i].blockData, pTimeout, pReadmask); for (i = 0; i < screenInfo.numGPUScreens; i++) -(*screenInfo.gpuscreens[i]->BlockHandler) (screenInfo.gpuscreens[i], - pTimeout, pReadmask); +(*screenInfo.gpuscreens[i]->BlockHandler) (screenInfo.gpuscreens[i], pTimeout); for (i = 0; i < screenInfo.numScreens; i++) -(*screenInfo.screens[i]->BlockHandler) (screenInfo.screens[i], -pTimeout, pReadmask); +(*screenInfo.screens[i]->BlockHandler) (screenInfo.screens[i], pTimeout); if (handlerDeleted) { for (i = 0; i < numHandlers;) @@ -422,15 +419,12 @@ WakeupHandler(int result, void *pReadmask) ++inHandler; for (i = 0; i < screenInfo.numScreens; i++) -(*screenInfo.screens[i]->WakeupHandler) (screenInfo.screens[i], - result, pReadmask); +(*screenInfo.screens[i]->WakeupHandler) (screenInfo.screens[i], result); for (i = 0; i < screenInfo.numGPUScreens; i++) -(*screenInfo.gpuscreens[i]->WakeupHandler) (screenInfo.gpuscreens[i], -result, pReadmask); +(*screenInfo.gpuscreens[i]->WakeupHandler) (screenInfo.gpuscreens[i], result); for (i = numHandlers - 1; i >= 0; i--) if (!handlers[i].deleted) -(*handlers[i].WakeupHandler) (handlers[i].blockData, - result, pReadmask); +(*handlers[i].WakeupHandler) (handlers[i].blockData, result, pReadmask); if (handlerDeleted) { for (i = 0; i < numHandlers;) if (handlers[i].deleted) { diff --git a/doc/Xinput.xml b/doc/Xinput.xml index 083b109..0e7fbda 100644 --- a/doc/Xinput.xml +++ b/doc/Xinput.xml @@ -210,7 +210,7 @@ A sample InitInput implementation is shown below. InitInput(argc,argv) { -int i, numdevs, ReadInput(); +int i, numdevs; DeviceIntPtr dev; LocalDevice localdevs[LOCAL_MAX_DEVS]; DeviceProc kbdproc, ptrproc, extproc; @@ -224,12 +224,6 @@ InitInput(argc,argv) open_input_devices (numdevs, localdevs); /** - * Register a WakeupHandler to handle input when it is generated. - *
[PATCH xserver 01/23] dix: Switch to the libXfont2 API (v2)
This new libXfont API eliminates exposing internal X server symbols to the font library, replacing those with a struct full of the entire API needed to use that library. v2: Use libXfont2 instead of libXfont_2 Signed-off-by: Keith Packard <kei...@keithp.com> --- Xext/xf86bigfont.c | 4 +- configure.ac | 2 +- dix/dispatch.c | 4 +- dix/dixfonts.c | 323 + dix/main.c | 4 +- glamor/glamor_font.c | 6 +- hw/dmx/dmxfont.c | 9 +- hw/dmx/dmxscrinit.c| 4 +- hw/xfree86/sdksyms.sh | 1 - hw/xnest/Font.c| 7 +- hw/xnest/Init.c| 3 +- include/dixfont.h | 18 +-- include/dixfontstr.h | 1 + include/dixfontstubs.h | 43 --- mi/miglblt.c | 6 +- miext/damage/damage.c | 4 +- os/utils.c | 4 +- 17 files changed, 231 insertions(+), 212 deletions(-) delete mode 100644 include/dixfontstubs.h diff --git a/Xext/xf86bigfont.c b/Xext/xf86bigfont.c index 95b5371..682d84f 100644 --- a/Xext/xf86bigfont.c +++ b/Xext/xf86bigfont.c @@ -439,7 +439,7 @@ ProcXF86BigfontQueryFont(ClientPtr client) #ifdef HAS_SHM if (pDesc && !badSysCall) { *(CARD32 *) (pCI + nCharInfos) = signature; -if (!FontSetPrivate(pFont, FontShmdescIndex, pDesc)) { +if (!xfont2_font_set_private(pFont, FontShmdescIndex, pDesc)) { shmdealloc(pDesc); return BadAlloc; } @@ -723,7 +723,7 @@ XFree86BigfontExtensionInit(void) + (unsigned int) (65536.0 / (RAND_MAX + 1.0) * rand()); /* fprintf(stderr, "signature = 0x%08X\n", signature); */ -FontShmdescIndex = AllocateFontPrivateIndex(); +FontShmdescIndex = xfont2_allocate_font_private_index(); #if !defined(CSRG_BASED) && !defined(__CYGWIN__) pagesize = SHMLBA; diff --git a/configure.ac b/configure.ac index 6c96de2..1a9aa81 100644 --- a/configure.ac +++ b/configure.ac @@ -813,7 +813,7 @@ LIBEGL="egl" LIBGBM="gbm >= 10.2.0" LIBGL="gl >= 7.1.0" LIBXEXT="xext >= 1.0.99.4" -LIBXFONT="xfont >= 1.4.2" +LIBXFONT="xfont2 >= 2.0.0" LIBXI="xi >= 1.2.99.1" LIBXTST="xtst >= 1.0.99.2" LIBPCIACCESS="pciaccess >= 0.12.901" diff --git a/dix/dispatch.c b/dix/dispatch.c index 26122c1..89c0a4e 100644 --- a/dix/dispatch.c +++ b/dix/dispatch.c @@ -108,7 +108,7 @@ int ProcInitialConnection(); #include "windowstr.h" #include -#include +#include #include "dixfontstr.h" #include "gcstruct.h" #include "selection.h" @@ -1286,7 +1286,7 @@ ProcQueryTextExtents(ClientPtr client) return BadLength; length--; } -if (!QueryTextExtents(pFont, length, (unsigned char *) [1], )) +if (!xfont2_query_text_extents(pFont, length, (unsigned char *) [1], )) return BadAlloc; reply = (xQueryTextExtentsReply) { .type = X_Reply, diff --git a/dix/dixfonts.c b/dix/dixfonts.c index 19db141..d217d12 100644 --- a/dix/dixfonts.c +++ b/dix/dixfonts.c @@ -65,6 +65,7 @@ Equipment Corporation. #include "closestr.h" #include "dixfont.h" #include "xace.h" +#include #ifdef XF86BIGFONT #include "xf86bigfontsrv.h" @@ -75,7 +76,7 @@ extern FontPtr defaultFont; static FontPathElementPtr *font_path_elements = (FontPathElementPtr *) 0; static int num_fpes = 0; -static FPEFunctions *fpe_functions = (FPEFunctions *) 0; +static xfont2_fpe_funcs_rec const **fpe_functions; static int num_fpe_types = 0; static unsigned char *font_path_string; @@ -83,7 +84,7 @@ static unsigned char *font_path_string; static int num_slept_fpes = 0; static int size_slept_fpes = 0; static FontPathElementPtr *slept_fpes = (FontPathElementPtr *) 0; -static FontPatternCachePtr patternCache; +static xfont2_pattern_cache_ptr patternCache; static int FontToXError(int err) @@ -108,18 +109,18 @@ static int LoadGlyphs(ClientPtr client, FontPtr pfont, unsigned nchars, int item_size, unsigned char *data) { -if (fpe_functions[pfont->fpe->type].load_glyphs) -return (*fpe_functions[pfont->fpe->type].load_glyphs) +if (fpe_functions[pfont->fpe->type]->load_glyphs) +return (*fpe_functions[pfont->fpe->type]->load_glyphs) (client, pfont, 0, nchars, item_size, data); else return Successful; } void -dixGetGlyphs(FontPtr font, unsigned long count, unsigned char *chars, - FontEncoding fontEncoding, - unsigned long *glyphcount,/* RETURN */ - CharInfoPtr *glyphs) /* RETURN */ +GetGlyphs(FontPtr font, unsigned long count, unsigned char *chars, + FontEncoding fontEncoding, + unsigned long *glyphcount,
[PATCH xserver 00/23] Switch server to poll/epoll
Ok, I've reworked this patch series to try and have it make some semblance of sense. There's two scary patches, 18/23 and 19/23; everything else is pretty self contained. The first patch flips to the new font API: [PATCH xserver 01/23] dix: Switch to the libXfont2 API (v2) Then changes to move from select(2) to poll(2) in various isolated bits of the server: [PATCH xserver 02/23] kdrive: switch from select(2) to poll(2) [PATCH xserver 03/23] xfree86: Switch from select(2) to poll(2) [PATCH xserver 04/23] dmx: Switch from select(2) to poll(2) for input [PATCH xserver 05/23] os: Switch from select(2) to poll(2) in Then a bunch of fixes related to the use of NotifyFd APIs: [PATCH xserver 06/23] hw/xfree86: Use NotifyFd for other input fd [PATCH xserver 07/23] xnest: Use SetNotifyFd to receive events [PATCH xserver 08/23] hw/kdrive: Use passed-in fd for kdrive/linux [PATCH xserver 09/23] modesetting: Use passed-in fd for drm event [PATCH xserver 10/23] dmx: Eliminate use of AddEnabledDevice And, with everyone using NotifyFd outside of OS, all of the fd_set's visible in the API can be removed: [PATCH xserver 11/23] Remove readmask from screen block/wakeup [PATCH xserver 12/23] Remove fd_set from Block/Wakeup handler API [PATCH xserver 13/23] Remove AddEnabledDevice and AddGeneralSocket Next come a few small cleanups in the server to prepare for major surgery ahead: [PATCH xserver 14/23] dix/os: Merge priority computation into [PATCH xserver 15/23] dix: Intermediate GrabServer state [PATCH xserver 16/23] os: Compute timeout in milliseconds instead of Here's the new interface which I've already sent out. Adam Jackson has suggested that perhaps the edge trigger mode could be a hint instead of a requirement. I haven't done that yet, but it seems like it might be reasonable. Nothing is hooked to this in this patch. [PATCH xserver 17/23] os: Add ospoll interface Two patches which change the server to use the new ospoll bits in WaitForSomething. All of the old select mask frobbing is gone. [PATCH xserver 18/23] dix: Use list for ready clients [PATCH xserver 19/23] os: Switch server to poll(2) Next, the input thread is changed over [PATCH xserver 20/23] os: Use poll(2) for input thread Finally, with the server now independent of fd values, a few cleanups [PATCH xserver 21/23] os: eliminate fd value limits for clients [PATCH xserver 22/23] Allow 1024 and 2048 for LimitClients [PATCH xserver 23/23] os: Leave stdin and stdout open -keith ___ 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
[PATCH xserver 12/23] Remove fd_set from Block/Wakeup handler API
This removes the last uses of fd_set from the server interfaces outside of the OS layer itself. Signed-off-by: Keith Packard <kei...@keithp.com> --- Xext/sleepuntil.c | 17 +++-- Xext/sync.c | 12 ++-- dix/dixfonts.c | 7 +++ dix/dixutils.c | 20 ++-- hw/dmx/dmxsync.c| 4 ++-- hw/dmx/input/dmxinputinit.c | 4 ++-- hw/vfb/InitOutput.c | 4 ++-- hw/xfree86/common/xf86Events.c | 2 +- hw/xfree86/common/xf86Init.c| 2 +- hw/xfree86/common/xf86Priv.h| 2 +- hw/xfree86/dri/dri.c| 4 ++-- hw/xfree86/dri/dri.h| 6 ++ hw/xnest/Handlers.c | 4 ++-- hw/xnest/Handlers.h | 5 ++--- hw/xwayland/xwayland.c | 4 ++-- include/dix.h | 26 +- miext/rootless/rootlessScreen.c | 4 ++-- os/WaitFor.c| 4 ++-- 18 files changed, 62 insertions(+), 69 deletions(-) diff --git a/Xext/sleepuntil.c b/Xext/sleepuntil.c index 993c028..68a7a9b 100644 --- a/Xext/sleepuntil.c +++ b/Xext/sleepuntil.c @@ -63,14 +63,11 @@ static void ClientAwaken(ClientPtr /* client */ , static int SertafiedDelete(void * /* value */ , XID /* id */ ); -static void SertafiedBlockHandler(void */* data */ , - OSTimePtr /* wt */ , - void */* LastSelectMask */ -); -static void SertafiedWakeupHandler(void * /* data */ , - int /* i */ , - void * /* LastSelectMask */ -); +static void SertafiedBlockHandler(void *data, + void *timeout); + +static void SertafiedWakeupHandler(void *data, + int i); int ClientSleepUntil(ClientPtr client, @@ -154,7 +151,7 @@ SertafiedDelete(void *value, XID id) } static void -SertafiedBlockHandler(void *data, OSTimePtr wt, void *LastSelectMask) +SertafiedBlockHandler(void *data, void *wt) { SertafiedPtr pReq, pNext; unsigned long delay; @@ -186,7 +183,7 @@ SertafiedBlockHandler(void *data, OSTimePtr wt, void *LastSelectMask) } static void -SertafiedWakeupHandler(void *data, int i, void *LastSelectMask) +SertafiedWakeupHandler(void *data, int i) { SertafiedPtr pReq, pNext; TimeStamp now; diff --git a/Xext/sync.c b/Xext/sync.c index 4c59fea..323b9db 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -2556,8 +2556,8 @@ static XSyncValue *pnext_time; *** Server Block Handler *** code inspired by multibuffer extension (now deprecated) */ - /*ARGSUSED*/ static void -ServertimeBlockHandler(void *env, struct timeval **wt, void *LastSelectMask) +/*ARGSUSED*/ static void +ServertimeBlockHandler(void *env, void *wt) { XSyncValue delay; unsigned long timeout; @@ -2582,8 +2582,8 @@ ServertimeBlockHandler(void *env, struct timeval **wt, void *LastSelectMask) /* *** Wakeup Handler */ - /*ARGSUSED*/ static void -ServertimeWakeupHandler(void *env, int rc, void *LastSelectMask) +/*ARGSUSED*/ static void +ServertimeWakeupHandler(void *env, int rc) { if (pnext_time) { GetTime(); @@ -2658,7 +2658,7 @@ IdleTimeQueryValue(void *pCounter, CARD64 * pValue_return) } static void -IdleTimeBlockHandler(void *pCounter, struct timeval **wt, void *LastSelectMask) +IdleTimeBlockHandler(void *pCounter, void *wt) { SyncCounter *counter = pCounter; IdleCounterPriv *priv = SysCounterGetPrivate(counter); @@ -2751,7 +2751,7 @@ IdleTimeCheckBrackets(SyncCounter *counter, XSyncValue idle, XSyncValue *less, X } static void -IdleTimeWakeupHandler(void *pCounter, int rc, void *LastSelectMask) +IdleTimeWakeupHandler(void *pCounter, int rc) { SyncCounter *counter = pCounter; IdleCounterPriv *priv = SysCounterGetPrivate(counter); diff --git a/dix/dixfonts.c b/dix/dixfonts.c index d217d12..cca92ed 100644 --- a/dix/dixfonts.c +++ b/dix/dixfonts.c @@ -197,7 +197,7 @@ RemoveFontWakeup(FontPathElementPtr fpe) } static void -FontWakeup(void *data, int count, void *LastSelectMask) +FontWakeup(void *data, int count) { int i; FontPathElementPtr fpe; @@ -1918,8 +1918,7 @@ _client_auth_generation(ClientPtr client) static int fs_handlers_installed = 0; static unsigned int last_server_gen; -static void -fs_block_handler(void *blockData, OSTimePtr timeout, void *readmask) +static void fs_block_handler(void *blockData, void *timeout) { FontBlockHandlerProcPtr block_handler = blockData; @@ -2004,7 +2003,7 @@ _init_fs_handlers(FontPathElementPtr fpe, FontBlockHandlerProcPtr block_handler) static void _remove_fs_handlers(FontPathElementPtr fpe, FontBlockHandlerProcPtr block_handler, - Bool all) +Bool all) { if (all) { /* remove the handlers if no one else is using them */ diff
[PATCH xserver 13/23] Remove AddEnabledDevice and AddGeneralSocket APIs
All uses of these interfaces should instead be using the NotifyFd API instead. Signed-off-by: Keith Packard <kei...@keithp.com> --- include/os.h| 8 os/WaitFor.c| 4 +--- os/connection.c | 43 --- 3 files changed, 9 insertions(+), 46 deletions(-) diff --git a/include/os.h b/include/os.h index 20224f1..51400a9 100644 --- a/include/os.h +++ b/include/os.h @@ -143,14 +143,6 @@ extern _X_EXPORT void CheckConnections(void); extern _X_EXPORT void CloseDownConnection(ClientPtr /*client */ ); -extern _X_EXPORT void AddGeneralSocket(int /*fd */ ); - -extern _X_EXPORT void RemoveGeneralSocket(int /*fd */ ); - -extern _X_EXPORT void AddEnabledDevice(int /*fd */ ); - -extern _X_EXPORT void RemoveEnabledDevice(int /*fd */ ); - typedef void (*NotifyFdProcPtr)(int fd, int ready, void *data); #define X_NOTIFY_NONE 0 diff --git a/os/WaitFor.c b/os/WaitFor.c index 5793427..994edf0 100644 --- a/os/WaitFor.c +++ b/os/WaitFor.c @@ -153,7 +153,6 @@ WaitForSomething(int *pClientsReady) int curclient; int selecterr; static int nready; -fd_set devicesReadable; CARD32 now = 0; Bool someReady = FALSE; Bool someNotifyWriteReady = FALSE; @@ -309,14 +308,13 @@ WaitForSomething(int *pClientsReady) } } -XFD_ANDSET(, , ); XFD_ANDSET(, , ); XFD_ANDSET(_set, , ); if (XFD_ANYSET(_set) || someNotifyWriteReady) HandleNotifyFds(); -if (XFD_ANYSET() || XFD_ANYSET()) +if (XFD_ANYSET()) break; /* check here for DDXes that queue events during Block/Wakeup */ if (*checkForInput[0] != *checkForInput[1]) diff --git a/os/connection.c b/os/connection.c index 488672c..cfe641a 100644 --- a/os/connection.c +++ b/os/connection.c @@ -47,8 +47,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) @@ -121,7 +121,6 @@ SOFTWARE. static int lastfdesc; /* maximum file descriptor */ -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 */ @@ -1043,36 +1042,6 @@ CloseDownConnection(ClientPtr client) AuditF("client %d disconnected\n", client->index); } -void -AddGeneralSocket(int fd) -{ -FD_SET(fd, ); -if (GrabInProgress) -FD_SET(fd, ); -} - -void -AddEnabledDevice(int fd) -{ -FD_SET(fd, ); -AddGeneralSocket(fd); -} - -void -RemoveGeneralSocket(int fd) -{ -FD_CLR(fd, ); -if (GrabInProgress) -FD_CLR(fd, ); -} - -void -RemoveEnabledDevice(int fd) -{ -FD_CLR(fd, ); -RemoveGeneralSocket(fd); -} - struct notify_fd { struct xorg_list list; int fd; @@ -1130,9 +1099,13 @@ SetNotifyFd(int fd, NotifyFdProcPtr notify, int mask, void *data) if (changes & X_NOTIFY_READ) { if (mask & X_NOTIFY_READ) { FD_SET(fd, ); -AddGeneralSocket(fd); +FD_SET(fd, ); +if (GrabInProgress) +FD_SET(fd, ); } else { -RemoveGeneralSocket(fd); +FD_CLR(fd, ); +if (GrabInProgress) +FD_CLR(fd, ); FD_CLR(fd, ); } } -- 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
[PATCH xserver 04/23] dmx: Switch from select(2) to poll(2) for input
Signed-off-by: Keith Packard <kei...@keithp.com> --- hw/dmx/input/lnx-ms.c | 19 ++- hw/dmx/input/lnx-ps2.c | 12 +--- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/hw/dmx/input/lnx-ms.c b/hw/dmx/input/lnx-ms.c index 621f0fe..3d028be 100644 --- a/hw/dmx/input/lnx-ms.c +++ b/hw/dmx/input/lnx-ms.c @@ -76,6 +76,7 @@ #include #include #include +#include /*/ /* Define some macros to make it easier to move this file to another @@ -120,10 +121,11 @@ static int msLinuxReadBytes(int fd, unsigned char *buf, int len, int min) { int n, tot; -fd_set set; -struct timeval tv; +struct pollfd poll_fd; tot = 0; +poll_fd.fd = fd; +poll_fd.events = POLLIN; while (len) { n = read(fd, buf, len); if (n > 0) { @@ -133,11 +135,7 @@ msLinuxReadBytes(int fd, unsigned char *buf, int len, int min) } if (tot % min == 0) break; -FD_ZERO(); -FD_SET(fd, ); -tv.tv_sec = 0; -tv.tv_usec = 100 * 1000; -n = select(fd + 1, , 0, 0, ); +n = poll(_fd, 1, 100); if (n <= 0) break; } @@ -246,7 +244,8 @@ msLinuxInit(DevicePtr pDev) if (tcgetattr(priv->fd, >tty) < 0) FATAL1("msLinuxInit: tcgetattr failed (%s)\n", strerror(errno)); -write(priv->fd, "*n", 2); /* 1200 baud */ +i = write(priv->fd, "*n", 2); /* 1200 baud */ +(void) i; usleep(10); } @@ -256,6 +255,7 @@ msLinuxOn(DevicePtr pDev) { GETPRIV; struct termios nTty; +int i; if (priv->fd < 0) msLinuxInit(pDev); @@ -273,7 +273,8 @@ msLinuxOn(DevicePtr pDev) cfsetospeed(, B1200); if (tcsetattr(priv->fd, TCSANOW, ) < 0) FATAL1("msLinuxInit: tcsetattr failed (%s)\n", strerror(errno)); -write(priv->fd, "*V", 2); /* 2 button 3 byte protocol */ +i = write(priv->fd, "*V", 2); /* 2 button 3 byte protocol */ +(void) i; return priv->fd; } diff --git a/hw/dmx/input/lnx-ps2.c b/hw/dmx/input/lnx-ps2.c index dd70cb8..834beb0 100644 --- a/hw/dmx/input/lnx-ps2.c +++ b/hw/dmx/input/lnx-ps2.c @@ -73,6 +73,7 @@ #include #include #include +#include /*/ /* Define some macros to make it easier to move this file to another @@ -116,9 +117,10 @@ static int ps2LinuxReadBytes(int fd, unsigned char *buf, int len, int min) { int n, tot; -fd_set set; -struct timeval tv; +struct pollfd poll_fd; +poll_fd.fd = fd; +poll_fd.events = POLLIN; tot = 0; while (len) { n = read(fd, buf, len); @@ -129,11 +131,7 @@ ps2LinuxReadBytes(int fd, unsigned char *buf, int len, int min) } if (tot % min == 0) break; -FD_ZERO(); -FD_SET(fd, ); -tv.tv_sec = 0; -tv.tv_usec = 100 * 1000; -n = select(fd + 1, , 0, 0, ); +n = poll(_fd, 1, 100); if (n <= 0) break; } -- 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
[PATCH xserver 23/23] os: Leave stdin and stdout open
There's no reason to close these now that we don't care what file descriptors we use. Signed-off-by: Keith Packard <kei...@keithp.com> --- os/osinit.c | 11 --- 1 file changed, 11 deletions(-) diff --git a/os/osinit.c b/os/osinit.c index 6ec2f11..e269957 100644 --- a/os/osinit.c +++ b/os/osinit.c @@ -221,17 +221,6 @@ OsInit(void) #endif #if !defined(XQUARTZ)/* STDIN is already /dev/null and STDOUT/STDERR is managed by console_redirect.c */ -# if defined(__APPLE__) -int devnullfd = open(devnull, O_RDWR, 0); -assert(devnullfd > 2); - -dup2(devnullfd, STDIN_FILENO); -dup2(devnullfd, STDOUT_FILENO); -close(devnullfd); -# elif !defined(__CYGWIN__) -fclose(stdin); -fclose(stdout); -# endif /* * If a write of zero bytes to stderr returns non-zero, i.e. -1, * then writing to stderr failed, and we'll write somewhere else -- 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
[PATCH xserver 05/23] os: Switch from select(2) to poll(2) in ErrorConnMax
This avoids problems if the file descriptor is too large for select(2) Signed-off-by: Keith Packard <kei...@keithp.com> --- os/connection.c | 12 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/os/connection.c b/os/connection.c index 4c1ba4b..488672c 100644 --- a/os/connection.c +++ b/os/connection.c @@ -892,16 +892,12 @@ ErrorConnMax(XtransConnInfo trans_conn) struct iovec iov[3]; char order = 0; int whichbyte = 1; -struct timeval waittime; -fd_set mask; +struct pollfd poll_fd; /* if these seems like a lot of trouble to go to, it probably is */ -waittime.tv_sec = BOTIMEOUT / MILLI_PER_SECOND; -waittime.tv_usec = (BOTIMEOUT % MILLI_PER_SECOND) * -(100 / MILLI_PER_SECOND); -FD_ZERO(); -FD_SET(fd, ); -(void) Select(fd + 1, , NULL, NULL, ); +poll_fd.fd = fd; +poll_fd.events = POLLIN; +(void) poll(_fd, 1, BOTIMEOUT); /* try to read the byte-order of the connection */ (void) _XSERVTransRead(trans_conn, , 1); if (order == 'l' || order == 'B' || order == 'r' || order == 'R') { -- 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
[PATCH xserver 09/23] modesetting: Use passed-in fd for drm event monitoring NotifyFd callback
This is a cleanup, proposed by Adam Jackson, but wasn't merged with the original NotifyFD changes. Signed-off-by: Keith Packard <kei...@keithp.com> --- hw/xfree86/drivers/modesetting/vblank.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/xfree86/drivers/modesetting/vblank.c b/hw/xfree86/drivers/modesetting/vblank.c index 869472a..0727887 100644 --- a/hw/xfree86/drivers/modesetting/vblank.c +++ b/hw/xfree86/drivers/modesetting/vblank.c @@ -253,7 +253,7 @@ ms_drm_socket_handler(int fd, int ready, void *data) if (data == NULL) return; -drmHandleEvent(ms->fd, >event_context); +drmHandleEvent(fd, >event_context); } /* -- 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
[PATCH xserver 02/23] kdrive: switch from select(2) to poll(2)
This avoids fd limits Signed-off-by: Keith Packard <kei...@keithp.com> --- hw/kdrive/fake/mouse.c | 1 - hw/kdrive/linux/evdev.c | 14 +- hw/kdrive/linux/mouse.c | 34 +- hw/kdrive/linux/ms.c| 13 + hw/kdrive/linux/ps2.c | 13 + hw/kdrive/linux/tslib.c | 1 - 6 files changed, 28 insertions(+), 48 deletions(-) diff --git a/hw/kdrive/fake/mouse.c b/hw/kdrive/fake/mouse.c index bb4c25e..564dae4 100644 --- a/hw/kdrive/fake/mouse.c +++ b/hw/kdrive/fake/mouse.c @@ -27,7 +27,6 @@ #include #include #include -#include #include "inputstr.h" #include "scrnintstr.h" #include "kdrive.h" diff --git a/hw/kdrive/linux/evdev.c b/hw/kdrive/linux/evdev.c index 8415772..9590413 100644 --- a/hw/kdrive/linux/evdev.c +++ b/hw/kdrive/linux/evdev.c @@ -27,7 +27,6 @@ #include #include #include -#include #include "inputstr.h" #include "scrnintstr.h" #include "kdrive.h" @@ -444,6 +443,7 @@ EvdevKbdLeds(KdKeyboardInfo * ki, int leds) { struct input_event event; Kevdev *ke; +inti; if (!ki) return; @@ -458,22 +458,26 @@ EvdevKbdLeds(KdKeyboardInfo * ki, int leds) event.type = EV_LED; event.code = LED_CAPSL; event.value = leds & (1 << 0) ? 1 : 0; -write(ke->fd, (char *) , sizeof(event)); +i = write(ke->fd, (char *) , sizeof(event)); +(void) i; event.type = EV_LED; event.code = LED_NUML; event.value = leds & (1 << 1) ? 1 : 0; -write(ke->fd, (char *) , sizeof(event)); +i = write(ke->fd, (char *) , sizeof(event)); +(void) i; event.type = EV_LED; event.code = LED_SCROLLL; event.value = leds & (1 << 2) ? 1 : 0; -write(ke->fd, (char *) , sizeof(event)); +i = write(ke->fd, (char *) , sizeof(event)); +(void) i; event.type = EV_LED; event.code = LED_COMPOSE; event.value = leds & (1 << 3) ? 1 : 0; -write(ke->fd, (char *) , sizeof(event)); +i = write(ke->fd, (char *) , sizeof(event)); +(void) i; } static void diff --git a/hw/kdrive/linux/mouse.c b/hw/kdrive/linux/mouse.c index 2bfe7f2..3508b17 100644 --- a/hw/kdrive/linux/mouse.c +++ b/hw/kdrive/linux/mouse.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include "inputstr.h" #include "scrnintstr.h" #include "kdrive.h" @@ -47,23 +47,15 @@ typedef struct _kbufio { static Bool MouseWaitForReadable(int fd, int timeout) { -fd_set set; -struct timeval tv, *tp; +struct pollfd poll_fd; int n; CARD32 done; done = GetTimeInMillis() + timeout; +poll_fd.fd = fd; +poll_fd.events = POLLIN; for (;;) { -FD_ZERO(); -FD_SET(fd, ); -if (timeout == -1) -tp = 0; -else { -tv.tv_sec = timeout / 1000; -tv.tv_usec = (timeout % 1000) * 1000; -tp = -} -n = select(fd + 1, , 0, 0, tp); +n = poll(_fd, 1, timeout); if (n > 0) return TRUE; if (n < 0 && (errno == EAGAIN || errno == EINTR)) { @@ -139,20 +131,12 @@ MousePeekByte(Kbufio * b, int timeout) static Bool MouseWaitForWritable(int fd, int timeout) { -fd_set set; -struct timeval tv, *tp; +struct pollfd poll_fd; int n; -FD_ZERO(); -FD_SET(fd, ); -if (timeout == -1) -tp = 0; -else { -tv.tv_sec = timeout / 1000; -tv.tv_usec = (timeout % 1000) * 1000; -tp = -} -n = select(fd + 1, 0, , 0, tp); +poll_fd.fd = fd; +poll_fd.events = POLLOUT; +n = poll(_fd, 1, timeout); if (n > 0) return TRUE; return FALSE; diff --git a/hw/kdrive/linux/ms.c b/hw/kdrive/linux/ms.c index e82350a..79e6373 100644 --- a/hw/kdrive/linux/ms.c +++ b/hw/kdrive/linux/ms.c @@ -26,9 +26,9 @@ THE SOFTWARE. #endif #include #include +#include #include #include -#include #include "inputstr.h" #include "scrnintstr.h" #include "kdrive.h" @@ -37,9 +37,10 @@ static int MsReadBytes(int fd, char *buf, int len, int min) { int n, tot; -fd_set set; -struct timeval tv; +struct pollfd poll_fd; +poll_fd.fd = fd; +poll_fd.events = POLLIN; tot = 0; while (len) { n = read(fd, buf, len); @@ -50,11 +51,7 @@ MsReadBytes(int fd, char *buf, int len, int min) } if (tot % min == 0) break; -FD_ZERO(); -FD_SET(fd, ); -tv.tv_sec = 0; -tv.tv_usec = 100 * 1000; -n = select(fd + 1, , 0, 0, ); +n = poll(_fd, 1, 100); if (n <= 0) break; } diff --git a/hw/kdrive/linux/ps2.c b/hw/kdrive/linux/ps2.c index e5417a5..5d4a8eb 100644 --- a/hw/kdrive/linux/ps2.c +++ b/hw/kdrive/linux/ps2.c @@ -2
[PATCH xserver] os: Increase default client buffer to 16kB
This matches a change made in xcb and improves performance for a small increase in memory usage. Signed-off-by: Keith Packard <kei...@keithp.com> --- os/io.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/os/io.c b/os/io.c index 19a449a..d04ebd8 100644 --- a/os/io.c +++ b/os/io.c @@ -132,8 +132,8 @@ static OsCommPtr AvailableInput = (OsCommPtr) NULL; ((xBigReq *)(req))->length) #define MAX_TIMES_PER 10 -#define BUFSIZE 4096 -#define BUFWATERMARK 8192 +#define BUFSIZE 16384 +#define BUFWATERMARK 32768 /* * A lot of the code in this file manipulates a ConnectionInputPtr: -- 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
[PATCH xserver] dix: Call screen block/wakeup handlers closest to blocking [v3]
The screen block and wakeup handlers are the only ones which provide a well known ordering between the wrapping layers; placing these as close as possible to the server blocking provides a way for the driver to control the flow of execution correctly. Switch the shadow code to run in the screen block handler so that it now occurrs just before the server goes to sleep. Switch glamor to call down to the driver after it has executed its own block handler piece, in case the driver needs to perform additional flushing work after glamor has called glFlush. These changes ensure that the following modules update the screen in the correct order: animated cursors(uses RegisterBlockAndWakeupHandlers dynamically) composite (dynamic wrapping) misprite(dynamic wrapping) shadow (static wrapping) glamor (static wrapping) driver (static wrapping) It looks like there's still a bit of confusion between composite and misprite; if composite updates after misprite, then it's possible you'd exit the block handler chain with the cursor left hidden. To fix that, misprite should be wrapping during ScreenInit time and not unwrapping. And composite might as well join in that fun, just to make things consistent. [v2] Unwrap BlockHandler in shadowCloseScreen (ajax) [v3] ephyr: Use screen block handler for flushing changes ephyr needs to make sure it calls glXSwapBuffers after glamor finishes its rendering. As the screen block handler is now called last, we have to use that instead of a registered block/wakeup handler to make sure the GL rendering is done before we copy it to the front buffer. Signed-off-by: Keith Packard <kei...@keithp.com> --- dix/dixutils.c | 23 +-- glamor/glamor.c | 6 +++--- hw/kdrive/ephyr/ephyr.c | 43 +++ hw/kdrive/ephyr/ephyr.h | 2 ++ miext/shadow/shadow.c | 20 +++- miext/shadow/shadow.h | 1 + 6 files changed, 53 insertions(+), 42 deletions(-) diff --git a/dix/dixutils.c b/dix/dixutils.c index b6b0023..3d2e7a3 100644 --- a/dix/dixutils.c +++ b/dix/dixutils.c @@ -383,16 +383,19 @@ BlockHandler(void *pTimeout, void *pReadmask) int i, j; ++inHandler; -for (i = 0; i < screenInfo.numScreens; i++) -(*screenInfo.screens[i]->BlockHandler) (screenInfo.screens[i], -pTimeout, pReadmask); -for (i = 0; i < screenInfo.numGPUScreens; i++) -(*screenInfo.gpuscreens[i]->BlockHandler) (screenInfo.gpuscreens[i], - pTimeout, pReadmask); for (i = 0; i < numHandlers; i++) if (!handlers[i].deleted) (*handlers[i].BlockHandler) (handlers[i].blockData, pTimeout, pReadmask); + +for (i = 0; i < screenInfo.numGPUScreens; i++) +(*screenInfo.gpuscreens[i]->BlockHandler) (screenInfo.gpuscreens[i], + pTimeout, pReadmask); + +for (i = 0; i < screenInfo.numScreens; i++) +(*screenInfo.screens[i]->BlockHandler) (screenInfo.screens[i], +pTimeout, pReadmask); + if (handlerDeleted) { for (i = 0; i < numHandlers;) if (handlers[i].deleted) { @@ -418,16 +421,16 @@ WakeupHandler(int result, void *pReadmask) int i, j; ++inHandler; -for (i = numHandlers - 1; i >= 0; i--) -if (!handlers[i].deleted) -(*handlers[i].WakeupHandler) (handlers[i].blockData, - result, pReadmask); for (i = 0; i < screenInfo.numScreens; i++) (*screenInfo.screens[i]->WakeupHandler) (screenInfo.screens[i], result, pReadmask); for (i = 0; i < screenInfo.numGPUScreens; i++) (*screenInfo.gpuscreens[i]->WakeupHandler) (screenInfo.gpuscreens[i], result, pReadmask); +for (i = numHandlers - 1; i >= 0; i--) +if (!handlers[i].deleted) +(*handlers[i].WakeupHandler) (handlers[i].blockData, + result, pReadmask); if (handlerDeleted) { for (i = 0; i < numHandlers;) if (handlers[i].deleted) { diff --git a/glamor/glamor.c b/glamor/glamor.c index 62b5c3a..7d82ce8 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -264,13 +264,13 @@ _glamor_block_handler(ScreenPtr screen, void *timeout, void *readmask) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); +glamor_make_current(glamor_priv); +glFlush(); + screen->BlockHandler = glamor_priv->saved_procs.block_handler; screen->BlockHandler(screen, timeout, readmask); glamor_priv->saved_
Re: API for using poll/epoll instead of select
Adam Jacksonwrites: > Exposing edge/level in ospoll_add is a bit funky, you're silently > degrading edge to level if the OS backend can't do edge. kqueue could do > it if the code were written, and I suspect win32's WaitForMultipleObjects > could be made to do it if we got really wild, but Solaris doesn't have an > edge-triggered API for this at all (does have port_create which is > basically level-triggered epoll, but). Good comment here. poll(2) doesn't have edge-triggered options either, so the ospoll code emulates that by remembering the previous value and not reporting when it hasn't changed. This requires a call to ospoll_reset_events in io.c to clear the previous value when input runs dry. > If the intent is that asking for edge is an indication that the caller > _can_ use edge-triggers but will work with either then I guess that's > fine. A comment to that effect would be good. Could do it this way as well, and would eliminate the ospoll_reset_events interface. The only cost would be extra calls to the callback for clients which have input and are not getting serviced, which is not a big deal as that doesn't actually happen all that often in normal X usage. dix handles this just fine; checking to see if the client is on the ready list before inserting it. Sounds like a good change to me as it will simplify the poll(2) interface. -- -keith signature.asc Description: PGP signature ___ 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
Re: [PATCH xserver 1/3] glamor: Disable logic ops when doing compositing [v3]
Michel Dänzerwrites: > The glamor_set_composite_texture related change in this patch needs to > be moved to patch 3, or this patch fails to build. With that fixed, > patches 1 & 2 are That was also mentioned by Emil Velikov and was fixed in [v4] 1/3 and [v2] 3/3 > Reviewed-by: Michel Dänzer > > and patch 3 is > > Tested-by: Michel Dänzer Thanks! Pushed to master. -- -keith signature.asc Description: PGP signature ___ 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
Re: [PATCH xserver 1/9] xfree86: Set xf86CrtcConfigRec cursor pointer to NULL in HideCursor
Peter Hutterer <peter.hutte...@who-t.net> writes: >> Signed-off-by: Keith Packard <kei...@keithp.com> > > Acked-by: Peter Hutterer <peter.hutte...@who-t.net> Merged. b64108f..f5670b4 master -> master -- -keith signature.asc Description: PGP signature ___ 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
Performance benefit of epoll over poll
epoll is designed to reduce the cost of having many file descriptors in a process which are mostly idle. The kernel only reports data about active descriptors. I changed MAXCLIENTS from 512 to 2048 so I could get some 'worst case' measurements. I figured x11perf -noop would be a nice test, and then when I saw what the 'Sync time adjustment' was in these situations, I wondered what x11perf -noop -sync would do and was surprised to see that the effect was even larger. Clearly, calling poll with thousands of file descriptors is expensive... -noop -noop -sync clients clients 1 505 2047 1 505 2047 epoll 53e653e653e6140e3 140e3 140e3 poll53e650e634e6140e312e3 2e3 select 43e643e6140e312e3 So, epoll clearly wins when we have a bunch of clients, but both poll and epoll are winning over select because we aren't sending 512 file descriptors into the kernel for it to mull over every time we call select. I want to clean up the patches on my epoll branch before trying to get them merged; there are a couple of false starts left in the branch before I figured out the interface I wanted. -- -keith signature.asc Description: PGP signature ___ 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
Re: [PATCH xserver 3/4] dix: Convert ResourceClientBits to a variable
Mark Kettenis <mark.kette...@xs4all.nl> writes: > Hmm. This is marked as _X_EXPORT, so presumably part of the driver > ABI. Exporting variables like this is generally a bad idea, at least > for ELF DSOs. Copy relocations and all that. even libc exposes a pile of data, including stdin, stderr and stdout, and that seems to work just fine. Switching this from a #define to a exported variable makes the change minimally invasive while solving the problem nicely. Anything more complicated will be harder to understand and end up slower than this solution. I don't see any benefit there. Reviewed-by: Keith Packard <kei...@keithp.com> -- -keith signature.asc Description: PGP signature ___ 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
API for using poll/epoll instead of select
I'm finishing up replacing select with either poll or epoll (or other) and wanted to present the API I've constructed for this work. The goal is to hide the implementation details away from the server so that we can easily swap in OS-specific replacements. I've implemented poll and epoll back ends, and also discovered that winsock2 has a trivial replacment for poll called WSAPoll, so that should be covered as well. It's similar to the NotifyFd interfaces added to the OS layer, but has the ability to support both level-triggered and edge-triggered notifications. Using edge-triggered notifications along with epoll reduces the notifications received from the kernel when the server is busy as only newly ready clients appear. The NotifyFd interfaces are now fairly simple wrappers around this new interface. All of this is on the 'epoll' branch of my X server repository. /* * Copyright © 2016 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #ifndef _OSPOLL_H_ #define _OSPOLL_H_ /* Forward declaration */ struct ospoll; /** * ospoll_wait trigger mode * * @ospoll_trigger_edge * Trigger only when going from no data available * to data available. * * @ospoll_trigger_level * Trigger whenever there is data available */ enum ospoll_trigger { ospoll_trigger_edge ospoll_trigger_level }; /** * Create a new ospoll structure */ struct ospoll * ospoll_create(void); /** * Destroy an ospoll structure * * @param ospoll ospoll to destroy */ void ospoll_destroy(struct ospoll *ospoll); /** * Add a file descriptor to monitor * * @param ospoll ospoll to add to * @param fd File descriptor to monitor * @param trigger Trigger mode for ospoll_wait * @param callbackFunction to call when triggered * @param dataExtra data to pass callback */ Bool ospoll_add(struct ospoll *ospoll, int fd, enum ospoll_trigger trigger, void (*callback)(int fd, short revents, void *data), void *data); /** * Remove a monitored file descriptor * * @param ospoll ospoll to remove from * @param fd File descriptor to stop monitoring */ void ospoll_remove(struct ospoll *ospoll, int fd); /** * Listen on additional events * * @param ospoll ospoll monitoring fd * @param fd File descriptor to change * @param events Additional events to trigger on */ void ospoll_listen(struct ospoll *ospoll, int fd, short events); /** * Stop listening on events * * @param ospoll ospoll monitoring fd * @param fd File descriptor to change * @param events events to stop triggering on */ void ospoll_mute(struct ospoll *ospoll, int fd, short events); /** * Wait for events * * @param ospoll ospoll to wait on * @param timeout < 0 wait forever * = 0 check and return * > 0 timeout in milliseconds * @return < 0 error * = 0 timeout * > 0 number of events delivered */ int ospoll_wait(struct ospoll *ospoll, int timeout); /** * Reset edge trigger status * * @param ospoll ospoll monitoring fd * @param fd file descriptor * * ospoll_reset_events resets the state of an edge-triggered * fd so that ospoll_wait calls will report events again. * * Call this after a read/recv operation reports no more data available. */ void ospoll_reset_events(struct ospoll *ospoll, int fd); /** * Fetch the data associated with an fd * * @param ospoll ospoll monitoring fd * @param fd file descriptor * * @return data parameter passed to ospoll_add call on *
[PATCH xserver 24/25] dmx: Switch from select(2) to poll(2) for input
Signed-off-by: Keith Packard <kei...@keithp.com> --- hw/dmx/input/lnx-ms.c | 19 ++- hw/dmx/input/lnx-ps2.c | 12 +--- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/hw/dmx/input/lnx-ms.c b/hw/dmx/input/lnx-ms.c index 621f0fe..3d028be 100644 --- a/hw/dmx/input/lnx-ms.c +++ b/hw/dmx/input/lnx-ms.c @@ -76,6 +76,7 @@ #include #include #include +#include /*/ /* Define some macros to make it easier to move this file to another @@ -120,10 +121,11 @@ static int msLinuxReadBytes(int fd, unsigned char *buf, int len, int min) { int n, tot; -fd_set set; -struct timeval tv; +struct pollfd poll_fd; tot = 0; +poll_fd.fd = fd; +poll_fd.events = POLLIN; while (len) { n = read(fd, buf, len); if (n > 0) { @@ -133,11 +135,7 @@ msLinuxReadBytes(int fd, unsigned char *buf, int len, int min) } if (tot % min == 0) break; -FD_ZERO(); -FD_SET(fd, ); -tv.tv_sec = 0; -tv.tv_usec = 100 * 1000; -n = select(fd + 1, , 0, 0, ); +n = poll(_fd, 1, 100); if (n <= 0) break; } @@ -246,7 +244,8 @@ msLinuxInit(DevicePtr pDev) if (tcgetattr(priv->fd, >tty) < 0) FATAL1("msLinuxInit: tcgetattr failed (%s)\n", strerror(errno)); -write(priv->fd, "*n", 2); /* 1200 baud */ +i = write(priv->fd, "*n", 2); /* 1200 baud */ +(void) i; usleep(10); } @@ -256,6 +255,7 @@ msLinuxOn(DevicePtr pDev) { GETPRIV; struct termios nTty; +int i; if (priv->fd < 0) msLinuxInit(pDev); @@ -273,7 +273,8 @@ msLinuxOn(DevicePtr pDev) cfsetospeed(, B1200); if (tcsetattr(priv->fd, TCSANOW, ) < 0) FATAL1("msLinuxInit: tcsetattr failed (%s)\n", strerror(errno)); -write(priv->fd, "*V", 2); /* 2 button 3 byte protocol */ +i = write(priv->fd, "*V", 2); /* 2 button 3 byte protocol */ +(void) i; return priv->fd; } diff --git a/hw/dmx/input/lnx-ps2.c b/hw/dmx/input/lnx-ps2.c index dd70cb8..834beb0 100644 --- a/hw/dmx/input/lnx-ps2.c +++ b/hw/dmx/input/lnx-ps2.c @@ -73,6 +73,7 @@ #include #include #include +#include /*/ /* Define some macros to make it easier to move this file to another @@ -116,9 +117,10 @@ static int ps2LinuxReadBytes(int fd, unsigned char *buf, int len, int min) { int n, tot; -fd_set set; -struct timeval tv; +struct pollfd poll_fd; +poll_fd.fd = fd; +poll_fd.events = POLLIN; tot = 0; while (len) { n = read(fd, buf, len); @@ -129,11 +131,7 @@ ps2LinuxReadBytes(int fd, unsigned char *buf, int len, int min) } if (tot % min == 0) break; -FD_ZERO(); -FD_SET(fd, ); -tv.tv_sec = 0; -tv.tv_usec = 100 * 1000; -n = select(fd + 1, , 0, 0, ); +n = poll(_fd, 1, 100); if (n <= 0) break; } -- 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
[PATCH xserver 22/25] kdrive: switch from select(2) to poll(2)
This avoids fd limits Signed-off-by: Keith Packard <kei...@keithp.com> --- hw/kdrive/fake/mouse.c | 1 - hw/kdrive/linux/evdev.c | 14 +- hw/kdrive/linux/mouse.c | 34 +- hw/kdrive/linux/ms.c| 13 + hw/kdrive/linux/ps2.c | 13 + hw/kdrive/linux/tslib.c | 1 - 6 files changed, 28 insertions(+), 48 deletions(-) diff --git a/hw/kdrive/fake/mouse.c b/hw/kdrive/fake/mouse.c index bb4c25e..564dae4 100644 --- a/hw/kdrive/fake/mouse.c +++ b/hw/kdrive/fake/mouse.c @@ -27,7 +27,6 @@ #include #include #include -#include #include "inputstr.h" #include "scrnintstr.h" #include "kdrive.h" diff --git a/hw/kdrive/linux/evdev.c b/hw/kdrive/linux/evdev.c index 8415772..9590413 100644 --- a/hw/kdrive/linux/evdev.c +++ b/hw/kdrive/linux/evdev.c @@ -27,7 +27,6 @@ #include #include #include -#include #include "inputstr.h" #include "scrnintstr.h" #include "kdrive.h" @@ -444,6 +443,7 @@ EvdevKbdLeds(KdKeyboardInfo * ki, int leds) { struct input_event event; Kevdev *ke; +inti; if (!ki) return; @@ -458,22 +458,26 @@ EvdevKbdLeds(KdKeyboardInfo * ki, int leds) event.type = EV_LED; event.code = LED_CAPSL; event.value = leds & (1 << 0) ? 1 : 0; -write(ke->fd, (char *) , sizeof(event)); +i = write(ke->fd, (char *) , sizeof(event)); +(void) i; event.type = EV_LED; event.code = LED_NUML; event.value = leds & (1 << 1) ? 1 : 0; -write(ke->fd, (char *) , sizeof(event)); +i = write(ke->fd, (char *) , sizeof(event)); +(void) i; event.type = EV_LED; event.code = LED_SCROLLL; event.value = leds & (1 << 2) ? 1 : 0; -write(ke->fd, (char *) , sizeof(event)); +i = write(ke->fd, (char *) , sizeof(event)); +(void) i; event.type = EV_LED; event.code = LED_COMPOSE; event.value = leds & (1 << 3) ? 1 : 0; -write(ke->fd, (char *) , sizeof(event)); +i = write(ke->fd, (char *) , sizeof(event)); +(void) i; } static void diff --git a/hw/kdrive/linux/mouse.c b/hw/kdrive/linux/mouse.c index 2bfe7f2..3508b17 100644 --- a/hw/kdrive/linux/mouse.c +++ b/hw/kdrive/linux/mouse.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include "inputstr.h" #include "scrnintstr.h" #include "kdrive.h" @@ -47,23 +47,15 @@ typedef struct _kbufio { static Bool MouseWaitForReadable(int fd, int timeout) { -fd_set set; -struct timeval tv, *tp; +struct pollfd poll_fd; int n; CARD32 done; done = GetTimeInMillis() + timeout; +poll_fd.fd = fd; +poll_fd.events = POLLIN; for (;;) { -FD_ZERO(); -FD_SET(fd, ); -if (timeout == -1) -tp = 0; -else { -tv.tv_sec = timeout / 1000; -tv.tv_usec = (timeout % 1000) * 1000; -tp = -} -n = select(fd + 1, , 0, 0, tp); +n = poll(_fd, 1, timeout); if (n > 0) return TRUE; if (n < 0 && (errno == EAGAIN || errno == EINTR)) { @@ -139,20 +131,12 @@ MousePeekByte(Kbufio * b, int timeout) static Bool MouseWaitForWritable(int fd, int timeout) { -fd_set set; -struct timeval tv, *tp; +struct pollfd poll_fd; int n; -FD_ZERO(); -FD_SET(fd, ); -if (timeout == -1) -tp = 0; -else { -tv.tv_sec = timeout / 1000; -tv.tv_usec = (timeout % 1000) * 1000; -tp = -} -n = select(fd + 1, 0, , 0, tp); +poll_fd.fd = fd; +poll_fd.events = POLLOUT; +n = poll(_fd, 1, timeout); if (n > 0) return TRUE; return FALSE; diff --git a/hw/kdrive/linux/ms.c b/hw/kdrive/linux/ms.c index e82350a..79e6373 100644 --- a/hw/kdrive/linux/ms.c +++ b/hw/kdrive/linux/ms.c @@ -26,9 +26,9 @@ THE SOFTWARE. #endif #include #include +#include #include #include -#include #include "inputstr.h" #include "scrnintstr.h" #include "kdrive.h" @@ -37,9 +37,10 @@ static int MsReadBytes(int fd, char *buf, int len, int min) { int n, tot; -fd_set set; -struct timeval tv; +struct pollfd poll_fd; +poll_fd.fd = fd; +poll_fd.events = POLLIN; tot = 0; while (len) { n = read(fd, buf, len); @@ -50,11 +51,7 @@ MsReadBytes(int fd, char *buf, int len, int min) } if (tot % min == 0) break; -FD_ZERO(); -FD_SET(fd, ); -tv.tv_sec = 0; -tv.tv_usec = 100 * 1000; -n = select(fd + 1, , 0, 0, ); +n = poll(_fd, 1, 100); if (n <= 0) break; } diff --git a/hw/kdrive/linux/ps2.c b/hw/kdrive/linux/ps2.c index e5417a5..5d4a8eb 100644 --- a/hw/kdrive/linux/ps2.c +++ b/hw/kdrive/linux/ps2.c @@ -2
[PATCH xserver 25/25] os: eliminate fd value limits for clients
With no code depending on the range of file descriptors, checking for that can be eliminated. Signed-off-by: Keith Packard <kei...@keithp.com> --- os/connection.c | 74 - os/osdep.h | 37 ++--- 2 files changed, 22 insertions(+), 89 deletions(-) diff --git a/os/connection.c b/os/connection.c index c9e56b7..96f6971 100644 --- a/os/connection.c +++ b/os/connection.c @@ -103,7 +103,6 @@ SOFTWARE. #endif /* WIN32 */ #include "misc.h" /* for typedef of pointer */ #include "osdep.h" -#include #include "opaque.h" #include "dixstruct.h" #include "xace.h" @@ -119,12 +118,9 @@ SOFTWARE. #include "probes.h" -static int lastfdesc; /* maximum file descriptor */ - struct ospoll server_poll; int MaxClients = 0; -int NumNotifyWriteFd; /* Number of NotifyFd members with write set */ Bool NewOutputPending; /* not yet attempted to write some new output */ Bool NoListenAll; /* Don't establish any listening sockets */ @@ -135,8 +131,6 @@ static char dynamic_display[7]; /* display name */ Bool PartialNetwork;/* continue even if unable to bind all addrs */ static Pid_t ParentProcess; -static Bool debug_conns = FALSE; - int GrabInProgress = 0; static void @@ -150,6 +144,7 @@ set_poll_clients(void); #if !defined(WIN32) int *ConnectionTranslation = NULL; +int ConnectionTranslationSize = 0; #else /* * On NT fds are not between 0 and MAXSOCKS, they are unrelated, and there is @@ -264,44 +259,17 @@ lookup_trans_conn(int fd) void InitConnectionLimits(void) { -lastfdesc = -1; - -#ifndef __CYGWIN__ - -#if !defined(XNO_SYSCONF) && defined(_SC_OPEN_MAX) -lastfdesc = sysconf(_SC_OPEN_MAX) - 1; -#endif - -#ifdef HAVE_GETDTABLESIZE -if (lastfdesc < 0) -lastfdesc = getdtablesize() - 1; -#endif - -#ifdef _NFILE -if (lastfdesc < 0) -lastfdesc = _NFILE - 1; -#endif - -#endif /* __CYGWIN__ */ - -/* This is the fallback */ -if (lastfdesc < 0) -lastfdesc = MAXSOCKS; - -if (lastfdesc > MAXCLIENTS) { -lastfdesc = MAXCLIENTS; -if (debug_conns) -ErrorF("REACHED MAXIMUM CLIENTS LIMIT %d\n", LimitClients); -} -MaxClients = lastfdesc; +MaxClients = MAXCLIENTS; #ifdef DEBUG ErrorF("InitConnectionLimits: MaxClients = %d\n", MaxClients); #endif #if !defined(WIN32) -if (!ConnectionTranslation) -ConnectionTranslation = xnfallocarray(lastfdesc + 1, sizeof(int)); +if (!ConnectionTranslation) { +ConnectionTranslation = xnfallocarray(MaxClients, sizeof(int)); +ConnectionTranslationSize = MaxClients; +} #else InitConnectionTranslation(); #endif @@ -382,7 +350,7 @@ CreateWellKnownSockets(void) ospoll_fd_init(_poll); #if !defined(WIN32) -for (i = 0; i < MaxClients; i++) +for (i = 0; i < ConnectionTranslationSize; i++) ConnectionTranslation[i] = 0; #else ClearConnectionTranslation(); @@ -741,14 +709,6 @@ AllocNewConnection(XtransConnInfo trans_conn, int fd, CARD32 conn_time) OsCommPtr oc; ClientPtr client; -if ( -#ifndef WIN32 - fd >= lastfdesc -#else - XFD_SETCOUNT() >= MaxClients -#endif -) -return NullClient; oc = malloc(sizeof(OsCommRec)); if (!oc) return NullClient; @@ -765,6 +725,10 @@ AllocNewConnection(XtransConnInfo trans_conn, int fd, CARD32 conn_time) } client->local = ComputeLocalClient(client); #if !defined(WIN32) +if (fd >= ConnectionTranslationSize) { +ConnectionTranslationSize *= 2; +ConnectionTranslation = xnfreallocarray(ConnectionTranslation, ConnectionTranslationSize, sizeof (int)); +} ConnectionTranslation[fd] = client->index; #else SetConnectionTranslation(fd, client->index); @@ -801,6 +765,7 @@ EstablishNewConnections(ClientPtr clientUnused, void *closure) OsCommPtr oc; XtransConnInfo trans_conn, new_trans_conn; int status; +int clientid; connect_time = GetTimeInMillis(); /* kill off stragglers */ @@ -822,17 +787,9 @@ EstablishNewConnections(ClientPtr clientUnused, void *closure) newconn = _XSERVTransGetConnectionNumber(new_trans_conn); -if (newconn < lastfdesc) { -int clientid; - -#if !defined(WIN32) -clientid = ConnectionTranslation[newconn]; -#else -clientid = GetConnectionTranslation(newconn); -#endif -if (clientid && (client = clients[clientid])) -CloseDownClient(client); -} +clientid = GetConnectionTranslation(newconn); +if (clientid && (client = clients[clientid])) +CloseDownClient(client); _XSERVTransSetOption(new_trans_conn, TRANS_N
[PATCH xserver 20/25] os: Generalize poll fd management code
We want to use this in the input thread too Signed-off-by: Keith Packard <kei...@keithp.com> --- os/WaitFor.c| 10 ++--- os/connection.c | 123 ++-- os/osdep.h | 29 +++-- os/utils.c | 89 4 files changed, 121 insertions(+), 130 deletions(-) diff --git a/os/WaitFor.c b/os/WaitFor.c index a709859..21d9d97 100644 --- a/os/WaitFor.c +++ b/os/WaitFor.c @@ -211,7 +211,7 @@ WaitForSomething(Bool clients_are_ready) if (wt) poll_timeout = wt->tv_sec * 1000 + wt->tv_usec / 1000; -i = poll(poll_fds, poll_fds_num, poll_timeout); +i = poll(server_poll.fds, server_poll.num, poll_timeout); } pollerr = GetErrno(); WakeupHandler(i); @@ -279,11 +279,11 @@ WaitForSomething(Bool clients_are_ready) } } } -for (p = 0; p < poll_fds_num; p++) { -short revents = poll_fds[p].revents; +for (p = 0; p < server_poll.num; p++) { +short revents = server_poll.fds[p].revents; if (revents) { -int client_index = ConnectionTranslation[poll_fds[p].fd]; +int client_index = ConnectionTranslation[server_poll.fds[p].fd]; if (client_index) { if (revents & ~(POLLIN|POLLOUT)) @@ -298,7 +298,7 @@ WaitForSomething(Bool clients_are_ready) } } } else { -HandleNotifyFd(poll_fds[p].fd, revents); +HandleNotifyFd(server_poll.fds[p].fd, revents); } } } diff --git a/os/connection.c b/os/connection.c index 6b74c76..c9e56b7 100644 --- a/os/connection.c +++ b/os/connection.c @@ -121,8 +121,7 @@ SOFTWARE. static int lastfdesc; /* maximum file descriptor */ -struct pollfd *poll_fds; -int poll_fds_num; +struct ospoll server_poll; int MaxClients = 0; int NumNotifyWriteFd; /* Number of NotifyFd members with write set */ @@ -159,10 +158,7 @@ int *ConnectionTranslation = NULL; * list. */ -#undef MAXSOCKS #define MAXSOCKS 512 -#undef MAXSELECT -#define MAXSELECT 512 struct _ct_node { struct _ct_node *next; @@ -292,9 +288,6 @@ InitConnectionLimits(void) if (lastfdesc < 0) lastfdesc = MAXSOCKS; -if (lastfdesc > MAXSELECT) -lastfdesc = MAXSELECT; - if (lastfdesc > MAXCLIENTS) { lastfdesc = MAXCLIENTS; if (debug_conns) @@ -386,7 +379,7 @@ CreateWellKnownSockets(void) int i; int partial; -poll_fd_init(); +ospoll_fd_init(_poll); #if !defined(WIN32) for (i = 0; i < MaxClients; i++) @@ -776,7 +769,7 @@ AllocNewConnection(XtransConnInfo trans_conn, int fd, CARD32 conn_time) #else SetConnectionTranslation(fd, client->index); #endif -poll_fd_add(fd); +ospoll_fd_add(_poll, fd); set_poll_client(client); #ifdef DEBUG @@ -926,7 +919,7 @@ CloseDownFileDescriptor(OsCommPtr oc) #else SetConnectionTranslation(connection, 0); #endif -poll_fd_remove(connection); +ospoll_fd_remove(_poll, connection); } /* @@ -1044,24 +1037,24 @@ SetNotifyFd(int fd, NotifyFdProcPtr notify, int mask, void *data) if (changes & X_NOTIFY_READ) { if (mask & X_NOTIFY_READ) { -poll_fd_add(fd); -poll_fd_listen(fd, POLLIN); +ospoll_fd_add(_poll, fd); +ospoll_fd_listen(_poll, fd, POLLIN); } else { -poll_fd_mute(fd, POLLIN); +ospoll_fd_mute(_poll, fd, POLLIN); } } if (changes & X_NOTIFY_WRITE) { if (mask & X_NOTIFY_WRITE) { -poll_fd_add(fd); -poll_fd_listen(fd, POLLOUT); +ospoll_fd_add(_poll, fd); +ospoll_fd_listen(_poll, fd, POLLOUT); } else { -poll_fd_mute(fd, POLLOUT); +ospoll_fd_mute(_poll, fd, POLLOUT); } } if (mask == 0) { -poll_fd_remove(fd); +ospoll_fd_remove(_poll, fd); xorg_list_del(>list); free(n); } else { @@ -1293,8 +1286,6 @@ AddClientOnOpenFD(int fd) return TRUE; } -static int poll_fds_size; - Bool listen_to_client(ClientPtr client) { @@ -1321,9 +1312,9 @@ set_poll_client(ClientPtr client) OsCommPtr oc = (OsCommPtr) client->osPrivate; if (listen_to_client(client)) -poll_fd_listen(oc->fd, POLLIN); +ospoll_fd_listen(_poll, oc->fd, POLLIN); else -poll_fd_mute(oc->fd, POLLIN); +ospoll_fd_mute(_poll, oc->fd, POLLIN); } static void @@ -1338,91 +1329,3 @@ set_poll_clients(void) } } -static int -poll_fd_find(int fd) -{ -
[PATCH xserver 07/25] dix: Call screen block/wakeup handlers closest to blocking [v2]
The screen block and wakeup handlers are the only ones which provide a well known ordering between the wrapping layers; placing these as close as possible to the server blocking provides a way for the driver to control the flow of execution correctly. Switch the shadow code to run in the screen block handler so that it now occurrs just before the server goes to sleep. Switch glamor to call down to the driver after it has executed its own block handler piece, in case the driver needs to perform additional flushing work after glamor has called glFlush. These changes ensure that the following modules update the screen in the correct order: animated cursors(uses RegisterBlockAndWakeupHandlers dynamically) composite (dynamic wrapping) misprite(dynamic wrapping) shadow (static wrapping) glamor (static wrapping) driver (static wrapping) It looks like there's still a bit of confusion between composite and misprite; if composite updates after misprite, then it's possible you'd exit the block handler chain with the cursor left hidden. To fix that, misprite should be wrapping during ScreenInit time and not unwrapping. And composite might as well join in that fun, just to make things consistent. [v2] Unwrap BlockHandler in shadowCloseScreen (ajax) Signed-off-by: Keith Packard <kei...@keithp.com> --- dix/dixutils.c| 16 glamor/glamor.c | 6 +++--- miext/shadow/shadow.c | 20 +++- miext/shadow/shadow.h | 1 + 4 files changed, 19 insertions(+), 24 deletions(-) diff --git a/dix/dixutils.c b/dix/dixutils.c index 53a7a36..540023c 100644 --- a/dix/dixutils.c +++ b/dix/dixutils.c @@ -383,15 +383,15 @@ BlockHandler(void *pTimeout) int i, j; ++inHandler; -for (i = 0; i < screenInfo.numScreens; i++) -(*screenInfo.screens[i]->BlockHandler) (screenInfo.screens[i], pTimeout); +for (i = 0; i < numHandlers; i++) +if (!handlers[i].deleted) +(*handlers[i].BlockHandler) (handlers[i].blockData, pTimeout); for (i = 0; i < screenInfo.numGPUScreens; i++) (*screenInfo.gpuscreens[i]->BlockHandler) (screenInfo.gpuscreens[i], pTimeout); -for (i = 0; i < numHandlers; i++) -if (!handlers[i].deleted) -(*handlers[i].BlockHandler) (handlers[i].blockData, pTimeout); +for (i = 0; i < screenInfo.numScreens; i++) +(*screenInfo.screens[i]->BlockHandler) (screenInfo.screens[i], pTimeout); if (handlerDeleted) { for (i = 0; i < numHandlers;) @@ -418,13 +418,13 @@ WakeupHandler(int result) int i, j; ++inHandler; -for (i = numHandlers - 1; i >= 0; i--) -if (!handlers[i].deleted) -(*handlers[i].WakeupHandler) (handlers[i].blockData, result); for (i = 0; i < screenInfo.numScreens; i++) (*screenInfo.screens[i]->WakeupHandler) (screenInfo.screens[i], result); for (i = 0; i < screenInfo.numGPUScreens; i++) (*screenInfo.gpuscreens[i]->WakeupHandler) (screenInfo.gpuscreens[i], result); +for (i = numHandlers - 1; i >= 0; i--) +if (!handlers[i].deleted) +(*handlers[i].WakeupHandler) (handlers[i].blockData, result); if (handlerDeleted) { for (i = 0; i < numHandlers;) if (handlers[i].deleted) { diff --git a/glamor/glamor.c b/glamor/glamor.c index ae3f8bd..9e9db3c 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -264,13 +264,13 @@ _glamor_block_handler(ScreenPtr screen, void *timeout) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); +glamor_make_current(glamor_priv); +glFlush(); + screen->BlockHandler = glamor_priv->saved_procs.block_handler; screen->BlockHandler(screen, timeout); glamor_priv->saved_procs.block_handler = screen->BlockHandler; screen->BlockHandler = _glamor_block_handler; - -glamor_make_current(glamor_priv); -glFlush(); } static void diff --git a/miext/shadow/shadow.c b/miext/shadow/shadow.c index 0759298..b8e23da 100644 --- a/miext/shadow/shadow.c +++ b/miext/shadow/shadow.c @@ -65,16 +65,15 @@ shadowRedisplay(ScreenPtr pScreen) } static void -shadowBlockHandler(void *data, void *timeout) +shadowBlockHandler(ScreenPtr pScreen, void *timeout) { -ScreenPtr pScreen = (ScreenPtr) data; +shadowBuf(pScreen); shadowRedisplay(pScreen); -} -static void -shadowWakeupHandler(void *data, int result) -{ +unwrap(pBuf, pScreen, BlockHandler); +pScreen->BlockHandler(pScreen, timeout); +wrap(pBuf, pScreen, BlockHandler); } static void @@ -100,6 +99,7 @@ shadowCloseScreen(ScreenPtr pScreen) unwrap(pBuf, pScreen, GetImage); unwrap(pBuf, pScreen, CloseScreen); +unwrap(pBuf, pScreen, BlockHandler); shadowRemove(pScreen, pBuf->pPixmap); DamageDestroy(pBuf->pDamage); if (p
[PATCH xserver 15/25] Modify ready_client list directly from WaitForSomething
This changes the WaitForSomething API so that it only notifies DIX when a client becomes ready to read. This avoids walking over all existing ready clients to compute the total set each time. Signed-off-by: Keith Packard <kei...@keithp.com> --- dix/dispatch.c | 45 + include/os.h| 3 +-- os/WaitFor.c| 36 +--- os/connection.c | 5 - 4 files changed, 55 insertions(+), 34 deletions(-) diff --git a/dix/dispatch.c b/dix/dispatch.c index 76e392b..e3dc9b2 100644 --- a/dix/dispatch.c +++ b/dix/dispatch.c @@ -241,11 +241,13 @@ long SmartLastPrint; void Dispatch(void); static struct xorg_list ready_clients; +static struct xorg_list saved_ready_clients; static void init_client_ready(void) { xorg_list_init(_clients); +xorg_list_init(_ready_clients); } static Bool @@ -269,6 +271,30 @@ mark_client_not_ready(ClientPtr client) xorg_list_del(>ready); } +static void +mark_client_grab(ClientPtr grab) +{ +ClientPtr client, tmp; + +xorg_list_for_each_entry_safe(client, tmp, _clients, ready) { +if (client != grab) { +xorg_list_del(>ready); +xorg_list_append(>ready, _ready_clients); +} +} +} + +static void +mark_client_ungrab(void) +{ +ClientPtr client, tmp; + +xorg_list_for_each_entry_safe(client, tmp, _ready_clients, ready) { +xorg_list_del(>ready); +xorg_list_append(>ready, _clients); +} +} + static ClientPtr SmartScheduleClient(void) { @@ -365,32 +391,25 @@ DisableLimitedSchedulingLatency(void) void Dispatch(void) { -int *clientReady; /* array of request ready clients */ int result; ClientPtr client; -int nready; HWEventQueuePtr *icheck = checkForInput; long start_tick; nextFreeClientID = 1; nClients = 0; -clientReady = xallocarray(MaxClients, sizeof(int)); -if (!clientReady) -return; - SmartScheduleSlice = SmartScheduleInterval; +init_client_ready(); + while (!dispatchException) { if (*icheck[0] != *icheck[1]) { ProcessInputEvents(); FlushIfCriticalOutputPending(); } -nready = WaitForSomething(clientReady); - -init_client_ready(); -for (result = 0; result < nready; result++) -mark_client_ready(clients[clientReady[result]]); +if (!WaitForSomething(clients_are_ready())) +continue; /* * Handle events in round robin fashion, doing input between @@ -419,6 +438,7 @@ Dispatch(void) /* now, finally, deal with client requests */ result = ReadRequestFromClient(client); if (result <= 0) { +mark_client_not_ready(client); if (result < 0) CloseDownClient(client); break; @@ -481,7 +501,6 @@ Dispatch(void) ddxBeforeReset(); #endif KillAllClients(); -free(clientReady); dispatchException &= ~DE_RESET; SmartScheduleLatencyLimited = 0; ResetOsBuffers(); @@ -1081,6 +1100,7 @@ ProcGrabServer(ClientPtr client) return rc; grabState = GrabActive; grabClient = client; +mark_client_grab(client); if (ServerGrabCallback) { ServerGrabInfoRec grabinfo; @@ -1100,6 +1120,7 @@ UngrabServer(ClientPtr client) grabState = GrabNone; ListenToAllClients(); +mark_client_ungrab(); for (i = mskcnt; --i >= 0 && !grabWaiters[i];); if (i >= 0) { i <<= 5; diff --git a/include/os.h b/include/os.h index 1ede9b9..aeb1034 100644 --- a/include/os.h +++ b/include/os.h @@ -93,8 +93,7 @@ extern _X_EXPORT void (*OsVendorVErrorFProc) (const char *, _X_ATTRIBUTE_PRINTF(1, 0); #endif -extern _X_EXPORT int WaitForSomething(int * /*pClientsReady */ -); +extern _X_EXPORT Bool WaitForSomething(Bool clients_are_ready); extern _X_EXPORT int ReadRequestFromClient(ClientPtr /*client */ ); diff --git a/os/WaitFor.c b/os/WaitFor.c index 26673e4..e78e358 100644 --- a/os/WaitFor.c +++ b/os/WaitFor.c @@ -142,8 +142,8 @@ static volatile OsTimerPtr timers = NULL; * pClientsReady is an array to store ready client->index values into. */ -int -WaitForSomething(int *pClientsReady) +Bool +WaitForSomething(Bool clients_are_ready) { int i; struct timeval waittime, *wt; @@ -154,7 +154,6 @@ WaitForSomething(int *pClientsReady) int selecterr; static int nready; CARD32 now = 0; -Bool someReady = FALSE; Bool someNotifyWriteReady = FALSE; FD_ZERO(); @@ -174,13 +173,11 @@ WaitForSomething(int *pClientsReady) /* deal with any blocked jobs */ if (workQueue) ProcessWorkQueue(); -if (XFD_ANYSET()) { -someReady = TRUE; + +if (clients_are_ready) {
[PATCH xserver 18/25] os: Eliminate code managing fd_set masks for WaitForSomething
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(_clients); xorg_list_init(_ready_clients); +xorg_list_init(_pending_clients); } static Bool @@ -3413,6 +3415,7 @@ CloseDownClient(ClientPtr client) UngrabServer(client); } mark_client_not_ready(client); +xorg_list_del(>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(>ready); +xorg_list_init(>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(>ready); +} + +extern struct xorg_list output_pending_clients; + +static inline void +output_pending_mark(ClientPtr client) +{ +if (xorg_list_is_empty(>output_pending)) +xorg_list_append(>output_pending, _pending_clients); +} + +static inline void +output_pending_clear(ClientPtr client) +{ +xorg_list_del(>output_pending); +} + +static inline Bool any_output_pending(void) { +return !xorg_list_is_empty(_pending_clients); +} + +static inline Bool client_output_pending(ClientPtr client) +{ +return !xorg_list_is_empty(>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 #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 @@ CreateW
[PATCH xserver 13/25] dix/os: Merge priority computation into SmartScheduleClient
Instead of having scheduling done in two places (one in WaitForSomething, and the other in SmartScheduleClient), just stick all of the scheduling in SmartScheduleClient. Signed-off-by: Keith Packard <kei...@keithp.com> --- dix/dispatch.c | 17 ++--- os/WaitFor.c | 33 ++--- 2 files changed, 12 insertions(+), 38 deletions(-) diff --git a/dix/dispatch.c b/dix/dispatch.c index f7ac931..cd1e335 100644 --- a/dix/dispatch.c +++ b/dix/dispatch.c @@ -274,13 +274,11 @@ static ClientPtr SmartScheduleClient(void) { ClientPtr pClient, best = NULL; -int bestPrio; int bestRobin, robin; long now = SmartScheduleTime; long idle; int nready = 0; -bestPrio = -0x7fff; bestRobin = 0; idle = 2 * SmartScheduleSlice; @@ -298,11 +296,16 @@ SmartScheduleClient(void) (pClient->index - SmartLastIndex[pClient->smart_priority - SMART_MIN_PRIORITY]) & 0xff; -if (pClient->smart_priority > bestPrio || -(pClient->smart_priority == bestPrio && robin > bestRobin)) { -bestPrio = pClient->smart_priority; -bestRobin = robin; + +/* pick the best client */ +if (!best || +pClient->priority > best->priority || +(pClient->priority == best->priority && + (pClient->smart_priority > best->smart_priority || + (pClient->smart_priority == best->smart_priority && robin > bestRobin +{ best = pClient; +bestRobin = robin; } #ifdef SMART_DEBUG if ((now - SmartLastPrint) >= 5000) @@ -315,7 +318,7 @@ SmartScheduleClient(void) SmartLastPrint = now; } #endif -SmartLastIndex[bestPrio - SMART_MIN_PRIORITY] = best->index; +SmartLastIndex[best->smart_priority - SMART_MIN_PRIORITY] = best->index; /* * Set current client pointer */ diff --git a/os/WaitFor.c b/os/WaitFor.c index 994edf0..26673e4 100644 --- a/os/WaitFor.c +++ b/os/WaitFor.c @@ -326,17 +326,14 @@ WaitForSomething(int *pClientsReady) if (XFD_ANYSET()) { #ifndef WIN32 for (i = 0; i < howmany(XFD_SETSIZE, NFDBITS); i++) { -int highest_priority = 0; - while (clientsReadable.fds_bits[i]) { -int client_priority, client_index; +int client_index; curclient = mffs(clientsReadable.fds_bits[i]) - 1; client_index = /* raphael: modified */ ConnectionTranslation[curclient + (i * (sizeof(fd_mask) * 8))]; #else -int highest_priority = 0; fd_set savedClientsReadable; XFD_COPYSET(, ); @@ -346,33 +343,7 @@ WaitForSomething(int *pClientsReady) curclient = XFD_FD(, i); client_index = GetConnectionTranslation(curclient); #endif -/* We implement "strict" priorities. - * Only the highest priority client is returned to - * dix. If multiple clients at the same priority are - * ready, they are all returned. This means that an - * aggressive client could take over the server. - * This was not considered a big problem because - * aggressive clients can hose the server in so many - * other ways :) - */ -client_priority = clients[client_index]->priority; -if (nready == 0 || client_priority > highest_priority) { -/* Either we found the first client, or we found - * a client whose priority is greater than all others - * that have been found so far. Either way, we want - * to initialize the list of clients to contain just - * this client. - */ -pClientsReady[0] = client_index; -highest_priority = client_priority; -nready = 1; -} -/* the following if makes sure that multiple same-priority - * clients get batched together - */ -else if (client_priority == highest_priority) { -pClientsReady[nready++] = client_index; -} +pClientsReady[nready++] = client_index; #ifndef WIN32 clientsReadable.fds_bits[i] &= ~(((fd_mask) 1L) << curclient); } -- 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
[PATCH xserver 04/25] modesetting: Use passed-in fd for drm event monitoring NotifyFd callback
This is a cleanup, proposed by Adam Jackson, but wasn't merged with the original NotifyFD changes. Signed-off-by: Keith Packard <kei...@keithp.com> --- hw/xfree86/drivers/modesetting/vblank.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/xfree86/drivers/modesetting/vblank.c b/hw/xfree86/drivers/modesetting/vblank.c index 869472a..0727887 100644 --- a/hw/xfree86/drivers/modesetting/vblank.c +++ b/hw/xfree86/drivers/modesetting/vblank.c @@ -253,7 +253,7 @@ ms_drm_socket_handler(int fd, int ready, void *data) if (data == NULL) return; -drmHandleEvent(ms->fd, >event_context); +drmHandleEvent(fd, >event_context); } /* -- 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
[PATCH xserver 16/25] ephyr: Use screen block handler for flushing changes
ephyr needs to make sure it calls glXSwapBuffers after glamor finishes its rendering. As the screen block handler is now called last, we have to use that instead of a registered block/wakeup handler to make sure the GL rendering is done before we copy it to the front buffer. Signed-off-by: Keith Packard <kei...@keithp.com> --- hw/kdrive/ephyr/ephyr.c | 43 +++ hw/kdrive/ephyr/ephyr.h | 2 ++ 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c index 6066b5d..a9e700e 100644 --- a/hw/kdrive/ephyr/ephyr.c +++ b/hw/kdrive/ephyr/ephyr.c @@ -337,17 +337,29 @@ ephyrInternalDamageRedisplay(ScreenPtr pScreen) } static void -ephyrInternalDamageBlockHandler(void *data, void *timeout) +ephyrScreenBlockHandler(ScreenPtr pScreen, void *timeout) { -ScreenPtr pScreen = (ScreenPtr) data; +KdScreenPriv(pScreen); +KdScreenInfo *screen = pScreenPriv->screen; +EphyrScrPriv *scrpriv = screen->driver; -ephyrInternalDamageRedisplay(pScreen); -} +pScreen->BlockHandler = scrpriv->BlockHandler; +(*pScreen->BlockHandler)(pScreen, timeout); -static void -ephyrInternalDamageWakeupHandler(void *data, int i) -{ -/* FIXME: Not needed ? */ +if (scrpriv->pDamage) { + +/* Re-wrap if we're still tracking damage + */ +scrpriv->BlockHandler = pScreen->BlockHandler; +pScreen->BlockHandler = ephyrScreenBlockHandler; +ephyrInternalDamageRedisplay(pScreen); +} else { + +/* Done tracking damage, note that we've left + * the block handler unwrapped + */ +scrpriv->BlockHandler = NULL; +} } Bool @@ -362,10 +374,11 @@ ephyrSetInternalDamage(ScreenPtr pScreen) (DamageDestroyFunc) 0, DamageReportNone, TRUE, pScreen, pScreen); -if (!RegisterBlockAndWakeupHandlers(ephyrInternalDamageBlockHandler, -ephyrInternalDamageWakeupHandler, -(void *) pScreen)) -return FALSE; +/* Wrap only once */ +if (scrpriv->BlockHandler == NULL) { +scrpriv->BlockHandler = pScreen->BlockHandler; +pScreen->BlockHandler = ephyrScreenBlockHandler; +} pPixmap = (*pScreen->GetScreenPixmap) (pScreen); @@ -382,10 +395,7 @@ ephyrUnsetInternalDamage(ScreenPtr pScreen) EphyrScrPriv *scrpriv = screen->driver; DamageDestroy(scrpriv->pDamage); - -RemoveBlockAndWakeupHandlers(ephyrInternalDamageBlockHandler, - ephyrInternalDamageWakeupHandler, - (void *) pScreen); +scrpriv->pDamage = NULL; } #ifdef RANDR @@ -736,6 +746,7 @@ ephyrScreenFini(KdScreenInfo * screen) if (scrpriv->shadow) { KdShadowFbFree(screen); } +scrpriv->BlockHandler = NULL; } void diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h index ef5736e..1ec2c69 100644 --- a/hw/kdrive/ephyr/ephyr.h +++ b/hw/kdrive/ephyr/ephyr.h @@ -85,6 +85,8 @@ typedef struct _ephyrScrPriv { int mynum; /* Screen number */ unsigned long cmap[256]; +ScreenBlockHandlerProcPtr BlockHandler; + /** * Per-screen Xlib-using state for glamor (private to * ephyr_glamor_glx.c) -- 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
[PATCH xserver 01/25] hw/xfree86: Use NotifyFd for other input fd wakeups
Remove code in xf86Wakeup for dealing with other input and switch to using the new NotifyFd interface. Signed-off-by: Keith Packard <kei...@keithp.com> --- hw/xfree86/common/xf86Events.c | 76 -- 1 file changed, 22 insertions(+), 54 deletions(-) diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c index 7191980..6f8d763 100644 --- a/hw/xfree86/common/xf86Events.c +++ b/hw/xfree86/common/xf86Events.c @@ -101,8 +101,6 @@ Bool VTSwitchEnabled = TRUE;/* Allows run-time disabling for switches when using the DRI automatic full screen mode.*/ -extern fd_set EnabledDevices; - #ifdef XF86PM extern void (*xf86OSPMClose) (void); #endif @@ -247,45 +245,6 @@ xf86ProcessActionEvent(ActionEvent action, void *arg) void xf86Wakeup(void *blockData, int err, void *pReadmask) { -fd_set *LastSelectMask = (fd_set *) pReadmask; -fd_set devicesWithInput; -InputInfoPtr pInfo; - -if (err >= 0) { - -XFD_ANDSET(, LastSelectMask, ); -if (XFD_ANYSET()) { -pInfo = xf86InputDevs; -while (pInfo) { -if (pInfo->read_input && pInfo->fd >= 0 && -(FD_ISSET(pInfo->fd, ) != 0)) { -input_lock(); - -/* - * Remove the descriptior from the set because more than one - * device may share the same file descriptor. - */ -FD_CLR(pInfo->fd, ); - -pInfo->read_input(pInfo); -input_unlock(); -} -pInfo = pInfo->next; -} -} -} - -if (err >= 0) { /* we don't want the handlers called if select() */ -IHPtr ih, ih_tmp; /* returned with an error condition, do we? */ - -nt_list_for_each_entry_safe(ih, ih_tmp, InputHandlers, next) { -if (ih->enabled && ih->fd >= 0 && ih->ihproc && -(FD_ISSET(ih->fd, ((fd_set *) pReadmask)) != 0)) { -ih->ihproc(ih->fd, ih->data); -} -} -} - if (xf86VTSwitchPending()) xf86VTSwitch(); } @@ -630,6 +589,16 @@ xf86VTSwitch(void) /* Input handler registration */ +static void +xf86InputHandlerNotify(int fd, int ready, void *data) +{ +IHPtr ih = data; + +if (ih->enabled && ih->fd >= 0 && ih->ihproc) { +ih->ihproc(ih->fd, ih->data); +} +} + static void * addInputHandler(int fd, InputHandlerProc proc, void *data) { @@ -647,6 +616,11 @@ addInputHandler(int fd, InputHandlerProc proc, void *data) ih->data = data; ih->enabled = TRUE; +if (!SetNotifyFd(fd, xf86InputHandlerNotify, X_NOTIFY_READ, ih)) { +free(ih); +return NULL; +} + ih->next = InputHandlers; InputHandlers = ih; @@ -658,10 +632,8 @@ xf86AddInputHandler(int fd, InputHandlerProc proc, void *data) { IHPtr ih = addInputHandler(fd, proc, data); -if (ih) { -AddEnabledDevice(fd); +if (ih) ih->is_input = TRUE; -} return ih; } @@ -670,8 +642,6 @@ xf86AddGeneralHandler(int fd, InputHandlerProc proc, void *data) { IHPtr ih = addInputHandler(fd, proc, data); -if (ih) -AddGeneralSocket(fd); return ih; } @@ -701,6 +671,8 @@ removeInputHandler(IHPtr ih) { IHPtr p; +if (ih->fd >= 0) +RemoveNotifyFd(ih->fd); if (ih == InputHandlers) InputHandlers = ih->next; else { @@ -725,8 +697,6 @@ xf86RemoveInputHandler(void *handler) ih = handler; fd = ih->fd; -if (ih->fd >= 0) -RemoveEnabledDevice(ih->fd); removeInputHandler(ih); return fd; @@ -744,8 +714,6 @@ xf86RemoveGeneralHandler(void *handler) ih = handler; fd = ih->fd; -if (ih->fd >= 0) -RemoveGeneralSocket(ih->fd); removeInputHandler(ih); return fd; @@ -762,7 +730,7 @@ xf86DisableInputHandler(void *handler) ih = handler; ih->enabled = FALSE; if (ih->fd >= 0) -RemoveEnabledDevice(ih->fd); +RemoveNotifyFd(ih->fd); } void @@ -776,7 +744,7 @@ xf86DisableGeneralHandler(void *handler) ih = handler; ih->enabled = FALSE; if (ih->fd >= 0) -RemoveGeneralSocket(ih->fd); +RemoveNotifyFd(ih->fd); } void @@ -790,7 +758,7 @@ xf86EnableInputHandler(void *handler) ih = handler; ih->enabled = TRUE; if (ih->fd >= 0) -AddEnabledDevice(ih->fd); +SetNotifyFd(ih->fd, xf86InputHandlerNotify, X_NOTIFY_READ, ih); } void @@ -804,7 +772,7 @@ xf86EnableGeneralHandler(void *handler) ih = handler; ih-&g
[PATCH xserver 05/25] Remove readmask from screen block/wakeup handler
With no users of the interface needing the readmask anymore, we can remove it from the argument passed to these functions. Signed-off-by: Keith Packard <kei...@keithp.com> --- composite/compalloc.c | 4 +-- dix/dixutils.c | 14 doc/Xinput.xml | 8 + doc/Xserver-spec.xml| 59 +++-- exa/exa.c | 10 +++--- glamor/glamor.c | 4 +-- hw/kdrive/src/kdrive.h | 6 ++-- hw/kdrive/src/kinput.c | 4 +-- hw/xfree86/common/xf86VGAarbiter.c | 10 +++--- hw/xfree86/common/xf86VGAarbiterPriv.h | 6 ++-- hw/xfree86/dri/dri.c| 12 +++ hw/xfree86/dri/dri.h| 7 ++-- hw/xfree86/drivers/modesetting/driver.c | 8 ++--- hw/xfree86/modes/xf86Rotate.c | 5 ++- hw/xquartz/quartzCocoa.m| 8 ++--- hw/xquartz/quartzCommon.h | 5 +-- hw/xwin/win.h | 4 +-- hw/xwin/winwakeup.c | 3 +- include/scrnintstr.h| 11 +++--- mi/misprite.c | 8 ++--- 20 files changed, 73 insertions(+), 123 deletions(-) diff --git a/composite/compalloc.c b/composite/compalloc.c index 8daded0..e6a203f 100644 --- a/composite/compalloc.c +++ b/composite/compalloc.c @@ -55,13 +55,13 @@ compScreenUpdate(ScreenPtr pScreen) } static void -compBlockHandler(ScreenPtr pScreen, void *pTimeout, void *pReadmask) +compBlockHandler(ScreenPtr pScreen, void *pTimeout) { CompScreenPtr cs = GetCompScreen(pScreen); pScreen->BlockHandler = cs->BlockHandler; compScreenUpdate(pScreen); -(*pScreen->BlockHandler) (pScreen, pTimeout, pReadmask); +(*pScreen->BlockHandler) (pScreen, pTimeout); /* Next damage will restore the block handler */ cs->BlockHandler = NULL; diff --git a/dix/dixutils.c b/dix/dixutils.c index b6b0023..d357820 100644 --- a/dix/dixutils.c +++ b/dix/dixutils.c @@ -384,11 +384,11 @@ BlockHandler(void *pTimeout, void *pReadmask) ++inHandler; for (i = 0; i < screenInfo.numScreens; i++) -(*screenInfo.screens[i]->BlockHandler) (screenInfo.screens[i], -pTimeout, pReadmask); +(*screenInfo.screens[i]->BlockHandler) (screenInfo.screens[i], pTimeout); + for (i = 0; i < screenInfo.numGPUScreens; i++) -(*screenInfo.gpuscreens[i]->BlockHandler) (screenInfo.gpuscreens[i], - pTimeout, pReadmask); +(*screenInfo.gpuscreens[i]->BlockHandler) (screenInfo.gpuscreens[i], pTimeout); + for (i = 0; i < numHandlers; i++) if (!handlers[i].deleted) (*handlers[i].BlockHandler) (handlers[i].blockData, @@ -423,11 +423,9 @@ WakeupHandler(int result, void *pReadmask) (*handlers[i].WakeupHandler) (handlers[i].blockData, result, pReadmask); for (i = 0; i < screenInfo.numScreens; i++) -(*screenInfo.screens[i]->WakeupHandler) (screenInfo.screens[i], - result, pReadmask); +(*screenInfo.screens[i]->WakeupHandler) (screenInfo.screens[i], result); for (i = 0; i < screenInfo.numGPUScreens; i++) -(*screenInfo.gpuscreens[i]->WakeupHandler) (screenInfo.gpuscreens[i], -result, pReadmask); +(*screenInfo.gpuscreens[i]->WakeupHandler) (screenInfo.gpuscreens[i], result); if (handlerDeleted) { for (i = 0; i < numHandlers;) if (handlers[i].deleted) { diff --git a/doc/Xinput.xml b/doc/Xinput.xml index 083b109..0e7fbda 100644 --- a/doc/Xinput.xml +++ b/doc/Xinput.xml @@ -210,7 +210,7 @@ A sample InitInput implementation is shown below. InitInput(argc,argv) { -int i, numdevs, ReadInput(); +int i, numdevs; DeviceIntPtr dev; LocalDevice localdevs[LOCAL_MAX_DEVS]; DeviceProc kbdproc, ptrproc, extproc; @@ -224,12 +224,6 @@ InitInput(argc,argv) open_input_devices (numdevs, localdevs); /** - * Register a WakeupHandler to handle input when it is generated. - ***/ - -RegisterBlockAndWakeupHandlers (NoopDDA, ReadInput, NULL); - -/** * Register the input devices with DIX. ***/ diff --git a/doc/Xserver-spec.xml b/doc/Xserver-spec.xml index 72a544b..7867544 100644 --- a/doc/Xserver-spec.xml +++ b/doc/Xserver-spec.xml @@ -674,30 +674,22 @@ If WaitForSomething() decides it is about to do something that might block routin
[PATCH xserver 02/25] dix: Switch to the libXfont2 API (v2)
This new libXfont API eliminates exposing internal X server symbols to the font library, replacing those with a struct full of the entire API needed to use that library. v2: Use libXfont2 instead of libXfont_2 Signed-off-by: Keith Packard <kei...@keithp.com> --- Xext/xf86bigfont.c | 4 +- configure.ac | 2 +- dix/dispatch.c | 4 +- dix/dixfonts.c | 323 + dix/main.c | 4 +- glamor/glamor_font.c | 6 +- hw/dmx/dmxfont.c | 9 +- hw/dmx/dmxscrinit.c| 4 +- hw/xfree86/sdksyms.sh | 1 - hw/xnest/Font.c| 7 +- hw/xnest/Init.c| 3 +- include/dixfont.h | 18 +-- include/dixfontstr.h | 1 + include/dixfontstubs.h | 43 --- mi/miglblt.c | 6 +- miext/damage/damage.c | 4 +- os/utils.c | 4 +- 17 files changed, 231 insertions(+), 212 deletions(-) delete mode 100644 include/dixfontstubs.h diff --git a/Xext/xf86bigfont.c b/Xext/xf86bigfont.c index 95b5371..682d84f 100644 --- a/Xext/xf86bigfont.c +++ b/Xext/xf86bigfont.c @@ -439,7 +439,7 @@ ProcXF86BigfontQueryFont(ClientPtr client) #ifdef HAS_SHM if (pDesc && !badSysCall) { *(CARD32 *) (pCI + nCharInfos) = signature; -if (!FontSetPrivate(pFont, FontShmdescIndex, pDesc)) { +if (!xfont2_font_set_private(pFont, FontShmdescIndex, pDesc)) { shmdealloc(pDesc); return BadAlloc; } @@ -723,7 +723,7 @@ XFree86BigfontExtensionInit(void) + (unsigned int) (65536.0 / (RAND_MAX + 1.0) * rand()); /* fprintf(stderr, "signature = 0x%08X\n", signature); */ -FontShmdescIndex = AllocateFontPrivateIndex(); +FontShmdescIndex = xfont2_allocate_font_private_index(); #if !defined(CSRG_BASED) && !defined(__CYGWIN__) pagesize = SHMLBA; diff --git a/configure.ac b/configure.ac index eb0a07c..2176f32 100644 --- a/configure.ac +++ b/configure.ac @@ -814,7 +814,7 @@ LIBEGL="egl" LIBGBM="gbm >= 10.2.0" LIBGL="gl >= 7.1.0" LIBXEXT="xext >= 1.0.99.4" -LIBXFONT="xfont >= 1.4.2" +LIBXFONT="xfont2 >= 2.0.0" LIBXI="xi >= 1.2.99.1" LIBXTST="xtst >= 1.0.99.2" LIBPCIACCESS="pciaccess >= 0.12.901" diff --git a/dix/dispatch.c b/dix/dispatch.c index 26122c1..89c0a4e 100644 --- a/dix/dispatch.c +++ b/dix/dispatch.c @@ -108,7 +108,7 @@ int ProcInitialConnection(); #include "windowstr.h" #include -#include +#include #include "dixfontstr.h" #include "gcstruct.h" #include "selection.h" @@ -1286,7 +1286,7 @@ ProcQueryTextExtents(ClientPtr client) return BadLength; length--; } -if (!QueryTextExtents(pFont, length, (unsigned char *) [1], )) +if (!xfont2_query_text_extents(pFont, length, (unsigned char *) [1], )) return BadAlloc; reply = (xQueryTextExtentsReply) { .type = X_Reply, diff --git a/dix/dixfonts.c b/dix/dixfonts.c index 19db141..d217d12 100644 --- a/dix/dixfonts.c +++ b/dix/dixfonts.c @@ -65,6 +65,7 @@ Equipment Corporation. #include "closestr.h" #include "dixfont.h" #include "xace.h" +#include #ifdef XF86BIGFONT #include "xf86bigfontsrv.h" @@ -75,7 +76,7 @@ extern FontPtr defaultFont; static FontPathElementPtr *font_path_elements = (FontPathElementPtr *) 0; static int num_fpes = 0; -static FPEFunctions *fpe_functions = (FPEFunctions *) 0; +static xfont2_fpe_funcs_rec const **fpe_functions; static int num_fpe_types = 0; static unsigned char *font_path_string; @@ -83,7 +84,7 @@ static unsigned char *font_path_string; static int num_slept_fpes = 0; static int size_slept_fpes = 0; static FontPathElementPtr *slept_fpes = (FontPathElementPtr *) 0; -static FontPatternCachePtr patternCache; +static xfont2_pattern_cache_ptr patternCache; static int FontToXError(int err) @@ -108,18 +109,18 @@ static int LoadGlyphs(ClientPtr client, FontPtr pfont, unsigned nchars, int item_size, unsigned char *data) { -if (fpe_functions[pfont->fpe->type].load_glyphs) -return (*fpe_functions[pfont->fpe->type].load_glyphs) +if (fpe_functions[pfont->fpe->type]->load_glyphs) +return (*fpe_functions[pfont->fpe->type]->load_glyphs) (client, pfont, 0, nchars, item_size, data); else return Successful; } void -dixGetGlyphs(FontPtr font, unsigned long count, unsigned char *chars, - FontEncoding fontEncoding, - unsigned long *glyphcount,/* RETURN */ - CharInfoPtr *glyphs) /* RETURN */ +GetGlyphs(FontPtr font, unsigned long count, unsigned char *chars, + FontEncoding fontEncoding, + unsigned long *glyphcount,
[PATCH xserver 03/25] hw/kdrive: Use passed-in fd for kdrive/linux APM monitoring [v2]
This is a cleanup, proposed by Adam Jackson, but wasn't merged with the original NotifyFD changes. Signed-off-by: Keith Packard <kei...@keithp.com> --- hw/kdrive/linux/linux.c | 64 - 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/hw/kdrive/linux/linux.c b/hw/kdrive/linux/linux.c index a52bdef..bc48d8d 100644 --- a/hw/kdrive/linux/linux.c +++ b/hw/kdrive/linux/linux.c @@ -174,41 +174,39 @@ static Bool LinuxApmRunning; static void LinuxApmNotify(int fd, int mask, void *blockData) { -if (LinuxApmFd >= 0) { -apm_event_t event; -Bool running = LinuxApmRunning; -int cmd = APM_IOC_SUSPEND; - -while (read(LinuxApmFd, , sizeof(event)) == sizeof(event)) { -switch (event) { -case APM_SYS_STANDBY: -case APM_USER_STANDBY: -running = FALSE; -cmd = APM_IOC_STANDBY; -break; -case APM_SYS_SUSPEND: -case APM_USER_SUSPEND: -case APM_CRITICAL_SUSPEND: -running = FALSE; -cmd = APM_IOC_SUSPEND; -break; -case APM_NORMAL_RESUME: -case APM_CRITICAL_RESUME: -case APM_STANDBY_RESUME: -running = TRUE; -break; -} -} -if (running && !LinuxApmRunning) { -KdResume(); -LinuxApmRunning = TRUE; -} -else if (!running && LinuxApmRunning) { -KdSuspend(); -LinuxApmRunning = FALSE; -ioctl(LinuxApmFd, cmd, 0); +apm_event_t event; +Bool running = LinuxApmRunning; +int cmd = APM_IOC_SUSPEND; + +while (read(fd, , sizeof(event)) == sizeof(event)) { +switch (event) { +case APM_SYS_STANDBY: +case APM_USER_STANDBY: +running = FALSE; +cmd = APM_IOC_STANDBY; +break; +case APM_SYS_SUSPEND: +case APM_USER_SUSPEND: +case APM_CRITICAL_SUSPEND: +running = FALSE; +cmd = APM_IOC_SUSPEND; +break; +case APM_NORMAL_RESUME: +case APM_CRITICAL_RESUME: +case APM_STANDBY_RESUME: +running = TRUE; +break; } } +if (running && !LinuxApmRunning) { +KdResume(); +LinuxApmRunning = TRUE; +} +else if (!running && LinuxApmRunning) { +KdSuspend(); +LinuxApmRunning = FALSE; +ioctl(fd, cmd, 0); +} } #ifdef FNONBLOCK -- 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
[PATCH xserver 17/25] os: use poll(2) instead of select(2)
This leaves all of the select file descriptor bashing in place, and just adds the necessary hooks to compute the poll data as well. Signed-off-by: Keith Packard <kei...@keithp.com> --- os/WaitFor.c| 143 ++--- os/connection.c | 214 +++- os/osdep.h | 27 +++ 3 files changed, 277 insertions(+), 107 deletions(-) diff --git a/os/WaitFor.c b/os/WaitFor.c index e78e358..eff2f70 100644 --- a/os/WaitFor.c +++ b/os/WaitFor.c @@ -148,20 +148,19 @@ WaitForSomething(Bool clients_are_ready) int i; struct timeval waittime, *wt; INT32 timeout = 0; -fd_set clientsReadable; -fd_set clientsWritable; -int curclient; -int selecterr; -static int nready; +int pollerr; +static Bool clients_were_ready; +Bool timer_is_running; CARD32 now = 0; -Bool someNotifyWriteReady = FALSE; -FD_ZERO(); -FD_ZERO(); +timer_is_running = clients_were_ready; -if (nready) +if (clients_were_ready && !clients_are_ready) { +timer_is_running = FALSE; SmartScheduleStopTimer(); -nready = 0; +} + +clients_were_ready = FALSE; #ifdef BUSFAULT busfault_check(); @@ -178,8 +177,6 @@ WaitForSomething(Bool clients_are_ready) waittime.tv_sec = 0; waittime.tv_usec = 0; wt = -XFD_COPYSET(, ); -XFD_UNSET(, ); } else { wt = NULL; @@ -201,7 +198,6 @@ WaitForSomething(Bool clients_are_ready) wt = } } -XFD_COPYSET(, ); } BlockHandler(); @@ -210,40 +206,37 @@ WaitForSomething(Bool clients_are_ready) /* keep this check close to select() call to minimize race */ if (dispatchException) i = -1; -else if (AnyWritesPending) { -XFD_COPYSET(, ); -XFD_ORSET(, , ); -i = Select(MaxClients, , , NULL, wt); -} -else { -i = Select(MaxClients, , NULL, NULL, wt); +else +{ +int poll_timeout = -1; + +if (wt) +poll_timeout = wt->tv_sec * 1000 + wt->tv_usec / 1000; +i = poll(poll_fds, poll_fds_num, poll_timeout); } -selecterr = GetErrno(); +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()) -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 (clients_are_ready) { /* * If no-one else is home, bail quickly */ -XFD_COPYSET(, ); -XFD_COPYSET(, ); break; } if (*checkForInput[0] != *checkForInput[1]) @@ -267,7 +260,7 @@ WaitForSomething(Bool clients_are_ready) } } else { -fd_set tmp_set; +int p; if (*checkForInput[0] == *checkForInput[1]) { if (timers) { @@ -287,72 +280,44 @@ WaitForSomething(Bool clients_are_ready) } } } - -if (AnyWritesPending) { -XFD_ANDSET(, , ); -if (XFD_ANYSET()) { -NewOutputPending = TRUE; -XFD_ORSET(, , ); -XFD_UNSET(, ); -if (!XFD_ANYSET() && NumNotifyWriteFd == 0) -AnyWritesPending = FALSE; -} -if (NumNotifyWriteFd != 0) { -XFD_ANDSET(_set, , ); -if (XFD_ANYSET(_set)) -someNotifyWriteReady = TRUE; +
[PATCH xserver 06/25] Remove fd_set from Block/Wakeup handler API
This removes the last uses of fd_set from the server interfaces outside of the OS layer itself. Signed-off-by: Keith Packard <kei...@keithp.com> --- Xext/sleepuntil.c | 17 +++-- Xext/sync.c | 12 ++-- dix/dixfonts.c | 7 +++ dix/dixutils.c | 23 +++ hw/dmx/dmxsync.c| 4 ++-- hw/dmx/input/dmxinputinit.c | 4 ++-- hw/kdrive/ephyr/ephyr.c | 4 ++-- hw/vfb/InitOutput.c | 4 ++-- hw/xfree86/common/xf86Events.c | 2 +- hw/xfree86/common/xf86Init.c| 2 +- hw/xfree86/common/xf86Priv.h| 2 +- hw/xfree86/dri/dri.c| 4 ++-- hw/xfree86/dri/dri.h| 6 ++ hw/xnest/Handlers.c | 4 ++-- hw/xnest/Handlers.h | 5 ++--- hw/xwayland/xwayland.c | 4 ++-- include/dix.h | 26 +- miext/rootless/rootlessScreen.c | 4 ++-- miext/shadow/shadow.c | 4 ++-- os/WaitFor.c| 4 ++-- 20 files changed, 67 insertions(+), 75 deletions(-) diff --git a/Xext/sleepuntil.c b/Xext/sleepuntil.c index 993c028..68a7a9b 100644 --- a/Xext/sleepuntil.c +++ b/Xext/sleepuntil.c @@ -63,14 +63,11 @@ static void ClientAwaken(ClientPtr /* client */ , static int SertafiedDelete(void * /* value */ , XID /* id */ ); -static void SertafiedBlockHandler(void */* data */ , - OSTimePtr /* wt */ , - void */* LastSelectMask */ -); -static void SertafiedWakeupHandler(void * /* data */ , - int /* i */ , - void * /* LastSelectMask */ -); +static void SertafiedBlockHandler(void *data, + void *timeout); + +static void SertafiedWakeupHandler(void *data, + int i); int ClientSleepUntil(ClientPtr client, @@ -154,7 +151,7 @@ SertafiedDelete(void *value, XID id) } static void -SertafiedBlockHandler(void *data, OSTimePtr wt, void *LastSelectMask) +SertafiedBlockHandler(void *data, void *wt) { SertafiedPtr pReq, pNext; unsigned long delay; @@ -186,7 +183,7 @@ SertafiedBlockHandler(void *data, OSTimePtr wt, void *LastSelectMask) } static void -SertafiedWakeupHandler(void *data, int i, void *LastSelectMask) +SertafiedWakeupHandler(void *data, int i) { SertafiedPtr pReq, pNext; TimeStamp now; diff --git a/Xext/sync.c b/Xext/sync.c index 4c59fea..323b9db 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -2556,8 +2556,8 @@ static XSyncValue *pnext_time; *** Server Block Handler *** code inspired by multibuffer extension (now deprecated) */ - /*ARGSUSED*/ static void -ServertimeBlockHandler(void *env, struct timeval **wt, void *LastSelectMask) +/*ARGSUSED*/ static void +ServertimeBlockHandler(void *env, void *wt) { XSyncValue delay; unsigned long timeout; @@ -2582,8 +2582,8 @@ ServertimeBlockHandler(void *env, struct timeval **wt, void *LastSelectMask) /* *** Wakeup Handler */ - /*ARGSUSED*/ static void -ServertimeWakeupHandler(void *env, int rc, void *LastSelectMask) +/*ARGSUSED*/ static void +ServertimeWakeupHandler(void *env, int rc) { if (pnext_time) { GetTime(); @@ -2658,7 +2658,7 @@ IdleTimeQueryValue(void *pCounter, CARD64 * pValue_return) } static void -IdleTimeBlockHandler(void *pCounter, struct timeval **wt, void *LastSelectMask) +IdleTimeBlockHandler(void *pCounter, void *wt) { SyncCounter *counter = pCounter; IdleCounterPriv *priv = SysCounterGetPrivate(counter); @@ -2751,7 +2751,7 @@ IdleTimeCheckBrackets(SyncCounter *counter, XSyncValue idle, XSyncValue *less, X } static void -IdleTimeWakeupHandler(void *pCounter, int rc, void *LastSelectMask) +IdleTimeWakeupHandler(void *pCounter, int rc) { SyncCounter *counter = pCounter; IdleCounterPriv *priv = SysCounterGetPrivate(counter); diff --git a/dix/dixfonts.c b/dix/dixfonts.c index d217d12..cca92ed 100644 --- a/dix/dixfonts.c +++ b/dix/dixfonts.c @@ -197,7 +197,7 @@ RemoveFontWakeup(FontPathElementPtr fpe) } static void -FontWakeup(void *data, int count, void *LastSelectMask) +FontWakeup(void *data, int count) { int i; FontPathElementPtr fpe; @@ -1918,8 +1918,7 @@ _client_auth_generation(ClientPtr client) static int fs_handlers_installed = 0; static unsigned int last_server_gen; -static void -fs_block_handler(void *blockData, OSTimePtr timeout, void *readmask) +static void fs_block_handler(void *blockData, void *timeout) { FontBlockHandlerProcPtr block_handler = blockData; @@ -2004,7 +2003,7 @@ _init_fs_handlers(FontPathElementPtr fpe, FontBlockHandlerProcPtr block_handler) static void _remove_fs_handlers(FontPathElementPtr fpe, FontBlockHandlerProcPtr block_handler, - Bool all) +Bo
[PATCH xserver 12/25] dix: Use list for ready clients
This converts the dispatch loop into using a list of ready clients instead of an array. For now, that list is constructed from the array returned by WaitForSomething. Signed-off-by: Keith Packard <kei...@keithp.com> --- dix/dispatch.c | 86 ++--- include/dixstruct.h | 8 + 2 files changed, 64 insertions(+), 30 deletions(-) diff --git a/dix/dispatch.c b/dix/dispatch.c index 89c0a4e..f7ac931 100644 --- a/dix/dispatch.c +++ b/dix/dispatch.c @@ -241,23 +241,52 @@ long SmartLastPrint; void Dispatch(void); -static int -SmartScheduleClient(int *clientReady, int nready) +static struct xorg_list ready_clients; + +static void +init_client_ready(void) { -ClientPtr pClient; -int i; -int client; -int bestPrio, best = 0; +xorg_list_init(_clients); +} + +static Bool +clients_are_ready(void) +{ +return !xorg_list_is_empty(_clients); +} + +/* Client has requests queued or data on the network */ +void +mark_client_ready(ClientPtr client) +{ +if (xorg_list_is_empty(>ready)) +xorg_list_append(>ready, _clients); +} + +/* Client has no requests queued and no data on network */ +void +mark_client_not_ready(ClientPtr client) +{ +xorg_list_del(>ready); +} + +static ClientPtr +SmartScheduleClient(void) +{ +ClientPtr pClient, best = NULL; +int bestPrio; int bestRobin, robin; long now = SmartScheduleTime; long idle; +int nready = 0; bestPrio = -0x7fff; bestRobin = 0; idle = 2 * SmartScheduleSlice; -for (i = 0; i < nready; i++) { -client = clientReady[i]; -pClient = clients[client]; + +xorg_list_for_each_entry(pClient, _clients, ready) { +nready++; + /* Praise clients which haven't run in a while */ if ((now - pClient->smart_stop_tick) >= idle) { if (pClient->smart_priority < 0) @@ -273,27 +302,26 @@ SmartScheduleClient(int *clientReady, int nready) (pClient->smart_priority == bestPrio && robin > bestRobin)) { bestPrio = pClient->smart_priority; bestRobin = robin; -best = client; +best = pClient; } #ifdef SMART_DEBUG if ((now - SmartLastPrint) >= 5000) -fprintf(stderr, " %2d: %3d", client, pClient->smart_priority); +fprintf(stderr, " %2d: %3d", pClient->index, pClient->smart_priority); #endif } #ifdef SMART_DEBUG if ((now - SmartLastPrint) >= 5000) { -fprintf(stderr, " use %2d\n", best); +fprintf(stderr, " use %2d\n", best->index); SmartLastPrint = now; } #endif -pClient = clients[best]; -SmartLastIndex[bestPrio - SMART_MIN_PRIORITY] = pClient->index; +SmartLastIndex[bestPrio - SMART_MIN_PRIORITY] = best->index; /* * Set current client pointer */ -if (SmartLastClient != pClient) { -pClient->smart_start_tick = now; -SmartLastClient = pClient; +if (SmartLastClient != best) { +best->smart_start_tick = now; +SmartLastClient = best; } /* * Adjust slice @@ -358,25 +386,22 @@ Dispatch(void) nready = WaitForSomething(clientReady); -if (nready) { -clientReady[0] = SmartScheduleClient(clientReady, nready); -nready = 1; -} +init_client_ready(); +for (result = 0; result < nready; result++) +mark_client_ready(clients[clientReady[result]]); + /* * Handle events in round robin fashion, doing input between * each round */ -while (!dispatchException && (--nready >= 0)) { -client = clients[clientReady[nready]]; -if (!client) { -/* KillClient can cause this to happen */ -continue; -} +if (!dispatchException && clients_are_ready()) { +client = SmartScheduleClient(); + /* GrabServer activation can cause this to be true */ if (grabState == GrabKickout) { grabState = GrabActive; -break; +continue; } isItTimeToYield = FALSE; @@ -450,8 +475,7 @@ Dispatch(void) } } FlushAllOutput(); -client = clients[clientReady[nready]]; -if (client) +if (client == SmartLastClient) client->smart_stop_tick = SmartScheduleTime; } dispatchException &= ~DE_PRIORITYCHANGE; @@ -3370,6 +3394,7 @@ CloseDownClient(ClientPtr client) if (grabState != GrabNone && grabClient == client) { UngrabServer(client); } +mark_client_not_ready(client); BITCLEAR(grabWaiters, client->index);
[PATCH xserver 09/25] dmx: Eliminate use of AddEnabledDevice
Use SetNotifyFd instead, with the hope that someday someone will come fix this to be more efficient -- right now, the wakeup handler is doing the event reading, instead of the notify callback. Signed-off-by: Keith Packard <kei...@keithp.com> --- hw/dmx/input/dmxcommon.c | 17 + hw/dmx/input/dmxsigio.c | 9 +++-- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/hw/dmx/input/dmxcommon.c b/hw/dmx/input/dmxcommon.c index 90154ef..c7aed68 100644 --- a/hw/dmx/input/dmxcommon.c +++ b/hw/dmx/input/dmxcommon.c @@ -480,17 +480,26 @@ dmxCommonXSelect(DMXScreenInfo * dmxScreen, void *closure) return NULL; } +static void +dmxCommonFdNotify(int fd, int ready, void *data) +{ +/* This should process input on this fd, but instead all + * of that is delayed until the block and wakeup handlers are called + */ +; +} + static void * dmxCommonAddEnabledDevice(DMXScreenInfo * dmxScreen, void *closure) { -AddEnabledDevice(XConnectionNumber(dmxScreen->beDisplay)); +SetNotifyFd(XConnectionNumber(dmxScreen->beDisplay), dmxCommonFdNotify, X_NOTIFY_READ, closure); return NULL; } static void * dmxCommonRemoveEnabledDevice(DMXScreenInfo * dmxScreen, void *closure) { -RemoveEnabledDevice(XConnectionNumber(dmxScreen->beDisplay)); +RemoveNotifyFd(XConnectionNumber(dmxScreen->beDisplay)); return NULL; } @@ -504,7 +513,7 @@ dmxCommonMouOn(DevicePtr pDev) priv->eventMask |= DMX_POINTER_EVENT_MASK; if (!priv->be) { XSelectInput(priv->display, priv->window, priv->eventMask); -AddEnabledDevice(XConnectionNumber(priv->display)); +SetNotifyFd(XConnectionNumber(priv->display), dmxCommonFdNotify,X_NOTIFY_READ, pDev); } else { dmxPropertyIterate(priv->be, dmxCommonXSelect, priv); @@ -523,7 +532,7 @@ dmxCommonMouOff(DevicePtr pDev) priv->eventMask &= ~DMX_POINTER_EVENT_MASK; if (!priv->be) { -RemoveEnabledDevice(XConnectionNumber(priv->display)); +RemoveNotifyFd(XConnectionNumber(priv->display)); XSelectInput(priv->display, priv->window, priv->eventMask); } else { diff --git a/hw/dmx/input/dmxsigio.c b/hw/dmx/input/dmxsigio.c index 6ef543c..85eb5b9 100644 --- a/hw/dmx/input/dmxsigio.c +++ b/hw/dmx/input/dmxsigio.c @@ -114,6 +114,11 @@ dmxSigioUnhook(void) } static void +dmxSigioFdNotify(int fd, int ready, void *data) +{ +} + +static void dmxSigioAdd(DMXInputInfo * dmxInput) { int flags; @@ -138,7 +143,7 @@ dmxSigioAdd(DMXInputInfo * dmxInput) flags |= O_ASYNC | O_NONBLOCK; fcntl(fd, F_SETFL, flags); -AddEnabledDevice(fd); +SetNotifyFd(fd, dmxSigioFdNotify, X_NOTIFY_READ, NULL); dmxInput->sigioAdded[i] = TRUE; if (++dmxFdCount == 1) @@ -168,7 +173,7 @@ dmxSigioRemove(DMXInputInfo * dmxInput) int fd = dmxInput->sigioFd[i]; dmxInput->sigioAdded[i] = FALSE; -RemoveEnabledDevice(fd); +RemoveNotifyFd(fd); flags = fcntl(fd, F_GETFL); flags &= ~(O_ASYNC | O_NONBLOCK); -- 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
[PATCH xserver 14/25] dix: Intermediate GrabServer state 'GrabKickout' not needed
The intermediate grabState, "GrabKickout", was used to trigger dispatch into going back to WaitForSomething after doing a GrabServer so that the set of ready clients would be recomputed to match what the server should be processing. As we only process one client per WaitForSomething call, we will always hit WaitForSomething after finishing the current client, and so don't need any special case here. Signed-off-by: Keith Packard <kei...@keithp.com> --- dix/dispatch.c | 8 +--- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/dix/dispatch.c b/dix/dispatch.c index cd1e335..76e392b 100644 --- a/dix/dispatch.c +++ b/dix/dispatch.c @@ -151,7 +151,6 @@ static ClientPtr grabClient; #define GrabNone 0 #define GrabActive 1 -#define GrabKickout 2 static int grabState = GrabNone; static long grabWaiters[mskcnt]; CallbackListPtr ServerGrabCallback = NULL; @@ -401,11 +400,6 @@ Dispatch(void) if (!dispatchException && clients_are_ready()) { client = SmartScheduleClient(); -/* GrabServer activation can cause this to be true */ -if (grabState == GrabKickout) { -grabState = GrabActive; -continue; -} isItTimeToYield = FALSE; start_tick = SmartScheduleTime; @@ -1085,7 +1079,7 @@ ProcGrabServer(ClientPtr client) rc = OnlyListenToOneClient(client); if (rc != Success) return rc; -grabState = GrabKickout; +grabState = GrabActive; grabClient = client; if (ServerGrabCallback) { -- 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
[PATCH xserver 11/25] Remove AddEnabledDevice and AddGeneralSocket APIs
All uses of these interfaces should instead be using the NotifyFd API instead. Signed-off-by: Keith Packard <kei...@keithp.com> --- include/os.h| 8 os/WaitFor.c| 4 +--- os/connection.c | 23 --- 3 files changed, 5 insertions(+), 30 deletions(-) diff --git a/include/os.h b/include/os.h index e9b3709..1ede9b9 100644 --- a/include/os.h +++ b/include/os.h @@ -143,14 +143,6 @@ extern _X_EXPORT void CheckConnections(void); extern _X_EXPORT void CloseDownConnection(ClientPtr /*client */ ); -extern _X_EXPORT void AddGeneralSocket(int /*fd */ ); - -extern _X_EXPORT void RemoveGeneralSocket(int /*fd */ ); - -extern _X_EXPORT void AddEnabledDevice(int /*fd */ ); - -extern _X_EXPORT void RemoveEnabledDevice(int /*fd */ ); - typedef void (*NotifyFdProcPtr)(int fd, int ready, void *data); #define X_NOTIFY_NONE 0 diff --git a/os/WaitFor.c b/os/WaitFor.c index 5793427..994edf0 100644 --- a/os/WaitFor.c +++ b/os/WaitFor.c @@ -153,7 +153,6 @@ WaitForSomething(int *pClientsReady) int curclient; int selecterr; static int nready; -fd_set devicesReadable; CARD32 now = 0; Bool someReady = FALSE; Bool someNotifyWriteReady = FALSE; @@ -309,14 +308,13 @@ WaitForSomething(int *pClientsReady) } } -XFD_ANDSET(, , ); XFD_ANDSET(, , ); XFD_ANDSET(_set, , ); if (XFD_ANYSET(_set) || someNotifyWriteReady) HandleNotifyFds(); -if (XFD_ANYSET() || XFD_ANYSET()) +if (XFD_ANYSET()) break; /* check here for DDXes that queue events during Block/Wakeup */ if (*checkForInput[0] != *checkForInput[1]) diff --git a/os/connection.c b/os/connection.c index 4c1ba4b..b300025 100644 --- a/os/connection.c +++ b/os/connection.c @@ -47,8 +47,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) @@ -121,7 +121,6 @@ SOFTWARE. static int lastfdesc; /* maximum file descriptor */ -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 */ @@ -1047,7 +1046,7 @@ CloseDownConnection(ClientPtr client) AuditF("client %d disconnected\n", client->index); } -void +static void AddGeneralSocket(int fd) { FD_SET(fd, ); @@ -1055,14 +1054,7 @@ AddGeneralSocket(int fd) FD_SET(fd, ); } -void -AddEnabledDevice(int fd) -{ -FD_SET(fd, ); -AddGeneralSocket(fd); -} - -void +static void RemoveGeneralSocket(int fd) { FD_CLR(fd, ); @@ -1070,13 +1062,6 @@ RemoveGeneralSocket(int fd) FD_CLR(fd, ); } -void -RemoveEnabledDevice(int fd) -{ -FD_CLR(fd, ); -RemoveGeneralSocket(fd); -} - struct notify_fd { struct xorg_list list; int fd; -- 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
[PATCH xserver 23/25] xfree86: Switch from select(2) to poll(2)
xf86WaitForInput and the xf86 SIGIO handling code. Signed-off-by: Keith Packard <kei...@keithp.com> --- hw/xfree86/common/xf86Events.c | 1 - hw/xfree86/os-support/shared/posix_tty.c | 33 ++--- hw/xfree86/os-support/shared/sigio.c | 63 +--- 3 files changed, 52 insertions(+), 45 deletions(-) diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c index b12766f..9a8f432 100644 --- a/hw/xfree86/common/xf86Events.c +++ b/hw/xfree86/common/xf86Events.c @@ -54,7 +54,6 @@ #endif #include -#include #include #include #include "misc.h" diff --git a/hw/xfree86/os-support/shared/posix_tty.c b/hw/xfree86/os-support/shared/posix_tty.c index 6e2af00..d5a70ba 100644 --- a/hw/xfree86/os-support/shared/posix_tty.c +++ b/hw/xfree86/os-support/shared/posix_tty.c @@ -57,6 +57,7 @@ #endif #include +#include #include "xf86.h" #include "xf86Priv.h" #include "xf86_OSlib.h" @@ -387,26 +388,19 @@ xf86CloseSerial(int fd) int xf86WaitForInput(int fd, int timeout) { -fd_set readfds; -struct timeval to; int r; +struct pollfd poll_fd; -FD_ZERO(); +poll_fd.fd = fd; +poll_fd.events = POLLIN; if (fd >= 0) { -FD_SET(fd, ); -} - -to.tv_sec = timeout / 100; -to.tv_usec = timeout % 100; - -if (fd >= 0) { -SYSCALL(r = select(FD_SETSIZE, , NULL, NULL, )); +SYSCALL(r = poll(_fd, 1, timeout)); } else { -SYSCALL(r = select(FD_SETSIZE, NULL, NULL, NULL, )); +SYSCALL(r = poll(_fd, 0, timeout)); } -xf86ErrorFVerb(9, "select returned %d\n", r); +xf86ErrorFVerb(9, "poll returned %d\n", r); return r; } @@ -423,8 +417,7 @@ xf86SerialSendBreak(int fd, int duration) int xf86FlushInput(int fd) { -fd_set fds; -struct timeval timeout; +struct pollfd poll_fd; /* this needs to be big enough to flush an evdev event. */ char c[256]; @@ -432,15 +425,11 @@ xf86FlushInput(int fd) if (tcflush(fd, TCIFLUSH) == 0) return 0; -timeout.tv_sec = 0; -timeout.tv_usec = 0; -FD_ZERO(); -FD_SET(fd, ); -while (select(FD_SETSIZE, , NULL, NULL, ) > 0) { +poll_fd.fd = fd; +poll_fd.events = POLLIN; +while (poll(_fd, 1, 0) > 0) { if (read(fd, , sizeof(c)) < 1) return 0; -FD_ZERO(); -FD_SET(fd, ); } return 0; } diff --git a/hw/xfree86/os-support/shared/sigio.c b/hw/xfree86/os-support/shared/sigio.c index e0cd7a8..53ebacf 100644 --- a/hw/xfree86/os-support/shared/sigio.c +++ b/hw/xfree86/os-support/shared/sigio.c @@ -57,6 +57,7 @@ #endif #include +#include #include "xf86.h" #include "xf86Priv.h" #include "xf86_OSlib.h" @@ -83,8 +84,35 @@ typedef struct _xf86SigIOFunc { static Xf86SigIOFunc xf86SigIOFuncs[MAX_FUNCS]; static int xf86SigIOMax; -static int xf86SigIOMaxFd; -static fd_set xf86SigIOMask; +static struct pollfd *xf86SigIOFds; +static int xf86SigIONum; + +static Bool +xf86SigIOAdd(int fd) +{ +struct pollfd *n; + +n = realloc(xf86SigIOFds, (xf86SigIONum + 1) * sizeof (struct pollfd)); +if (!n) +return FALSE; + +n[xf86SigIONum].fd = fd; +n[xf86SigIONum].events = POLLIN; +xf86SigIOFds = n; +return TRUE; +} + +static void +xf86SigIORemove(int fd) +{ +int i; +for (i = 0; i < xf86SigIONum; i++) +if (xf86SigIOFds[i].fd == fd) { +memmove([i], [i+1], (xf86SigIONum - i - 1) * sizeof (struct pollfd)); +xf86SigIONum--; +break; +} +} /* * SIGIO gives no way of discovering which fd signalled, select @@ -93,24 +121,22 @@ static fd_set xf86SigIOMask; static void xf86SIGIO(int sig) { -int i; -fd_set ready; -struct timeval to; +int i, f; int save_errno = errno; /* do not clobber the global errno */ int r; inSignalContext = TRUE; -ready = xf86SigIOMask; -to.tv_sec = 0; -to.tv_usec = 0; -SYSCALL(r = select(xf86SigIOMaxFd, , 0, 0, )); -for (i = 0; r > 0 && i < xf86SigIOMax; i++) -if (xf86SigIOFuncs[i].f && FD_ISSET(xf86SigIOFuncs[i].fd, )) { -(*xf86SigIOFuncs[i].f) (xf86SigIOFuncs[i].fd, -xf86SigIOFuncs[i].closure); +SYSCALL(r = poll(xf86SigIOFds, xf86SigIONum, 0)); +for (f = 0; r > 0 && f < xf86SigIONum; f++) { +if (xf86SigIOFds[f].revents & POLLIN) { +for (i = 0; i < xf86SigIOMax; i++) +if (xf86SigIOFuncs[i].f && xf86SigIOFuncs[i].fd == xf86SigIOFds[f].fd) +(*xf86SigIOFuncs[i].f) (xf86SigIOFuncs[i].fd, +xf86SigIOFuncs[i].closure); r--; } +} if (r > 0) { xf86Msg(X_ERROR, "SIGIO %d descriptors not
Re: [PATCH xserver 1/2] xwayland: Move sprite invalidation logic into mipointer
Emil Velikovwrites: >> +/* Invalidate current sprite, forcing reload on next >> + * sprite setting (window crossing, grab action, etc) >> + */ >> +extern _X_EXPORT void >> +miPointerInvalidateSprite(DeviceIntPtr pDev); >> + > It doesn't look like this should be exported, should it ? Yes, it's part of the server API and replaces the public definition of the underlying structure. > Perhaps it's worth making a list of needed symbols (ideally in an > automated manner) and throwing the remainder out there ? Then anyone > can take a small bite as they get bored ;-) We've done a bunch of symbol hiding, but it's always good to review any of the remaining ones... > Just a related thought... there's nothing wrong with the patch. Thanks! -- -keith signature.asc Description: PGP signature ___ 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
Re: [PATCH xserver 08/11] kdrive/ephyr: Poll for events in block handler
Laércio de Sousawrites: > Could it be related somehow to my concerns in > https://patchwork.freedesktop.org/patch/86328 ? I don't think so -- my patch only changes where the FD is read, not when that FD is added to the select call. Your patch looks like a fine change, although I think it might need to include a change to discard input events when the input subsystem wasn't running (which is why the SetNotifyFd calls are where they are) -- -keith signature.asc Description: PGP signature ___ 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
Re: [PATCH 1/4] Remove CLTS code
Adam Jackson <a...@redhat.com> writes: > Never been used, as far as I can tell. All seem like fine changes to me, although I'd rather see people working to just stop using Xtrans entirely... For the series: Reviewed-by: Keith Packard <kei...@keithp.com> -- -keith signature.asc Description: PGP signature ___ 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
[PATCH xserver 01/11] hw/xfree86: Use NotifyFd for other input fd wakeups
Remove code in xf86Wakeup for dealing with other input and switch to using the new NotifyFd interface. Signed-off-by: Keith Packard <kei...@keithp.com> --- hw/xfree86/common/xf86Events.c | 76 -- 1 file changed, 22 insertions(+), 54 deletions(-) diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c index 7191980..6f8d763 100644 --- a/hw/xfree86/common/xf86Events.c +++ b/hw/xfree86/common/xf86Events.c @@ -101,8 +101,6 @@ Bool VTSwitchEnabled = TRUE;/* Allows run-time disabling for switches when using the DRI automatic full screen mode.*/ -extern fd_set EnabledDevices; - #ifdef XF86PM extern void (*xf86OSPMClose) (void); #endif @@ -247,45 +245,6 @@ xf86ProcessActionEvent(ActionEvent action, void *arg) void xf86Wakeup(void *blockData, int err, void *pReadmask) { -fd_set *LastSelectMask = (fd_set *) pReadmask; -fd_set devicesWithInput; -InputInfoPtr pInfo; - -if (err >= 0) { - -XFD_ANDSET(, LastSelectMask, ); -if (XFD_ANYSET()) { -pInfo = xf86InputDevs; -while (pInfo) { -if (pInfo->read_input && pInfo->fd >= 0 && -(FD_ISSET(pInfo->fd, ) != 0)) { -input_lock(); - -/* - * Remove the descriptior from the set because more than one - * device may share the same file descriptor. - */ -FD_CLR(pInfo->fd, ); - -pInfo->read_input(pInfo); -input_unlock(); -} -pInfo = pInfo->next; -} -} -} - -if (err >= 0) { /* we don't want the handlers called if select() */ -IHPtr ih, ih_tmp; /* returned with an error condition, do we? */ - -nt_list_for_each_entry_safe(ih, ih_tmp, InputHandlers, next) { -if (ih->enabled && ih->fd >= 0 && ih->ihproc && -(FD_ISSET(ih->fd, ((fd_set *) pReadmask)) != 0)) { -ih->ihproc(ih->fd, ih->data); -} -} -} - if (xf86VTSwitchPending()) xf86VTSwitch(); } @@ -630,6 +589,16 @@ xf86VTSwitch(void) /* Input handler registration */ +static void +xf86InputHandlerNotify(int fd, int ready, void *data) +{ +IHPtr ih = data; + +if (ih->enabled && ih->fd >= 0 && ih->ihproc) { +ih->ihproc(ih->fd, ih->data); +} +} + static void * addInputHandler(int fd, InputHandlerProc proc, void *data) { @@ -647,6 +616,11 @@ addInputHandler(int fd, InputHandlerProc proc, void *data) ih->data = data; ih->enabled = TRUE; +if (!SetNotifyFd(fd, xf86InputHandlerNotify, X_NOTIFY_READ, ih)) { +free(ih); +return NULL; +} + ih->next = InputHandlers; InputHandlers = ih; @@ -658,10 +632,8 @@ xf86AddInputHandler(int fd, InputHandlerProc proc, void *data) { IHPtr ih = addInputHandler(fd, proc, data); -if (ih) { -AddEnabledDevice(fd); +if (ih) ih->is_input = TRUE; -} return ih; } @@ -670,8 +642,6 @@ xf86AddGeneralHandler(int fd, InputHandlerProc proc, void *data) { IHPtr ih = addInputHandler(fd, proc, data); -if (ih) -AddGeneralSocket(fd); return ih; } @@ -701,6 +671,8 @@ removeInputHandler(IHPtr ih) { IHPtr p; +if (ih->fd >= 0) +RemoveNotifyFd(ih->fd); if (ih == InputHandlers) InputHandlers = ih->next; else { @@ -725,8 +697,6 @@ xf86RemoveInputHandler(void *handler) ih = handler; fd = ih->fd; -if (ih->fd >= 0) -RemoveEnabledDevice(ih->fd); removeInputHandler(ih); return fd; @@ -744,8 +714,6 @@ xf86RemoveGeneralHandler(void *handler) ih = handler; fd = ih->fd; -if (ih->fd >= 0) -RemoveGeneralSocket(ih->fd); removeInputHandler(ih); return fd; @@ -762,7 +730,7 @@ xf86DisableInputHandler(void *handler) ih = handler; ih->enabled = FALSE; if (ih->fd >= 0) -RemoveEnabledDevice(ih->fd); +RemoveNotifyFd(ih->fd); } void @@ -776,7 +744,7 @@ xf86DisableGeneralHandler(void *handler) ih = handler; ih->enabled = FALSE; if (ih->fd >= 0) -RemoveGeneralSocket(ih->fd); +RemoveNotifyFd(ih->fd); } void @@ -790,7 +758,7 @@ xf86EnableInputHandler(void *handler) ih = handler; ih->enabled = TRUE; if (ih->fd >= 0) -AddEnabledDevice(ih->fd); +SetNotifyFd(ih->fd, xf86InputHandlerNotify, X_NOTIFY_READ, ih); } void @@ -804,7 +772,7 @@ xf86EnableGeneralHandler(void *handler) ih = handler; ih-&g
[PATCH xserver 2/2] mi: Remove miPointerRec from API
This moves the definition of miPointerRec from mipointrst.h to mipointer.c so that it is no longer visible in the API, allowing it to be changed while the API/ABI is frozen. Signed-off-by: Keith Packard <kei...@keithp.com> --- mi/mipointer.c | 12 mi/mipointrst.h | 12 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/mi/mipointer.c b/mi/mipointer.c index 7f95cdb..caa7a9f 100644 --- a/mi/mipointer.c +++ b/mi/mipointer.c @@ -65,6 +65,18 @@ in this Software without prior written authorization from The Open Group. #include "inpututils.h" #include "eventstr.h" +typedef struct { +ScreenPtr pScreen; /* current screen */ +ScreenPtr pSpriteScreen;/* screen containing current sprite */ +CursorPtr pCursor; /* current cursor */ +CursorPtr pSpriteCursor;/* cursor on screen */ +BoxRec limits; /* current constraints */ +Bool confined; /* pointer can't change screens */ +int x, y; /* hot spot location */ +int devx, devy; /* sprite position */ +Bool generateEvent; /* generate an event during warping? */ +} miPointerRec, *miPointerPtr; + DevPrivateKeyRec miPointerScreenKeyRec; #define GetScreenPrivate(s) ((miPointerScreenPtr) \ diff --git a/mi/mipointrst.h b/mi/mipointrst.h index 104e45c..4319b12 100644 --- a/mi/mipointrst.h +++ b/mi/mipointrst.h @@ -35,18 +35,6 @@ in this Software without prior written authorization from The Open Group. #include "scrnintstr.h" typedef struct { -ScreenPtr pScreen; /* current screen */ -ScreenPtr pSpriteScreen;/* screen containing current sprite */ -CursorPtr pCursor; /* current cursor */ -CursorPtr pSpriteCursor;/* cursor on screen */ -BoxRec limits; /* current constraints */ -Bool confined; /* pointer can't change screens */ -int x, y; /* hot spot location */ -int devx, devy; /* sprite position */ -Bool generateEvent; /* generate an event during warping? */ -} miPointerRec, *miPointerPtr; - -typedef struct { miPointerSpriteFuncPtr spriteFuncs; /* sprite-specific methods */ miPointerScreenFuncPtr screenFuncs; /* screen-specific methods */ CloseScreenProcPtr CloseScreen; -- 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
[PATCH xserver 02/11] dix: Switch to the libXfont2 API (v2)
This new libXfont API eliminates exposing internal X server symbols to the font library, replacing those with a struct full of the entire API needed to use that library. v2: Use libXfont2 instead of libXfont_2 Signed-off-by: Keith Packard <kei...@keithp.com> --- Xext/xf86bigfont.c | 4 +- configure.ac | 2 +- dix/dispatch.c | 4 +- dix/dixfonts.c | 323 + dix/main.c | 4 +- glamor/glamor_font.c | 6 +- hw/dmx/dmxfont.c | 9 +- hw/dmx/dmxscrinit.c| 4 +- hw/xfree86/sdksyms.sh | 1 - hw/xnest/Font.c| 7 +- hw/xnest/Init.c| 3 +- include/dixfont.h | 18 +-- include/dixfontstr.h | 1 + include/dixfontstubs.h | 43 --- mi/miglblt.c | 6 +- miext/damage/damage.c | 4 +- os/utils.c | 4 +- 17 files changed, 231 insertions(+), 212 deletions(-) delete mode 100644 include/dixfontstubs.h diff --git a/Xext/xf86bigfont.c b/Xext/xf86bigfont.c index 95b5371..682d84f 100644 --- a/Xext/xf86bigfont.c +++ b/Xext/xf86bigfont.c @@ -439,7 +439,7 @@ ProcXF86BigfontQueryFont(ClientPtr client) #ifdef HAS_SHM if (pDesc && !badSysCall) { *(CARD32 *) (pCI + nCharInfos) = signature; -if (!FontSetPrivate(pFont, FontShmdescIndex, pDesc)) { +if (!xfont2_font_set_private(pFont, FontShmdescIndex, pDesc)) { shmdealloc(pDesc); return BadAlloc; } @@ -723,7 +723,7 @@ XFree86BigfontExtensionInit(void) + (unsigned int) (65536.0 / (RAND_MAX + 1.0) * rand()); /* fprintf(stderr, "signature = 0x%08X\n", signature); */ -FontShmdescIndex = AllocateFontPrivateIndex(); +FontShmdescIndex = xfont2_allocate_font_private_index(); #if !defined(CSRG_BASED) && !defined(__CYGWIN__) pagesize = SHMLBA; diff --git a/configure.ac b/configure.ac index eb0a07c..2176f32 100644 --- a/configure.ac +++ b/configure.ac @@ -814,7 +814,7 @@ LIBEGL="egl" LIBGBM="gbm >= 10.2.0" LIBGL="gl >= 7.1.0" LIBXEXT="xext >= 1.0.99.4" -LIBXFONT="xfont >= 1.4.2" +LIBXFONT="xfont2 >= 2.0.0" LIBXI="xi >= 1.2.99.1" LIBXTST="xtst >= 1.0.99.2" LIBPCIACCESS="pciaccess >= 0.12.901" diff --git a/dix/dispatch.c b/dix/dispatch.c index 26122c1..89c0a4e 100644 --- a/dix/dispatch.c +++ b/dix/dispatch.c @@ -108,7 +108,7 @@ int ProcInitialConnection(); #include "windowstr.h" #include -#include +#include #include "dixfontstr.h" #include "gcstruct.h" #include "selection.h" @@ -1286,7 +1286,7 @@ ProcQueryTextExtents(ClientPtr client) return BadLength; length--; } -if (!QueryTextExtents(pFont, length, (unsigned char *) [1], )) +if (!xfont2_query_text_extents(pFont, length, (unsigned char *) [1], )) return BadAlloc; reply = (xQueryTextExtentsReply) { .type = X_Reply, diff --git a/dix/dixfonts.c b/dix/dixfonts.c index 19db141..d217d12 100644 --- a/dix/dixfonts.c +++ b/dix/dixfonts.c @@ -65,6 +65,7 @@ Equipment Corporation. #include "closestr.h" #include "dixfont.h" #include "xace.h" +#include #ifdef XF86BIGFONT #include "xf86bigfontsrv.h" @@ -75,7 +76,7 @@ extern FontPtr defaultFont; static FontPathElementPtr *font_path_elements = (FontPathElementPtr *) 0; static int num_fpes = 0; -static FPEFunctions *fpe_functions = (FPEFunctions *) 0; +static xfont2_fpe_funcs_rec const **fpe_functions; static int num_fpe_types = 0; static unsigned char *font_path_string; @@ -83,7 +84,7 @@ static unsigned char *font_path_string; static int num_slept_fpes = 0; static int size_slept_fpes = 0; static FontPathElementPtr *slept_fpes = (FontPathElementPtr *) 0; -static FontPatternCachePtr patternCache; +static xfont2_pattern_cache_ptr patternCache; static int FontToXError(int err) @@ -108,18 +109,18 @@ static int LoadGlyphs(ClientPtr client, FontPtr pfont, unsigned nchars, int item_size, unsigned char *data) { -if (fpe_functions[pfont->fpe->type].load_glyphs) -return (*fpe_functions[pfont->fpe->type].load_glyphs) +if (fpe_functions[pfont->fpe->type]->load_glyphs) +return (*fpe_functions[pfont->fpe->type]->load_glyphs) (client, pfont, 0, nchars, item_size, data); else return Successful; } void -dixGetGlyphs(FontPtr font, unsigned long count, unsigned char *chars, - FontEncoding fontEncoding, - unsigned long *glyphcount,/* RETURN */ - CharInfoPtr *glyphs) /* RETURN */ +GetGlyphs(FontPtr font, unsigned long count, unsigned char *chars, + FontEncoding fontEncoding, + unsigned long *glyphcount,
[PATCH 0/2] Hide pointer invalidation details from xwayland
Here's a couple of patches which makes miPointerRec private to the miPointer code; the only user of that struct was Xwayland which used it to invalidate the current sprite. An API is provided to perform that invalidation, and then the struct definition is removed from the API. ___ 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
[PATCH xserver 11/11] Remove AddEnabledDevice and AddGeneralSocket APIs
All uses of these interfaces should instead be using the NotifyFd API instead. Signed-off-by: Keith Packard <kei...@keithp.com> --- include/os.h| 8 os/WaitFor.c| 4 +--- os/connection.c | 23 --- 3 files changed, 5 insertions(+), 30 deletions(-) diff --git a/include/os.h b/include/os.h index e9b3709..1ede9b9 100644 --- a/include/os.h +++ b/include/os.h @@ -143,14 +143,6 @@ extern _X_EXPORT void CheckConnections(void); extern _X_EXPORT void CloseDownConnection(ClientPtr /*client */ ); -extern _X_EXPORT void AddGeneralSocket(int /*fd */ ); - -extern _X_EXPORT void RemoveGeneralSocket(int /*fd */ ); - -extern _X_EXPORT void AddEnabledDevice(int /*fd */ ); - -extern _X_EXPORT void RemoveEnabledDevice(int /*fd */ ); - typedef void (*NotifyFdProcPtr)(int fd, int ready, void *data); #define X_NOTIFY_NONE 0 diff --git a/os/WaitFor.c b/os/WaitFor.c index 5793427..994edf0 100644 --- a/os/WaitFor.c +++ b/os/WaitFor.c @@ -153,7 +153,6 @@ WaitForSomething(int *pClientsReady) int curclient; int selecterr; static int nready; -fd_set devicesReadable; CARD32 now = 0; Bool someReady = FALSE; Bool someNotifyWriteReady = FALSE; @@ -309,14 +308,13 @@ WaitForSomething(int *pClientsReady) } } -XFD_ANDSET(, , ); XFD_ANDSET(, , ); XFD_ANDSET(_set, , ); if (XFD_ANYSET(_set) || someNotifyWriteReady) HandleNotifyFds(); -if (XFD_ANYSET() || XFD_ANYSET()) +if (XFD_ANYSET()) break; /* check here for DDXes that queue events during Block/Wakeup */ if (*checkForInput[0] != *checkForInput[1]) diff --git a/os/connection.c b/os/connection.c index 4c1ba4b..b300025 100644 --- a/os/connection.c +++ b/os/connection.c @@ -47,8 +47,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) @@ -121,7 +121,6 @@ SOFTWARE. static int lastfdesc; /* maximum file descriptor */ -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 */ @@ -1047,7 +1046,7 @@ CloseDownConnection(ClientPtr client) AuditF("client %d disconnected\n", client->index); } -void +static void AddGeneralSocket(int fd) { FD_SET(fd, ); @@ -1055,14 +1054,7 @@ AddGeneralSocket(int fd) FD_SET(fd, ); } -void -AddEnabledDevice(int fd) -{ -FD_SET(fd, ); -AddGeneralSocket(fd); -} - -void +static void RemoveGeneralSocket(int fd) { FD_CLR(fd, ); @@ -1070,13 +1062,6 @@ RemoveGeneralSocket(int fd) FD_CLR(fd, ); } -void -RemoveEnabledDevice(int fd) -{ -FD_CLR(fd, ); -RemoveGeneralSocket(fd); -} - struct notify_fd { struct xorg_list list; int fd; -- 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
[PATCH xserver 05/11] Remove readmask from screen block/wakeup handler
With no users of the interface needing the readmask anymore, we can remove it from the argument passed to these functions. Signed-off-by: Keith Packard <kei...@keithp.com> --- composite/compalloc.c | 4 +-- dix/dixutils.c | 14 doc/Xinput.xml | 8 + doc/Xserver-spec.xml| 59 +++-- exa/exa.c | 10 +++--- glamor/glamor.c | 4 +-- hw/kdrive/src/kdrive.h | 6 ++-- hw/kdrive/src/kinput.c | 4 +-- hw/xfree86/common/xf86VGAarbiter.c | 10 +++--- hw/xfree86/common/xf86VGAarbiterPriv.h | 6 ++-- hw/xfree86/dri/dri.c| 12 +++ hw/xfree86/dri/dri.h| 7 ++-- hw/xfree86/drivers/modesetting/driver.c | 4 +-- hw/xfree86/modes/xf86Rotate.c | 5 ++- hw/xquartz/quartzCocoa.m| 8 ++--- hw/xquartz/quartzCommon.h | 5 +-- hw/xwin/win.h | 4 +-- hw/xwin/winwakeup.c | 3 +- include/scrnintstr.h| 11 +++--- mi/misprite.c | 8 ++--- 20 files changed, 71 insertions(+), 121 deletions(-) diff --git a/composite/compalloc.c b/composite/compalloc.c index 8daded0..e6a203f 100644 --- a/composite/compalloc.c +++ b/composite/compalloc.c @@ -55,13 +55,13 @@ compScreenUpdate(ScreenPtr pScreen) } static void -compBlockHandler(ScreenPtr pScreen, void *pTimeout, void *pReadmask) +compBlockHandler(ScreenPtr pScreen, void *pTimeout) { CompScreenPtr cs = GetCompScreen(pScreen); pScreen->BlockHandler = cs->BlockHandler; compScreenUpdate(pScreen); -(*pScreen->BlockHandler) (pScreen, pTimeout, pReadmask); +(*pScreen->BlockHandler) (pScreen, pTimeout); /* Next damage will restore the block handler */ cs->BlockHandler = NULL; diff --git a/dix/dixutils.c b/dix/dixutils.c index b6b0023..d357820 100644 --- a/dix/dixutils.c +++ b/dix/dixutils.c @@ -384,11 +384,11 @@ BlockHandler(void *pTimeout, void *pReadmask) ++inHandler; for (i = 0; i < screenInfo.numScreens; i++) -(*screenInfo.screens[i]->BlockHandler) (screenInfo.screens[i], -pTimeout, pReadmask); +(*screenInfo.screens[i]->BlockHandler) (screenInfo.screens[i], pTimeout); + for (i = 0; i < screenInfo.numGPUScreens; i++) -(*screenInfo.gpuscreens[i]->BlockHandler) (screenInfo.gpuscreens[i], - pTimeout, pReadmask); +(*screenInfo.gpuscreens[i]->BlockHandler) (screenInfo.gpuscreens[i], pTimeout); + for (i = 0; i < numHandlers; i++) if (!handlers[i].deleted) (*handlers[i].BlockHandler) (handlers[i].blockData, @@ -423,11 +423,9 @@ WakeupHandler(int result, void *pReadmask) (*handlers[i].WakeupHandler) (handlers[i].blockData, result, pReadmask); for (i = 0; i < screenInfo.numScreens; i++) -(*screenInfo.screens[i]->WakeupHandler) (screenInfo.screens[i], - result, pReadmask); +(*screenInfo.screens[i]->WakeupHandler) (screenInfo.screens[i], result); for (i = 0; i < screenInfo.numGPUScreens; i++) -(*screenInfo.gpuscreens[i]->WakeupHandler) (screenInfo.gpuscreens[i], -result, pReadmask); +(*screenInfo.gpuscreens[i]->WakeupHandler) (screenInfo.gpuscreens[i], result); if (handlerDeleted) { for (i = 0; i < numHandlers;) if (handlers[i].deleted) { diff --git a/doc/Xinput.xml b/doc/Xinput.xml index 083b109..0e7fbda 100644 --- a/doc/Xinput.xml +++ b/doc/Xinput.xml @@ -210,7 +210,7 @@ A sample InitInput implementation is shown below. InitInput(argc,argv) { -int i, numdevs, ReadInput(); +int i, numdevs; DeviceIntPtr dev; LocalDevice localdevs[LOCAL_MAX_DEVS]; DeviceProc kbdproc, ptrproc, extproc; @@ -224,12 +224,6 @@ InitInput(argc,argv) open_input_devices (numdevs, localdevs); /** - * Register a WakeupHandler to handle input when it is generated. - ***/ - -RegisterBlockAndWakeupHandlers (NoopDDA, ReadInput, NULL); - -/** * Register the input devices with DIX. ***/ diff --git a/doc/Xserver-spec.xml b/doc/Xserver-spec.xml index 72a544b..7867544 100644 --- a/doc/Xserver-spec.xml +++ b/doc/Xserver-spec.xml @@ -674,30 +674,22 @@ If WaitForSomething() decides it is about to do something that might block routin
[PATCH xserver 10/11] xnest: Use SetNotifyFd to receive events
Signed-off-by: Keith Packard <kei...@keithp.com> --- hw/xnest/Init.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/hw/xnest/Init.c b/hw/xnest/Init.c index bec2c51..e8a700e 100644 --- a/hw/xnest/Init.c +++ b/hw/xnest/Init.c @@ -35,6 +35,7 @@ is" without express or implied warranty. #include "Pointer.h" #include "Keyboard.h" #include "Handlers.h" +#include "Events.h" #include "Init.h" #include "Args.h" #include "Drawable.h" @@ -86,6 +87,12 @@ InitOutput(ScreenInfo * screen_info, int argc, char *argv[]) xnestDoFullGeneration = xnestFullGeneration; } +static void +xnestNotifyConnection(int fd, int ready, void *data) +{ +xnestCollectEvents(); +} + void InitInput(int argc, char *argv[]) { @@ -101,7 +108,7 @@ InitInput(int argc, char *argv[]) mieqInit(); -AddEnabledDevice(XConnectionNumber(xnestDisplay)); +SetNotifyFd(XConnectionNumber(xnestDisplay), xnestNotifyConnection, X_NOTIFY_READ, NULL); RegisterBlockAndWakeupHandlers(xnestBlockHandler, xnestWakeupHandler, NULL); } -- 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
[PATCH xserver 09/11] dmx: Eliminate use of AddEnabledDevice
Use SetNotifyFd instead, with the hope that someday someone will come fix this to be more efficient -- right now, the wakeup handler is doing the event reading, instead of the notify callback. Signed-off-by: Keith Packard <kei...@keithp.com> --- hw/dmx/input/dmxcommon.c | 17 + hw/dmx/input/dmxsigio.c | 9 +++-- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/hw/dmx/input/dmxcommon.c b/hw/dmx/input/dmxcommon.c index 90154ef..c7aed68 100644 --- a/hw/dmx/input/dmxcommon.c +++ b/hw/dmx/input/dmxcommon.c @@ -480,17 +480,26 @@ dmxCommonXSelect(DMXScreenInfo * dmxScreen, void *closure) return NULL; } +static void +dmxCommonFdNotify(int fd, int ready, void *data) +{ +/* This should process input on this fd, but instead all + * of that is delayed until the block and wakeup handlers are called + */ +; +} + static void * dmxCommonAddEnabledDevice(DMXScreenInfo * dmxScreen, void *closure) { -AddEnabledDevice(XConnectionNumber(dmxScreen->beDisplay)); +SetNotifyFd(XConnectionNumber(dmxScreen->beDisplay), dmxCommonFdNotify, X_NOTIFY_READ, closure); return NULL; } static void * dmxCommonRemoveEnabledDevice(DMXScreenInfo * dmxScreen, void *closure) { -RemoveEnabledDevice(XConnectionNumber(dmxScreen->beDisplay)); +RemoveNotifyFd(XConnectionNumber(dmxScreen->beDisplay)); return NULL; } @@ -504,7 +513,7 @@ dmxCommonMouOn(DevicePtr pDev) priv->eventMask |= DMX_POINTER_EVENT_MASK; if (!priv->be) { XSelectInput(priv->display, priv->window, priv->eventMask); -AddEnabledDevice(XConnectionNumber(priv->display)); +SetNotifyFd(XConnectionNumber(priv->display), dmxCommonFdNotify,X_NOTIFY_READ, pDev); } else { dmxPropertyIterate(priv->be, dmxCommonXSelect, priv); @@ -523,7 +532,7 @@ dmxCommonMouOff(DevicePtr pDev) priv->eventMask &= ~DMX_POINTER_EVENT_MASK; if (!priv->be) { -RemoveEnabledDevice(XConnectionNumber(priv->display)); +RemoveNotifyFd(XConnectionNumber(priv->display)); XSelectInput(priv->display, priv->window, priv->eventMask); } else { diff --git a/hw/dmx/input/dmxsigio.c b/hw/dmx/input/dmxsigio.c index 6ef543c..85eb5b9 100644 --- a/hw/dmx/input/dmxsigio.c +++ b/hw/dmx/input/dmxsigio.c @@ -114,6 +114,11 @@ dmxSigioUnhook(void) } static void +dmxSigioFdNotify(int fd, int ready, void *data) +{ +} + +static void dmxSigioAdd(DMXInputInfo * dmxInput) { int flags; @@ -138,7 +143,7 @@ dmxSigioAdd(DMXInputInfo * dmxInput) flags |= O_ASYNC | O_NONBLOCK; fcntl(fd, F_SETFL, flags); -AddEnabledDevice(fd); +SetNotifyFd(fd, dmxSigioFdNotify, X_NOTIFY_READ, NULL); dmxInput->sigioAdded[i] = TRUE; if (++dmxFdCount == 1) @@ -168,7 +173,7 @@ dmxSigioRemove(DMXInputInfo * dmxInput) int fd = dmxInput->sigioFd[i]; dmxInput->sigioAdded[i] = FALSE; -RemoveEnabledDevice(fd); +RemoveNotifyFd(fd); flags = fcntl(fd, F_GETFL); flags &= ~(O_ASYNC | O_NONBLOCK); -- 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
[PATCH xserver 00/11] Eliminate fd_set from server ABI/API
This series builds on the input-thread changes and eliminates the 'fd_set' type outside of the OS layer, along with the AddEnabledDevice and AddGeneralSocket APIs. My eventual goal is to replace select with epoll on linux and the equvalent for BSD so that we no longer care what fd values are used by clients, and to improve performance within the server. The series has a sequenc eof small logic changes and larger mechanical changes to try and make it easier to understand. Of course, some of the changes don't seem to make much sense in isolation so I'll explain the relationship here Many of these changes relate to how alternate input is handled in the X server. In the original API, the only way to deal with non-client file descriptors was to merged them into the select mask and then check that in a wakeup handler. With the NotifyFd interface, we've an alternative. [PATCH xserver 01/11] hw/xfree86: Use NotifyFd for other input fd A large monolithic change is to switch the font API to version 2. That interface passed fd_set references between the X server and the font server. This has naturally been changed to use the NotifyFd interface. Given the chance to fix the API, the new font library also eliminates explicit referances to functions in the X server. Now, the font library is provided with a vector of functions at initialization time. [PATCH xserver 02/11] dix: Switch to the libXfont2 API (v2) Ajax found a few places where the NotifyFd callbacks could be "improved" by using the fd provided to the callback rather than fetching the fd from some module-specific location. [PATCH xserver 03/11] hw/kdrive: Use passed-in fd for kdrive/linux [PATCH xserver 04/11] modesetting: Use passed-in fd for drm event With all users of the readmask in block/wakeup handlers gone, there are two large mechanical patches which adjust the API. [PATCH xserver 05/11] Remove readmask from screen block/wakeup [PATCH xserver 06/11] Remove fd_set from Block/Wakeup handler API While fixing the block handler API, I discovered that block handlers were called in an ill-defined order, causing ephyr (at least) to need a polling kludge in case additional data arrived from the host X server. Fixing the order to call the screen block handlers last meant that Xephyr can now reliably flush the X event queue before select is called. [PATCH xserver 07/11] dix: Call screen block/wakeup handlers closest [PATCH xserver 08/11] kdrive/ephyr: Poll for events in block handler dmx and xnest weren't using the readmask in their wakeup handlers, but were using AddEnabledDevice to cause the server to wakeup when input happened. Both dmx and xnest would then just poll their inputs to see where the data was. This is terribly inefficient, but using NotifyFd doesn't make it any worse. If anyone is interested, it should be pretty easy to fix. [PATCH xserver 09/11] dmx: Eliminate use of AddEnabledDevice [PATCH xserver 10/11] xnest: Use SetNotifyFd to receive events And, with no calls to AddEnableDevice or AddGeneralSocket, we can remove them from the server. [PATCH xserver 11/11] Remove AddEnabledDevice and AddGeneralSocket ___ 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
[PATCH xserver 1/2] xwayland: Move sprite invalidation logic into mipointer
This creates a function that invalidates the current sprite and forces a sprite image reload the next time the sprite is checked, moving that logic out of the xwayland sources and allowing the miPointerRec structure to be removed from the server API. Signed-off-by: Keith Packard <kei...@keithp.com> --- hw/xwayland/xwayland-input.c | 9 + mi/mipointer.c | 15 +++ mi/mipointer.h | 6 ++ 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c index cbc1bf2..d186681 100644 --- a/hw/xwayland/xwayland-input.c +++ b/hw/xwayland/xwayland-input.c @@ -219,7 +219,6 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer, struct xwl_seat *xwl_seat = data; DeviceIntPtr dev = xwl_seat->pointer; DeviceIntPtr master; -miPointerPtr mipointer; int i; int sx = wl_fixed_to_int(sx_w); int sy = wl_fixed_to_int(sy_w); @@ -243,13 +242,7 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer, master = GetMaster(dev, POINTER_OR_FLOAT); (*pScreen->SetCursorPosition) (dev, pScreen, sx, sy, TRUE); -/* X is very likely to have the wrong idea of what the actual cursor - * sprite is, so in order to force updating the cursor lets set the - * current sprite to some invalid cursor behind its back so that it - * always will think it changed to the not invalid cursor. - */ -mipointer = MIPOINTER(master); -mipointer->pSpriteCursor = (CursorPtr) 1; +miPointerInvalidateSprite(master); CheckMotion(NULL, master); diff --git a/mi/mipointer.c b/mi/mipointer.c index ada1ab5..7f95cdb 100644 --- a/mi/mipointer.c +++ b/mi/mipointer.c @@ -468,6 +468,21 @@ miPointerUpdateSprite(DeviceIntPtr pDev) } /** + * Invalidate the current sprite and force it to be reloaded on next cursor setting + * operation + * + * @param pDev The device to invalidate the sprite fore + */ +void +miPointerInvalidateSprite(DeviceIntPtr pDev) +{ +miPointerPtr pPointer; + +pPointer = MIPOINTER(pDev); +pPointer->pSpriteCursor = (CursorPtr) 1; +} + +/** * Set the device to the coordinates on the given screen. * * @param pDev The device to move diff --git a/mi/mipointer.h b/mi/mipointer.h index bdeed12..7ce6409 100644 --- a/mi/mipointer.h +++ b/mi/mipointer.h @@ -109,6 +109,12 @@ miPointerSetPosition(DeviceIntPtr pDev, int mode, double *x, double *y, extern _X_EXPORT void miPointerUpdateSprite(DeviceIntPtr pDev); +/* Invalidate current sprite, forcing reload on next + * sprite setting (window crossing, grab action, etc) + */ +extern _X_EXPORT void +miPointerInvalidateSprite(DeviceIntPtr pDev); + /* Sets whether the sprite should be updated immediately on pointer moves */ extern _X_EXPORT Bool miPointerSetWaitForUpdate(ScreenPtr pScreen, Bool wait); -- 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
[PATCH xserver 04/11] modesetting: Use passed-in fd for drm event monitoring NotifyFd callback
This is a cleanup, proposed by Adam Jackson, but wasn't merged with the original NotifyFD changes. Signed-off-by: Keith Packard <kei...@keithp.com> --- hw/xfree86/drivers/modesetting/vblank.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/xfree86/drivers/modesetting/vblank.c b/hw/xfree86/drivers/modesetting/vblank.c index 869472a..0727887 100644 --- a/hw/xfree86/drivers/modesetting/vblank.c +++ b/hw/xfree86/drivers/modesetting/vblank.c @@ -253,7 +253,7 @@ ms_drm_socket_handler(int fd, int ready, void *data) if (data == NULL) return; -drmHandleEvent(ms->fd, >event_context); +drmHandleEvent(fd, >event_context); } /* -- 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
[PATCH xserver 07/11] dix: Call screen block/wakeup handlers closest to blocking [v2]
The screen block and wakeup handlers are the only ones which provide a well known ordering between the wrapping layers; placing these as close as possible to the server blocking provides a way for the driver to control the flow of execution correctly. Switch the shadow code to run in the screen block handler so that it now occurrs just before the server goes to sleep. Switch glamor to call down to the driver after it has executed its own block handler piece, in case the driver needs to perform additional flushing work after glamor has called glFlush. These changes ensure that the following modules update the screen in the correct order: animated cursors(uses RegisterBlockAndWakeupHandlers dynamically) composite (dynamic wrapping) misprite(dynamic wrapping) shadow (static wrapping) glamor (static wrapping) driver (static wrapping) It looks like there's still a bit of confusion between composite and misprite; if composite updates after misprite, then it's possible you'd exit the block handler chain with the cursor left hidden. To fix that, misprite should be wrapping during ScreenInit time and not unwrapping. And composite might as well join in that fun, just to make things consistent. [v2] Unwrap BlockHandler in shadowCloseScreen (ajax) Signed-off-by: Keith Packard <kei...@keithp.com> --- dix/dixutils.c| 16 glamor/glamor.c | 6 +++--- miext/shadow/shadow.c | 20 +++- miext/shadow/shadow.h | 1 + 4 files changed, 19 insertions(+), 24 deletions(-) diff --git a/dix/dixutils.c b/dix/dixutils.c index 53a7a36..540023c 100644 --- a/dix/dixutils.c +++ b/dix/dixutils.c @@ -383,15 +383,15 @@ BlockHandler(void *pTimeout) int i, j; ++inHandler; -for (i = 0; i < screenInfo.numScreens; i++) -(*screenInfo.screens[i]->BlockHandler) (screenInfo.screens[i], pTimeout); +for (i = 0; i < numHandlers; i++) +if (!handlers[i].deleted) +(*handlers[i].BlockHandler) (handlers[i].blockData, pTimeout); for (i = 0; i < screenInfo.numGPUScreens; i++) (*screenInfo.gpuscreens[i]->BlockHandler) (screenInfo.gpuscreens[i], pTimeout); -for (i = 0; i < numHandlers; i++) -if (!handlers[i].deleted) -(*handlers[i].BlockHandler) (handlers[i].blockData, pTimeout); +for (i = 0; i < screenInfo.numScreens; i++) +(*screenInfo.screens[i]->BlockHandler) (screenInfo.screens[i], pTimeout); if (handlerDeleted) { for (i = 0; i < numHandlers;) @@ -418,13 +418,13 @@ WakeupHandler(int result) int i, j; ++inHandler; -for (i = numHandlers - 1; i >= 0; i--) -if (!handlers[i].deleted) -(*handlers[i].WakeupHandler) (handlers[i].blockData, result); for (i = 0; i < screenInfo.numScreens; i++) (*screenInfo.screens[i]->WakeupHandler) (screenInfo.screens[i], result); for (i = 0; i < screenInfo.numGPUScreens; i++) (*screenInfo.gpuscreens[i]->WakeupHandler) (screenInfo.gpuscreens[i], result); +for (i = numHandlers - 1; i >= 0; i--) +if (!handlers[i].deleted) +(*handlers[i].WakeupHandler) (handlers[i].blockData, result); if (handlerDeleted) { for (i = 0; i < numHandlers;) if (handlers[i].deleted) { diff --git a/glamor/glamor.c b/glamor/glamor.c index ae3f8bd..9e9db3c 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -264,13 +264,13 @@ _glamor_block_handler(ScreenPtr screen, void *timeout) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); +glamor_make_current(glamor_priv); +glFlush(); + screen->BlockHandler = glamor_priv->saved_procs.block_handler; screen->BlockHandler(screen, timeout); glamor_priv->saved_procs.block_handler = screen->BlockHandler; screen->BlockHandler = _glamor_block_handler; - -glamor_make_current(glamor_priv); -glFlush(); } static void diff --git a/miext/shadow/shadow.c b/miext/shadow/shadow.c index 0759298..b8e23da 100644 --- a/miext/shadow/shadow.c +++ b/miext/shadow/shadow.c @@ -65,16 +65,15 @@ shadowRedisplay(ScreenPtr pScreen) } static void -shadowBlockHandler(void *data, void *timeout) +shadowBlockHandler(ScreenPtr pScreen, void *timeout) { -ScreenPtr pScreen = (ScreenPtr) data; +shadowBuf(pScreen); shadowRedisplay(pScreen); -} -static void -shadowWakeupHandler(void *data, int result) -{ +unwrap(pBuf, pScreen, BlockHandler); +pScreen->BlockHandler(pScreen, timeout); +wrap(pBuf, pScreen, BlockHandler); } static void @@ -100,6 +99,7 @@ shadowCloseScreen(ScreenPtr pScreen) unwrap(pBuf, pScreen, GetImage); unwrap(pBuf, pScreen, CloseScreen); +unwrap(pBuf, pScreen, BlockHandler); shadowRemove(pScreen, pBuf->pPixmap); DamageDestroy(pBuf->pDamage); if (p
[PATCH xserver 03/11] hw/kdrive: Use passed-in fd for kdrive/linux APM monitoring [v2]
This is a cleanup, proposed by Adam Jackson, but wasn't merged with the original NotifyFD changes. Signed-off-by: Keith Packard <kei...@keithp.com> --- hw/kdrive/linux/linux.c | 64 - 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/hw/kdrive/linux/linux.c b/hw/kdrive/linux/linux.c index a52bdef..bc48d8d 100644 --- a/hw/kdrive/linux/linux.c +++ b/hw/kdrive/linux/linux.c @@ -174,41 +174,39 @@ static Bool LinuxApmRunning; static void LinuxApmNotify(int fd, int mask, void *blockData) { -if (LinuxApmFd >= 0) { -apm_event_t event; -Bool running = LinuxApmRunning; -int cmd = APM_IOC_SUSPEND; - -while (read(LinuxApmFd, , sizeof(event)) == sizeof(event)) { -switch (event) { -case APM_SYS_STANDBY: -case APM_USER_STANDBY: -running = FALSE; -cmd = APM_IOC_STANDBY; -break; -case APM_SYS_SUSPEND: -case APM_USER_SUSPEND: -case APM_CRITICAL_SUSPEND: -running = FALSE; -cmd = APM_IOC_SUSPEND; -break; -case APM_NORMAL_RESUME: -case APM_CRITICAL_RESUME: -case APM_STANDBY_RESUME: -running = TRUE; -break; -} -} -if (running && !LinuxApmRunning) { -KdResume(); -LinuxApmRunning = TRUE; -} -else if (!running && LinuxApmRunning) { -KdSuspend(); -LinuxApmRunning = FALSE; -ioctl(LinuxApmFd, cmd, 0); +apm_event_t event; +Bool running = LinuxApmRunning; +int cmd = APM_IOC_SUSPEND; + +while (read(fd, , sizeof(event)) == sizeof(event)) { +switch (event) { +case APM_SYS_STANDBY: +case APM_USER_STANDBY: +running = FALSE; +cmd = APM_IOC_STANDBY; +break; +case APM_SYS_SUSPEND: +case APM_USER_SUSPEND: +case APM_CRITICAL_SUSPEND: +running = FALSE; +cmd = APM_IOC_SUSPEND; +break; +case APM_NORMAL_RESUME: +case APM_CRITICAL_RESUME: +case APM_STANDBY_RESUME: +running = TRUE; +break; } } +if (running && !LinuxApmRunning) { +KdResume(); +LinuxApmRunning = TRUE; +} +else if (!running && LinuxApmRunning) { +KdSuspend(); +LinuxApmRunning = FALSE; +ioctl(fd, cmd, 0); +} } #ifdef FNONBLOCK -- 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
[PATCH xserver 06/11] Remove fd_set from Block/Wakeup handler API
This removes the last uses of fd_set from the server interfaces outside of the OS layer itself. Signed-off-by: Keith Packard <kei...@keithp.com> --- Xext/sleepuntil.c | 17 +++-- Xext/sync.c | 12 ++-- dix/dixfonts.c | 7 +++ dix/dixutils.c | 23 +++ hw/dmx/dmxsync.c| 4 ++-- hw/dmx/input/dmxinputinit.c | 4 ++-- hw/kdrive/ephyr/ephyr.c | 4 ++-- hw/vfb/InitOutput.c | 4 ++-- hw/xfree86/common/xf86Events.c | 2 +- hw/xfree86/common/xf86Init.c| 2 +- hw/xfree86/common/xf86Priv.h| 2 +- hw/xfree86/dri/dri.c| 4 ++-- hw/xfree86/dri/dri.h| 6 ++ hw/xnest/Handlers.c | 4 ++-- hw/xnest/Handlers.h | 5 ++--- hw/xwayland/xwayland.c | 4 ++-- include/dix.h | 26 +- miext/rootless/rootlessScreen.c | 4 ++-- miext/shadow/shadow.c | 4 ++-- os/WaitFor.c| 4 ++-- 20 files changed, 67 insertions(+), 75 deletions(-) diff --git a/Xext/sleepuntil.c b/Xext/sleepuntil.c index 993c028..68a7a9b 100644 --- a/Xext/sleepuntil.c +++ b/Xext/sleepuntil.c @@ -63,14 +63,11 @@ static void ClientAwaken(ClientPtr /* client */ , static int SertafiedDelete(void * /* value */ , XID /* id */ ); -static void SertafiedBlockHandler(void */* data */ , - OSTimePtr /* wt */ , - void */* LastSelectMask */ -); -static void SertafiedWakeupHandler(void * /* data */ , - int /* i */ , - void * /* LastSelectMask */ -); +static void SertafiedBlockHandler(void *data, + void *timeout); + +static void SertafiedWakeupHandler(void *data, + int i); int ClientSleepUntil(ClientPtr client, @@ -154,7 +151,7 @@ SertafiedDelete(void *value, XID id) } static void -SertafiedBlockHandler(void *data, OSTimePtr wt, void *LastSelectMask) +SertafiedBlockHandler(void *data, void *wt) { SertafiedPtr pReq, pNext; unsigned long delay; @@ -186,7 +183,7 @@ SertafiedBlockHandler(void *data, OSTimePtr wt, void *LastSelectMask) } static void -SertafiedWakeupHandler(void *data, int i, void *LastSelectMask) +SertafiedWakeupHandler(void *data, int i) { SertafiedPtr pReq, pNext; TimeStamp now; diff --git a/Xext/sync.c b/Xext/sync.c index 4c59fea..323b9db 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -2556,8 +2556,8 @@ static XSyncValue *pnext_time; *** Server Block Handler *** code inspired by multibuffer extension (now deprecated) */ - /*ARGSUSED*/ static void -ServertimeBlockHandler(void *env, struct timeval **wt, void *LastSelectMask) +/*ARGSUSED*/ static void +ServertimeBlockHandler(void *env, void *wt) { XSyncValue delay; unsigned long timeout; @@ -2582,8 +2582,8 @@ ServertimeBlockHandler(void *env, struct timeval **wt, void *LastSelectMask) /* *** Wakeup Handler */ - /*ARGSUSED*/ static void -ServertimeWakeupHandler(void *env, int rc, void *LastSelectMask) +/*ARGSUSED*/ static void +ServertimeWakeupHandler(void *env, int rc) { if (pnext_time) { GetTime(); @@ -2658,7 +2658,7 @@ IdleTimeQueryValue(void *pCounter, CARD64 * pValue_return) } static void -IdleTimeBlockHandler(void *pCounter, struct timeval **wt, void *LastSelectMask) +IdleTimeBlockHandler(void *pCounter, void *wt) { SyncCounter *counter = pCounter; IdleCounterPriv *priv = SysCounterGetPrivate(counter); @@ -2751,7 +2751,7 @@ IdleTimeCheckBrackets(SyncCounter *counter, XSyncValue idle, XSyncValue *less, X } static void -IdleTimeWakeupHandler(void *pCounter, int rc, void *LastSelectMask) +IdleTimeWakeupHandler(void *pCounter, int rc) { SyncCounter *counter = pCounter; IdleCounterPriv *priv = SysCounterGetPrivate(counter); diff --git a/dix/dixfonts.c b/dix/dixfonts.c index d217d12..cca92ed 100644 --- a/dix/dixfonts.c +++ b/dix/dixfonts.c @@ -197,7 +197,7 @@ RemoveFontWakeup(FontPathElementPtr fpe) } static void -FontWakeup(void *data, int count, void *LastSelectMask) +FontWakeup(void *data, int count) { int i; FontPathElementPtr fpe; @@ -1918,8 +1918,7 @@ _client_auth_generation(ClientPtr client) static int fs_handlers_installed = 0; static unsigned int last_server_gen; -static void -fs_block_handler(void *blockData, OSTimePtr timeout, void *readmask) +static void fs_block_handler(void *blockData, void *timeout) { FontBlockHandlerProcPtr block_handler = blockData; @@ -2004,7 +2003,7 @@ _init_fs_handlers(FontPathElementPtr fpe, FontBlockHandlerProcPtr block_handler) static void _remove_fs_handlers(FontPathElementPtr fpe, FontBlockHandlerProcPtr block_handler, - Bool all) +Bo
[PATCH xserver 08/11] kdrive/ephyr: Poll for events in block handler
With the driver block handler guaranteed to be the last thing called before the server blocks, we can now reliably check for events there and never block with events read but not processed. Signed-off-by: Keith Packard <kei...@keithp.com> --- hw/kdrive/ephyr/ephyr.c | 14 +- hw/kdrive/ephyr/ephyr.h | 3 +++ hw/kdrive/ephyr/ephyrinit.c | 1 + hw/kdrive/src/kdrive.h | 2 +- hw/kdrive/src/kinput.c | 9 - 5 files changed, 22 insertions(+), 7 deletions(-) diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c index 1a410ca..6066b5d 100644 --- a/hw/kdrive/ephyr/ephyr.c +++ b/hw/kdrive/ephyr/ephyr.c @@ -1106,7 +1106,7 @@ ephyrProcessConfigureNotify(xcb_generic_event_t *xev) } static void -ephyrXcbNotify(int fd, int ready, void *data) +ephyrXcbProcessEvents(void) { xcb_connection_t *conn = hostx_get_xcbconn(); @@ -1166,6 +1166,18 @@ ephyrXcbNotify(int fd, int ready, void *data) } } +static void +ephyrXcbNotify(int fd, int ready, void *data) +{ +ephyrXcbProcessEvents(); +} + +void +ephyrBlockHandler(ScreenPtr pScreen, void *timeo) +{ +ephyrXcbProcessEvents(); +} + void ephyrCardFini(KdCardInfo * card) { diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h index f5015f6..ef5736e 100644 --- a/hw/kdrive/ephyr/ephyr.h +++ b/hw/kdrive/ephyr/ephyr.h @@ -138,6 +138,9 @@ void ephyrCloseScreen(ScreenPtr pScreen); void +ephyrBlockHandler(ScreenPtr pScreen, void *timeo); + +void ephyrCardFini(KdCardInfo * card); void diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c index 149ea98..03d6289 100644 --- a/hw/kdrive/ephyr/ephyrinit.c +++ b/hw/kdrive/ephyr/ephyrinit.c @@ -411,4 +411,5 @@ KdCardFuncs ephyrFuncs = { ephyrPutColors, /* putColors */ ephyrCloseScreen, /* closeScreen */ +ephyrBlockHandler, /* blockHandler */ }; diff --git a/hw/kdrive/src/kdrive.h b/hw/kdrive/src/kdrive.h index 3c7f2cd..6ef7337 100644 --- a/hw/kdrive/src/kdrive.h +++ b/hw/kdrive/src/kdrive.h @@ -133,6 +133,7 @@ typedef struct _KdCardFuncs { void (*putColors) (ScreenPtr, int, xColorItem *); void (*closeScreen) (ScreenPtr);/* close ScreenRec */ +void (*blockHandler) (ScreenPtr, void *timeo); } KdCardFuncs; #define KD_MAX_PSEUDO_DEPTH 8 @@ -296,7 +297,6 @@ typedef struct _KdOsFuncs { Bool (*SpecialKey) (KeySym); void (*Disable) (void); void (*Fini) (void); -void (*pollEvents) (void); void (*Bell) (int, int, int); } KdOsFuncs; diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c index c0f1cf7..2234dfc 100644 --- a/hw/kdrive/src/kinput.c +++ b/hw/kdrive/src/kinput.c @@ -1965,6 +1965,7 @@ KdBlockHandler(ScreenPtr pScreen, void *timeo) { KdPointerInfo *pi; int myTimeout = 0; +KdScreenPriv(pScreen); for (pi = kdPointers; pi; pi = pi->next) { if (pi->timeoutPending) { @@ -1977,13 +1978,11 @@ KdBlockHandler(ScreenPtr pScreen, void *timeo) myTimeout = ms; } } -/* if we need to poll for events, do that */ -if (kdOsFuncs->pollEvents) { -(*kdOsFuncs->pollEvents) (); -myTimeout = 20; -} if (myTimeout > 0) AdjustWaitForDelay(timeo, myTimeout); + +if (pScreenPriv->card->cfuncs->blockHandler) +(*pScreenPriv->card->cfuncs->blockHandler)(pScreen, timeo); } void -- 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
Re: [PATCH xserver 2/9] Remove SIGIO support for input [v3]
Peter Huttererwrites: > f9c58cdf8b51 and 59bba16c have my rev-by and the revised v5 > (f2161ee249c1b6806) as well, this is as close as I'm going to get to review > those anyway ;) Thanks. I've pushed an updated version of the branch. Just one more to review, the actual input thread code. -- -keith signature.asc Description: PGP signature ___ 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
Re: [PATCH xserver 1/3] glamor: Disable logic ops when doing compositing [v3]
Michel Dänzerwrites: > https://bugs.freedesktop.org/show_bug.cgi?id=63397#c24 Some day I'll think to look at bugzilla when I fix a bug :-) I've added a comment and copy of the patch to that bug. -- -keith signature.asc Description: PGP signature ___ 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
Re: [PATCH xserver 7/9] dix: Reallocate touchpoint buffer at input event time
Peter Huttererwrites: > fwiw, that first sentence isn't correct anymore, you can drop it. > rev-by still stands. I've edited the comment, along with re-adding the UseSIGIO option to the parsing code and pushed out an updated thread with all of your kind Rb/Ab lines added. We have but the two giant patches left to see through the review process before this series can be merged. I'd love to make those simpler, but I can't imagine how... Thanks again for helping get us this far. -- -keith signature.asc Description: PGP signature ___ 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
Re: [PATCH xserver 2/9] Remove SIGIO support for input [v3]
Peter Huttererwrites: Thanks for taking a look at these. This one is less mechanical than I'd like, so some of the changes aren't obvious. It's definitely good to review them carefully. >> KdNotifyFd(int fd, int ready, void *data) >> { >> int i = (int) (intptr_t) data; >> -OsBlockSIGIO(); >> (*kdInputFds[i].read)(fd, kdInputFds[i].closure); >> -OsReleaseSIGIO(); > > how comes you don't replace these with input_lock/input_unlock()? if there's > a specific reason it'd be better to have this in a follow-up patch, I'd > prefer this patch to be mostly mechanical. Just that we won't need a lock here in the threaded input case; threaded input holds the input lock across all input processing. This could go in a separate patch, but of course with SIGIO removed, we wouldn't need locking anyways. If I replaced them with input_lock/input_unlock, I'd just have to remove those calls when threaded input got added. >> static void >> KdAddFd(int fd, int i) >> { >> -struct sigaction act; >> -sigset_t set; >> - >> -kdnFds++; >> -fcntl(fd, F_SETOWN, getpid()); >> KdNonBlockFd(fd); >> -AddEnabledDevice(fd); > > > it's not clear why you're dropping this bit. (the fcntl should be self-evident) The AddEnabledDevice call was not necessary, given the SetNotifyFd call just below. Was a harmless bug before threaded input as it just whacked the same mask that SetNotifyFd was going to whack. However, with threaded input, we don't want the main server select to see the input devices, so the call needs to be removed. > same here. Same reason. >> -{FLAG_USE_SIGIO, "UseSIGIO", OPTV_BOOLEAN, >> - {0}, FALSE}, > > not 100% here - if you take this out won't current configs with that option > now throw an error? should't we be more lenient here? Good point. Leaving this in seems harmless enough. One wonders if this value has ever been used... Do you want me to rearrange the other fixes above to make more sense? Or is it good enough to have explanation here? -- -keith signature.asc Description: PGP signature ___ 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
Re: [PATCH xserver 1/3] glamor: Disable logic ops when doing compositing [v3]
Emil Velikovwrites: > This hunk should be in 3/3, shouldn't it ? Yup, thanks for the catch! Series re-pushed to my 'render-fixes' branch, no change in the final version. -- -keith signature.asc Description: PGP signature ___ 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
Re: [PATCH xserver 1/3] glamor: Disable logic ops when doing compositing [v3]
Hans de Goedewrites: > Note I've not actually tested if these patches fix the issues at > hand, I've only run my normal stuff and did not notice any > regressions. I'm surprised no-one else has noticed the problems with libreoffice; random bits of GUI text rendered as black rectangles was pretty annoying to me. I fear I use that fine application more than most actual X developers these days. -- -keith signature.asc Description: PGP signature ___ 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
Re: [PATCH xserver] glamor: Disable logic ops when doing compositing
Eric Anholtwrites: > Oh, yeah. Even better. And a v3 which catches the other place where GL_BLEND is getting set. Sent that under a separate cover along with a more complicated patch for the red/alpha swizzling stuff. -- -keith signature.asc Description: PGP signature ___ 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
Re: [PATCH] glamor: swizzle RED to 0 for alpha textures.
Keith Packard <kei...@keithp.com> writes: > And, loading a page from gfycat is broken by this change. > > firefox https://gfycat.com/HoarseCheapAmericankestrel > > So, we can either have feedly with black text or gfycat with > cat videos, but not both at the same time. I'm not sure I can live in a > world without both of these. I just posted a fix for this which leaves bits in the Red channel when the destination is also in GL_RED format. -- -keith signature.asc Description: PGP signature ___ 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
[PATCH xserver 1/3] glamor: Disable logic ops when doing compositing [v3]
If the logic op gets left enabled, it overrides the blending operation, causing incorrect contents on the display. v2: Disable only on non-ES2, but disable even for PictOpSrc v3: Found another place this is needed in glamor_composite_set_shader_blend Signed-off-by: Keith Packard <kei...@keithp.com> --- glamor/glamor_program.c | 4 glamor/glamor_render.c | 6 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/glamor/glamor_program.c b/glamor/glamor_program.c index 0a94de6..322d198 100644 --- a/glamor/glamor_program.c +++ b/glamor/glamor_program.c @@ -445,6 +445,7 @@ static struct blendinfo composite_op_info[] = { static void glamor_set_blend(CARD8 op, glamor_program_alpha alpha, PicturePtr dst) { +glamor_screen_private *glamor_priv = glamor_get_screen_private(dst->pDrawable->pScreen); GLenum src_blend, dst_blend; struct blendinfo *op_info; @@ -459,6 +460,9 @@ glamor_set_blend(CARD8 op, glamor_program_alpha alpha, PicturePtr dst) break; } +if (glamor_priv->gl_flavor != GLAMOR_GL_ES2) +glDisable(GL_COLOR_LOGIC_OP); + if (op == PictOpSrc) return; diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 65f7059..ea9abc7 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -1075,10 +1075,14 @@ glamor_composite_set_shader_blend(glamor_screen_private *glamor_priv, glamor_set_composite_texture(glamor_priv, 1, shader->mask, shader->mask_pixmap, shader->mask_wh, - shader->mask_repeat_mode); + shader->mask_repeat_mode, + dest_priv); } } +if (glamor_priv->gl_flavor != GLAMOR_GL_ES2) +glDisable(GL_COLOR_LOGIC_OP); + if (op_info->source_blend == GL_ONE && op_info->dest_blend == GL_ZERO) { glDisable(GL_BLEND); } -- 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
[PATCH xserver 3/3] glamor: Preserve GL_RED bits in R channel when destination is GL_RED
A1 and A8 pixmaps are usually stored in the Red channel to conform with more recent GL versions. When using these pixmaps as mask values, that works great. When using these pixmaps as source values, then the value we want depends on what the destination looks like. For RGBA or RGB destinations, then we want to use the Red channel for A values and leave RGB all set to zero. For A destinations, then we want to leave the R values in the Red channel so that they end up in the Red channel of the output. This patch adds a helper function, glamor_bind_texture, which performs the glBindTexture call along with setting the swizzle parameter correctly for the Red channel. The swizzle parameter for the Alpha channel doesn't depend on the destination as it's safe to leave it always swizzled from the Red channel. This fixes incorrect rendering in firefox for this page: https://gfycat.com/HoarseCheapAmericankestrel while not breaking rendering for this page: https://feedly.com Signed-off-by: Keith Packard <kei...@keithp.com> --- glamor/glamor.c | 36 glamor/glamor_composite_glyphs.c | 3 +-- glamor/glamor_copy.c | 8 glamor/glamor_dash.c | 3 +-- glamor/glamor_fbo.c | 4 +--- glamor/glamor_priv.h | 28 glamor/glamor_program.c | 4 +++- glamor/glamor_render.c | 18 ++ glamor/glamor_spans.c| 3 +-- glamor/glamor_transfer.c | 3 +-- glamor/glamor_transform.c| 12 glamor/glamor_transform.h| 4 +++- 12 files changed, 101 insertions(+), 25 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index 477bc0e..62b5c3a 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -140,6 +140,42 @@ glamor_get_pixmap_texture(PixmapPtr pixmap) return pixmap_priv->fbo->tex; } +void +glamor_bind_texture(glamor_screen_private *glamor_priv, GLenum texture, +glamor_pixmap_fbo *fbo, Bool destination_red) +{ +glActiveTexture(texture); +glBindTexture(GL_TEXTURE_2D, fbo->tex); + +/* If we're pulling data from a GL_RED texture, then whether we + * want to make it an A,0,0,0 result or a 0,0,0,R result depends + * on whether the destination is also a GL_RED texture. + * + * For GL_RED destinations, we need to leave the bits in the R + * channel. For all other destinations, we need to clear out the R + * channel so that it returns zero for R, G and B. + * + * Note that we're leaving the SWIZZLE_A value alone; for GL_RED + * destinations, that means we'll actually be returning R,0,0,R, + * but it doesn't matter as the bits in the alpha channel aren't + * going anywhere. + */ + +/* Is the operand a GL_RED fbo? + */ + +if (glamor_fbo_red_is_alpha(glamor_priv, fbo)) { + +/* If destination is also GL_RED, then preserve the bits in + * the R channel */ + +if (destination_red) +glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED); +else +glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ZERO); +} +} + PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, unsigned int usage) diff --git a/glamor/glamor_composite_glyphs.c b/glamor/glamor_composite_glyphs.c index f51ff6d..50fd026 100644 --- a/glamor/glamor_composite_glyphs.c +++ b/glamor/glamor_composite_glyphs.c @@ -246,8 +246,7 @@ glamor_glyphs_flush(CARD8 op, PicturePtr src, PicturePtr dst, glamor_put_vbo_space(drawable->pScreen); glEnable(GL_SCISSOR_TEST); -glActiveTexture(GL_TEXTURE1); -glBindTexture(GL_TEXTURE_2D, atlas_fbo->tex); +glamor_bind_texture(glamor_priv, GL_TEXTURE1, atlas_fbo, FALSE); for (;;) { if (!glamor_use_program_render(prog, op, src, dst)) diff --git a/glamor/glamor_copy.c b/glamor/glamor_copy.c index 5fed89f..3501a0d 100644 --- a/glamor/glamor_copy.c +++ b/glamor/glamor_copy.c @@ -38,8 +38,8 @@ use_copyarea(PixmapPtr dst, GCPtr gc, glamor_program *prog, void *arg) struct copy_args *args = arg; glamor_pixmap_fbo *src = args->src; -glActiveTexture(GL_TEXTURE0); -glBindTexture(GL_TEXTURE_2D, src->tex); +glamor_bind_texture(glamor_get_screen_private(dst->drawable.pScreen), +GL_TEXTURE0, src, TRUE); glUniform2f(prog->fill_offset_uniform, args->dx, args->dy); glUniform2f(prog->fill_size_inv_uniform, 1.0f/src->width, 1.0f/src->height); @@ -67,8 +67,8 @@ use_copyplane(PixmapPtr dst, GCPtr gc, glamor_program *prog, void *arg) struct copy_args *args = arg; glamor_pixmap_fbo *src = args->src; -glActiveTexture(GL_TEXTURE0); -glBindTexture(GL_TEXTURE_2D, src->tex); +glamor_bind_texture(glamor_get_screen_private(dst->drawable.pScreen), +
[PATCH xserver 2/3] glamor: glamor_make_current sooner in glamor_composite_with_shader
glamor_make_current is supposed to be called before any GL APIs. Signed-off-by: Keith Packard <kei...@keithp.com> --- glamor/glamor_render.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index ea9abc7..1e03ca0 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -1143,12 +1143,12 @@ glamor_composite_with_shader(CARD8 op, } } +glamor_make_current(glamor_priv); + glamor_set_destination_pixmap_priv_nc(glamor_priv, dest_pixmap, dest_pixmap_priv); glamor_composite_set_shader_blend(glamor_priv, dest_pixmap_priv, , shader, _info); glamor_set_alu(screen, GXcopy); -glamor_make_current(glamor_priv); - glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID; glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID); -- 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
Re: [PATCH] glamor: swizzle RED to 0 for alpha textures.
Dave Airliewrites: > From: Dave Airlie > > I'm pretty sure Eric suspected this could cause a problem, and > we couldn't find a test. Well loading feedly in firefox seems > to trigger badness that this solves. And, loading a page from gfycat is broken by this change. firefox https://gfycat.com/HoarseCheapAmericankestrel So, we can either have feedly with black text or gfycat with cat videos, but not both at the same time. I'm not sure I can live in a world without both of these. -- -keith signature.asc Description: PGP signature ___ 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
Re: [PATCH xserver] glamor: Disable logic ops when doing compositing
Markus Wickwrites: > Hi, > > AFAIK we disable logic ops after each usage, so this seems a bit > redundant to me. Did we miss one usages? Nope, GL_COLOR_LOGIC_OP isn't managed like other glEnable/glDisable pairs; it's left at the previous value. Someday we should figure out how we want this to work and make it all consistent. I'd suggest defining the set of glEnable values that are 'global' and having every user set them to the desired value. That way, they will get changed only when actually changing modes, and not just to reset back to a 'base' state, whatever that means, under an assumption that gl will be able to easily optimize calls which set the state to the current value, but that flipping the state between two values may actually cost something. Right now, in glamor, we use: GL_BLEND, GL_COLOR_LOGIC_OP, GL_SCISSOR_TEST > As logic ops aren't very common, this sounds good to me. It's all inconsistent, which is the worst possible plan. -- -keith signature.asc Description: PGP signature ___ 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
Re: [PATCH xserver] glamor: Disable logic ops when doing compositing
Eric Anholt <e...@anholt.net> writes: > Keith Packard <kei...@keithp.com> writes: > >> If the logic op gets left enabled, it overrides the blending >> operation, causing incorrect contents on the display. >> >> Signed-off-by: Keith Packard <kei...@keithp.com> > > Reviewed-by: Eric Anholt <e...@anholt.net> And it's actually wrong (sigh). Need to do this in all paths through this function (even the PictOpSrc case), and we only want to do it on non-ES2 flavors. Here's an updated version. From 1ac2ef66369f36ef132f643969ad176db39babe7 Mon Sep 17 00:00:00 2001 From: Keith Packard <kei...@keithp.com> Date: Fri, 13 May 2016 04:25:43 -0700 Subject: [PATCH xserver] glamor: Disable logic ops when doing compositing [v2] If the logic op gets left enabled, it overrides the blending operation, causing incorrect contents on the display. v2: Disable only on non-ES2, but disable even for PictOpSrc Signed-off-by: Keith Packard <kei...@keithp.com> --- glamor/glamor_program.c | 4 1 file changed, 4 insertions(+) diff --git a/glamor/glamor_program.c b/glamor/glamor_program.c index 0a94de6..322d198 100644 --- a/glamor/glamor_program.c +++ b/glamor/glamor_program.c @@ -445,6 +445,7 @@ static struct blendinfo composite_op_info[] = { static void glamor_set_blend(CARD8 op, glamor_program_alpha alpha, PicturePtr dst) { +glamor_screen_private *glamor_priv = glamor_get_screen_private(dst->pDrawable->pScreen); GLenum src_blend, dst_blend; struct blendinfo *op_info; @@ -459,6 +460,9 @@ glamor_set_blend(CARD8 op, glamor_program_alpha alpha, PicturePtr dst) break; } +if (glamor_priv->gl_flavor != GLAMOR_GL_ES2) +glDisable(GL_COLOR_LOGIC_OP); + if (op == PictOpSrc) return; -- 2.8.0.rc3 -- -keith signature.asc Description: PGP signature ___ 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
[PATCH xserver] glamor: Disable logic ops when doing compositing
If the logic op gets left enabled, it overrides the blending operation, causing incorrect contents on the display. Signed-off-by: Keith Packard <kei...@keithp.com> --- glamor/glamor_program.c | 1 + 1 file changed, 1 insertion(+) diff --git a/glamor/glamor_program.c b/glamor/glamor_program.c index 0a94de6..a43ee6e 100644 --- a/glamor/glamor_program.c +++ b/glamor/glamor_program.c @@ -499,6 +499,7 @@ glamor_set_blend(CARD8 op, glamor_program_alpha alpha, PicturePtr dst) } glEnable(GL_BLEND); +glDisable(GL_COLOR_LOGIC_OP); glBlendFunc(src_blend, dst_blend); } -- 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
Re: [PATCH xserver 5/9] Create a threaded mechanism for input [v5]
Emil Velikovwrites: > The commit summary does not mention anything, just the revision log > suggests "linux only". Worth adding a couple of words to clarify > things ? good point, I reworded the 'v2' comment to say: v2: Fix non-Xorg link. Enable where supported by default. -- -keith signature.asc Description: PGP signature ___ 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
Re: [PATCH xserver] Use separate name for --with-bundle-version help variable
Jeremy Huddleston Sequoiawrites: > I actually already had a patch for that on my branch and just hadn't gotten > around to sending it, sorry: > > > https://github.com/XQuartz/xorg-server/commit/eb7c1e7fb16338d8fc03a0bb0f9bb53eb99ee139 > > I ended up just getting rid of the shell variable and only using the > m4 variable. I don't think we should be using AC_ as that should be > seen as a restricted namespace (like m4_, AS_, and AM_). If you > change the m4 variable name, then 'Reviewed-by: Jeremy Sequoia > ' or you can merge mine: Let's just use your patch; I was just fixing an error I saw in the configure output on Linux. -- -keith signature.asc Description: PGP signature ___ 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
Re: [PATCH RESEND xserver v3] xfree86: Immediately handle failure to set HW cursor
Alexandre Courbot <acour...@nvidia.com> writes: > Signed-off-by: Alexandre Courbot <acour...@nvidia.com> > Cc: Michael Thayer <michael.tha...@oracle.com> Reviewed-by: Keith Packard <kei...@keithp.com> -- -keith signature.asc Description: PGP signature ___ 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