Re: [PATCH xserver 2/6] Remove SIGIO support.
Peter Huttererwrites: >> /* Call PIE here so we don't try to dereference a device that's >> * already been removed. */ >> -OsBlockSignals(); >> ProcessInputEvents(); >> +input_lock(); > > this is a behaviour change, was this intended? I'd rather not have this > hidden in a giant patch that is otherwise mostly search and replace. (I knew locking was the hard part...). OsBlockSignals has a counter, so you can call it multiple times. input_lock is (going to be) a regular mutex, so you can't (and ProcessInputEvents definitely needs to hold the input lock). I moved this to eliminate a deadlock, only to now discover that xfree86's DeleteInputDeviceRequest grabs the input lock itself. And, kdrive's evdev driver calls DeleteInputDeviceRequest from the event reading code (!). We may uncover more deadlocks in the code; I think each one in isolation should be pretty easy to fix. We could also implement a counter in the mutex? That would require using thread local storage, which is kinda ugly, but should at least allow the existing locking to not deadlock. I'd rather work on annotating the code and data structures so that we know when the lock should be held; right now it's somewhat haphazard, with things like device property changes not taking the lock. For instance, in this case we would mark the device as 'pending deletion' and have the event queuing code discard incoming events: input_lock(); dev->pending_deletion = TRUE; input_unlock(); ProcessInputEvents(); input_lock(); DeleteInputDeviceRequest(dev); input_unlock(); >> @@ -1077,8 +1077,8 @@ TouchEndPhysicallyActiveTouches(DeviceIntPtr dev) >> InternalEvent *eventlist = InitEventList(GetMaximumEventsNum()); >> int i; >> >> -OsBlockSignals(); >> mieqProcessInputEvents(); >> +input_lock(); > > same here. How about making the first patch all the search/replace cases and > let input_lock/unlock call OsBlockSignals/OsReleaseSignals. Then in the > second patch you can change the places where it needs to be moved around, > then in a third patch actually drop the signal handling. For this case, mieqProcessDeviceEvent must not be called with the input_lock held as it (eventually) may call SetCursorPosition, which will grab input_lock to warp the cursor on the screen. Given what this function does, it seems like it is equivalent to: input_lock(); for (i = 0; i < dev->last.num_touches; i++) { DDXTouchPointInfoPtr ddxti = dev->last.touches + i; if (ddxti->active) QueueTouchEvents(dev, XI_TouchEnd, ddxti->ddx_id, 0, NULL); } input_unlock(); ProcessInputEvents(); Similarly, ReleaseButtonsAndKeys should be changed to queue the relevant events under the lock and then process them. That's a bit harder as that function is looking at the logical state of the device, not the physical state. It looks like that's just the tip of a large bug though -- a frozen device that gets removed is going to have events in the syncEvents list still pointing at it. That seems bad... >> +xf86ReadInput(int fd, int ready, void *closure) { > > new line for {, no empty line before static void Thanks. >> diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c >> index c42e93e..b506338 100644 >> --- a/hw/xfree86/common/xf86Helper.c >> +++ b/hw/xfree86/common/xf86Helper.c >> @@ -1729,7 +1729,7 @@ xf86SetSilkenMouse(ScreenPtr pScreen) >> * yet. Should handle this differently so that alternate async methods >> * work correctly with this too. >> */ >> -pScrn->silkenMouse = useSM && xf86Info.useSIGIO && xf86SIGIOSupported(); >> +pScrn->silkenMouse = useSM && FALSE; > > wait, what? It's a temporary hack -- having removed SIGIO and not replaced it with threading, all of the 'silken mouse' code can't actually work. Once we add threads, then this looks sensible again. >> libbsd_la_SOURCES = \ >> $(srcdir)/../shared/posix_tty.c \ >> -$(srcdir)/../shared/sigio.c \ >> $(srcdir)/../shared/vidmem.c \ >> bsd_VTsw.c \ >> bsd_init.c \ > > [...] I split the DRI1 breakage and SIGIO API removal out into separate patches so we can discuss whether DRI1 needs to be supported independently of whether input should be threaded. >> diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c >> index aeb702c..effda7c 100644 >> --- a/xkb/xkbActions.c >> +++ b/xkb/xkbActions.c >> @@ -1526,7 +1526,7 @@ InjectPointerKeyEvents(DeviceIntPtr dev, int type, int >> button, int flags, >> return; >> >> events = InitEventList(GetMaximumEventsNum() + 1); >> -OsBlockSignals(); >> +input_lock(); >> pScreen = miPointerGetScreen(ptr); >> saveWait = miPointerSetWaitForUpdate(pScreen, FALSE); >> nevents = GetPointerEvents(events, ptr, type, button, flags, mask); >> @@ -1534,10 +1534,10 @@ InjectPointerKeyEvents(DeviceIntPtr dev, int type, >> int
Re: [PATCH xserver 2/6] Remove SIGIO support.
On Wed, Dec 09, 2015 at 11:13:14AM -0800, Keith Packard wrote: > Peter Huttererwrites: > > >> /* Call PIE here so we don't try to dereference a device that's > >> * already been removed. */ > >> -OsBlockSignals(); > >> ProcessInputEvents(); > >> +input_lock(); > > > > this is a behaviour change, was this intended? I'd rather not have this > > hidden in a giant patch that is otherwise mostly search and replace. > > (I knew locking was the hard part...). > > OsBlockSignals has a counter, so you can call it multiple > times. input_lock is (going to be) a regular mutex, so you can't (and > ProcessInputEvents definitely needs to hold the input lock). I moved > this to eliminate a deadlock, only to now discover that xfree86's > DeleteInputDeviceRequest grabs the input lock itself. And, kdrive's > evdev driver calls DeleteInputDeviceRequest from the event reading code (!). > > We may uncover more deadlocks in the code; I think each one in isolation > should be pretty easy to fix. We could also implement a counter in the > mutex? That would require using thread local storage, which is kinda > ugly, but should at least allow the existing locking to not deadlock. > > I'd rather work on annotating the code and data structures so that we > know when the lock should be held; right now it's somewhat haphazard, > with things like device property changes not taking the lock. > > For instance, in this case we would mark the device as 'pending > deletion' and have the event queuing code discard incoming events: > > input_lock(); > dev->pending_deletion = TRUE; > input_unlock(); > ProcessInputEvents(); > input_lock(); > DeleteInputDeviceRequest(dev); > input_unlock(); > > >> @@ -1077,8 +1077,8 @@ TouchEndPhysicallyActiveTouches(DeviceIntPtr dev) > >> InternalEvent *eventlist = InitEventList(GetMaximumEventsNum()); > >> int i; > >> > >> -OsBlockSignals(); > >> mieqProcessInputEvents(); > >> +input_lock(); > > > > same here. How about making the first patch all the search/replace cases and > > let input_lock/unlock call OsBlockSignals/OsReleaseSignals. Then in the > > second patch you can change the places where it needs to be moved around, > > then in a third patch actually drop the signal handling. > > For this case, mieqProcessDeviceEvent must not be called with the > input_lock held as it (eventually) may call SetCursorPosition, which > will grab input_lock to warp the cursor on the screen. yes, but you can do that with the suggestion above. do a straightforward search/replace for OsBlockSignals -> input_lock, then when you drop OsBlockSignals from input_lock you can move things where needed. plus you get to see the places where the reordering was needed stand out. [ok, now that I read the rest of the email I see you're suggesting to do this further below] > Given what this > function does, it seems like it is equivalent to: > > input_lock(); > for (i = 0; i < dev->last.num_touches; i++) { > DDXTouchPointInfoPtr ddxti = dev->last.touches + i; > > if (ddxti->active) > QueueTouchEvents(dev, XI_TouchEnd, ddxti->ddx_id, 0, NULL); > } > input_unlock(); > ProcessInputEvents(); > > Similarly, ReleaseButtonsAndKeys should be changed to queue the relevant > events under the lock and then process them. That's a bit harder as that > function is looking at the logical state of the device, not the physical > state. It looks like that's just the tip of a large bug though -- a > frozen device that gets removed is going to have events in the > syncEvents list still pointing at it. That seems bad... > > >> +xf86ReadInput(int fd, int ready, void *closure) { > > > > new line for {, no empty line before static void > > Thanks. > > >> diff --git a/hw/xfree86/common/xf86Helper.c > >> b/hw/xfree86/common/xf86Helper.c > >> index c42e93e..b506338 100644 > >> --- a/hw/xfree86/common/xf86Helper.c > >> +++ b/hw/xfree86/common/xf86Helper.c > >> @@ -1729,7 +1729,7 @@ xf86SetSilkenMouse(ScreenPtr pScreen) > >> * yet. Should handle this differently so that alternate async > >> methods > >> * work correctly with this too. > >> */ > >> -pScrn->silkenMouse = useSM && xf86Info.useSIGIO && > >> xf86SIGIOSupported(); > >> +pScrn->silkenMouse = useSM && FALSE; > > > > wait, what? > > It's a temporary hack -- having removed SIGIO and not replaced it with > threading, all of the 'silken mouse' code can't actually work. Once we > add threads, then this looks sensible again. add a comment please, if for no other reason than to reduce confusion of those who look at the patches separately. > > >> libbsd_la_SOURCES = \ > >>$(srcdir)/../shared/posix_tty.c \ > >> - $(srcdir)/../shared/sigio.c \ > >>$(srcdir)/../shared/vidmem.c \ > >>bsd_VTsw.c \ > >>bsd_init.c \ > > > > [...] > > I split the DRI1 breakage and SIGIO API
Re: [PATCH xserver 2/6] Remove SIGIO support.
Peter Huttererwrites: > this is a behaviour change, was this intended? I'd rather not have this > hidden in a giant patch that is otherwise mostly search and replace. Ok, I've pushed out a new series which creates a recursive (counting) mutex that makes all of this stuff quite easy. Nice to have only two threads, and to not be worrying about performance here. In particular, I didn't have to move locks around, except for one case where the existing code looked like it wasn't locking enough. That's a separate patch. I'll send the updated series to the list; it's also in my git repository at: git://people.freedesktop.org/~keithp/xserver.git input-thread This also removes the (controversial) DRI1 changes from this series; they're tacked ontop of the fd_set patches in my remove-xfree86-sigio branch. -- -keith signature.asc Description: PGP signature ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
Re: [PATCH xserver 2/6] Remove SIGIO support.
On 12/ 8/15 03:44 PM, Keith Packard wrote: This removes all of the SIGIO handling support throughout the X server, preparing the way for using threads for input handling instead. Places calling OsBlockSIGIO and OsReleaseSIGIO are marked with calls to stub functions input_lock/input_unlock so that we don't lose this information. Signed-off-by: Keith Packard--- Xi/exevents.c | 4 +- config/config.c | 4 +- dix/devices.c | 10 +- dix/ptrveloc.c| 4 +- dix/touch.c | 8 +- hw/dmx/input/dmxevents.c | 24 +-- hw/kdrive/ephyr/ephyr.c | 4 +- hw/kdrive/src/kinput.c| 74 +--- hw/xfree86/common/xf86Config.c| 24 --- hw/xfree86/common/xf86Cursor.c| 8 +- hw/xfree86/common/xf86Events.c| 33 ++-- hw/xfree86/common/xf86Helper.c| 2 +- hw/xfree86/common/xf86Init.c | 6 +- hw/xfree86/common/xf86PM.c| 8 +- hw/xfree86/common/xf86Xinput.c| 8 +- hw/xfree86/dri/dri.c | 54 +- hw/xfree86/os-support/bsd/Makefile.am | 1 - hw/xfree86/os-support/hurd/Makefile.am| 1 - hw/xfree86/os-support/linux/Makefile.am | 1 - hw/xfree86/os-support/shared/sigio.c | 291 -- hw/xfree86/os-support/shared/sigiostubs.c | 70 --- hw/xfree86/os-support/solaris/Makefile.am | 1 - hw/xfree86/os-support/stub/Makefile.am| 1 - hw/xfree86/os-support/xf86_OSproc.h | 12 -- include/os.h | 6 - mi/mieq.c | 6 +- mi/mipointer.c| 4 +- os/utils.c| 54 +- test/Makefile.am | 2 +- test/os.c | 166 - xkb/xkbActions.c | 4 +- 31 files changed, 77 insertions(+), 818 deletions(-) delete mode 100644 hw/xfree86/os-support/shared/sigio.c delete mode 100644 hw/xfree86/os-support/shared/sigiostubs.c delete mode 100644 test/os.c Shouldn't this also remove all the USE_SIGIO_BY_DEFAULT references in configure.ac? -- -Alan Coopersmith- alan.coopersm...@oracle.com Oracle Solaris Engineering - http://blogs.oracle.com/alanc ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
Re: [PATCH xserver 2/6] Remove SIGIO support.
Alan Coopersmithwrites: > Shouldn't this also remove all the USE_SIGIO_BY_DEFAULT references in > configure.ac? Yes. Thanks! -- -keith signature.asc Description: PGP signature ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
Re: [PATCH xserver 2/6] Remove SIGIO support.
On Tue, Dec 08, 2015 at 03:44:50PM -0800, Keith Packard wrote: > This removes all of the SIGIO handling support throughout the X > server, preparing the way for using threads for input handling > instead. > > Places calling OsBlockSIGIO and OsReleaseSIGIO are marked with calls > to stub functions input_lock/input_unlock so that we don't lose this > information. > > Signed-off-by: Keith Packard[...] > /** > diff --git a/config/config.c b/config/config.c > index de45cc3..263982e 100644 > --- a/config/config.c > +++ b/config/config.c > @@ -86,10 +86,10 @@ remove_device(const char *backend, DeviceIntPtr dev) > > /* Call PIE here so we don't try to dereference a device that's > * already been removed. */ > -OsBlockSignals(); > ProcessInputEvents(); > +input_lock(); this is a behaviour change, was this intended? I'd rather not have this hidden in a giant patch that is otherwise mostly search and replace. > DeleteInputDeviceRequest(dev); > -OsReleaseSignals(); > +input_unlock(); > } > > void > diff --git a/dix/devices.c b/dix/devices.c > index 9b0c7d2..7ba6b94 100644 > --- a/dix/devices.c > +++ b/dix/devices.c [...] > @@ -1077,8 +1077,8 @@ TouchEndPhysicallyActiveTouches(DeviceIntPtr dev) > InternalEvent *eventlist = InitEventList(GetMaximumEventsNum()); > int i; > > -OsBlockSignals(); > mieqProcessInputEvents(); > +input_lock(); same here. How about making the first patch all the search/replace cases and let input_lock/unlock call OsBlockSignals/OsReleaseSignals. Then in the second patch you can change the places where it needs to be moved around, then in a third patch actually drop the signal handling. > for (i = 0; i < dev->last.num_touches; i++) { > DDXTouchPointInfoPtr ddxti = dev->last.touches + i; > > @@ -1091,7 +1091,7 @@ TouchEndPhysicallyActiveTouches(DeviceIntPtr dev) > mieqProcessDeviceEvent(dev, eventlist + j, NULL); > } > } > -OsReleaseSignals(); > +input_unlock(); > > FreeEventList(eventlist, GetMaximumEventsNum()); > } > diff --git a/hw/dmx/input/dmxevents.c b/hw/dmx/input/dmxevents.c > index 2b579ee..3789602 100644 > --- a/hw/dmx/input/dmxevents.c > +++ b/hw/dmx/input/dmxevents.c > @@ -227,25 +227,25 @@ dmxCoreMotion(DevicePtr pDev, int x, int y, int delta, > DMXBlockType block) > && pScreen->myNum == dmxScreen->index) { > /* Screen is old screen */ > if (block) > -OsBlockSIGIO(); > +input_lock(); > if (pDev) > enqueueMotion(pDev, localX, localY); > if (block) > -OsReleaseSIGIO(); > +input_unlock(); > } > else { > /* Screen is new */ > DMXDBG4(" New screen: old=%d new=%d localX=%d localY=%d\n", > pScreen->myNum, dmxScreen->index, localX, localY); > if (block) > -OsBlockSIGIO(); > +input_lock(); > mieqProcessInputEvents(); > miPointerSetScreen(inputInfo.pointer, dmxScreen->index, > localX, localY); > if (pDev) > enqueueMotion(pDev, localX, localY); > if (block) > -OsReleaseSIGIO(); > +input_unlock(); > } > #if 00 > miPointerGetPosition(inputInfo.pointer, , ); > @@ -387,12 +387,12 @@ dmxExtMotion(DMXLocalInputInfoPtr dmxLocal, > } > > if (block) > -OsBlockSIGIO(); > +input_lock(); > valuator_mask_set_range(, firstAxis, axesCount, v); > QueuePointerEvents(pDevice, MotionNotify, 0, POINTER_ABSOLUTE, ); > > if (block) > -OsReleaseSIGIO(); > +input_unlock(); > } > > static int > @@ -489,10 +489,10 @@ dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr > dmxLocal, > case XI_DeviceKeyPress: > case XI_DeviceKeyRelease: > if (block) > -OsBlockSIGIO(); > +input_lock(); > QueueKeyboardEvents(pDevice, event, ke->keycode); > if (block) > -OsReleaseSIGIO(); > +input_unlock(); > break; > case XI_DeviceButtonPress: > case XI_DeviceButtonRelease: > @@ -500,11 +500,11 @@ dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr > dmxLocal, > valuator_mask_set_range(, ke->first_axis, ke->axes_count, > valuators); > if (block) > -OsBlockSIGIO(); > +input_lock(); > QueuePointerEvents(pDevice, event, ke->keycode, > POINTER_ABSOLUTE, ); > if (block) > -OsReleaseSIGIO(); > +input_unlock(); > break; > case XI_ProximityIn: > case XI_ProximityOut: > @@ -512,10 +512,10 @@ dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr > dmxLocal, >