[PATCH libevdev 1/3] Count the number of events needed for a full sync
Peter Hutterer
peter.hutterer at who-t.net
Sun Jan 19 15:58:37 PST 2014
On Fri, Jan 17, 2014 at 01:15:02PM +0100, David Herrmann wrote:
> Hi
>
> On Fri, Jan 17, 2014 at 4:31 AM, Peter Hutterer
> <peter.hutterer at who-t.net> wrote:
> > Make sure we have a queue that is at least large enough to do a full sync
> > after a SYN_DROPPED, plus store a few extra events in case some came in after
> > the sync.
>
> EVIOCGKEY() and friends flush the input queue, so there's no need to
> account for extra events. Obviously, we don't flush EV_REL or EV_ABS,
> as they don't suffer from synchronization-issues. So only these need
> extra space.
>
> On the other hand, there might be incoming events between our
> sync-ioctl()s, so we can never be sure there're no new events.. So
> maybe I should just shut up..
there's one use-case where we need the ability to store all key events: when
a client runs LIBEVDEV_READ_FLAG_FORCE_SYNC, which you will have to do (in
most cases) after libevdev_change_fd(). for example in the X driver, if the
device is disabled and re-enabled, the fd changes. to make sure the library
has the right view of the device, you need FORCE_SYNC. otherwise, libevdev
may think a key is still down even though it was released ages ago.
> > Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> > ---
> > libevdev/libevdev.c | 34 ++++++++++++++++++++++++++++++----
> > 1 file changed, 30 insertions(+), 4 deletions(-)
> >
> > diff --git a/libevdev/libevdev.c b/libevdev/libevdev.c
> > index 8a37204..59625a4 100644
> > --- a/libevdev/libevdev.c
> > +++ b/libevdev/libevdev.c
> > @@ -41,12 +41,38 @@ static int sync_mt_state(struct libevdev *dev, int create_events);
> > static int
> > init_event_queue(struct libevdev *dev)
> > {
> > - /* FIXME: count the number of axes, keys, etc. to get a better idea at how many events per
> > - EV_SYN we could possibly get. Then multiply that by the actual buffer size we care about */
> > + const int MIN_QUEUE_SIZE = 256;
> > + int nevents = 1; /* terminating SYN_REPORT */
>
> You do "nevents * 2" below, but you account for a single report here?
> Seems overkill, but ok, doesn't hurt.
>
> > + int nslots;
> > + unsigned int type, code;
> >
> > - const int QUEUE_SIZE = 256;
> > + /* count the number of axes, keys, etc. to get a better idea at how
> > + many events per EV_SYN we could possibly get. That's the max we
> > + may get during SYN_DROPPED too. Use double that, just so we have
> > + room for events while syncing an event.
> > + */
> > + for (type = EV_KEY; type < EV_MAX; type++) {
> > + int max = libevdev_event_type_get_max(type);
> > + for (code = 0; max > 0 && code < (unsigned int) max; code++) {
> > + if (libevdev_has_event_code(dev, type, code))
> > + nevents++;
> > + }
> > + }
> >
> > - return queue_alloc(dev, QUEUE_SIZE);
> > + nslots = libevdev_get_num_slots(dev);
> > + if (nslots > 1) {
> > + int num_mt_axes = 0;
> > +
> > + for (code = ABS_MT_SLOT; code < ABS_MAX; code++) {
> > + if (libevdev_has_event_code(dev, EV_ABS, code))
> > + num_mt_axes++;
> > + }
> > +
> > + /* We already counted the first slot in the initial count */
> > + nevents += num_mt_axes * (nslots - 1);
>
> Again a bit overkill to drop that one axis, but ok. Patch looks good to me:
> Reviewed-by: David Herrmann <dh.herrmann at gmail.com>
fwiw, just for correctness this is one slot, not just one axis, so
potentially 16 axes.
anyway, I admit that it seems overkill, I only added the * 2 late in the
patch. The reasoning is that we want the maximum number of possible events
plus a little bit. but "a little bit" is hard to define, so * 2 was the
easiest solution :)
Cheers,
Peter
> > + }
> > +
> > + return queue_alloc(dev, min(MIN_QUEUE_SIZE, nevents * 2));
> > }
> >
> > static void
> > --
> > 1.8.4.2
> >
> > _______________________________________________
> > Input-tools mailing list
> > Input-tools at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/input-tools
More information about the Input-tools
mailing list