Re: sem_open

2013-10-25 Thread Vadim Zhukov
> This may or may not be a working implementation of sem_open.

This is a bit improved version of Ted's diff:

  * Add support of shared=1 for sem_init()
  * Less memory leaks in error paths
  * More strong checks where applicable

This is RFC/FYI status only, still under testing.
--
zhuk@


Index: sys/kern/kern_synch.c
===
RCS file: /cvs/src/sys/kern/kern_synch.c,v
retrieving revision 1.108
diff -u -p -r1.108 kern_synch.c
--- sys/kern/kern_synch.c   14 Sep 2013 01:35:01 -  1.108
+++ sys/kern/kern_synch.c   26 Oct 2013 01:34:03 -
@@ -419,6 +419,7 @@ thrsleep_unlock(void *lock, int lockflag
return (error);
 }
 
+static int magicnumber;
 
 int
 thrsleep(struct proc *p, struct sys___thrsleep_args *v)
@@ -482,9 +483,13 @@ thrsleep(struct proc *p, struct sys___th
 
if (p->p_thrslpid == 0)
error = 0;
-   else
-   error = tsleep(&p->p_thrslpid, PUSER | PCATCH, "thrsleep",
+   else {
+   void *sleepaddr = &p->p_thrslpid;
+   if (ident == -1)
+   sleepaddr = &magicnumber;
+   error = tsleep(sleepaddr, PUSER | PCATCH, "thrsleep",
(int)to_ticks);
+   }
 
 out:
p->p_thrslpid = 0;
@@ -535,6 +540,8 @@ sys___thrwakeup(struct proc *p, void *v,
 
if (ident == 0)
*retval = EINVAL;
+   else if (ident == -1)
+   wakeup(&magicnumber);
else {
TAILQ_FOREACH(q, &p->p_p->ps_threads, p_thr_link) {
if (q->p_thrslpid == ident) {
Index: lib/librthread/rthread.h
===
RCS file: /cvs/src/lib/librthread/rthread.h,v
retrieving revision 1.45
diff -u -p -r1.45 rthread.h
--- lib/librthread/rthread.h21 Jun 2013 06:08:50 -  1.45
+++ lib/librthread/rthread.h26 Oct 2013 01:34:03 -
@@ -64,7 +64,7 @@ struct __sem {
struct _spinlock lock;
volatile int waitcount;
volatile int value;
-   int __pad;
+   struct __sem *shared;
 };
 
 TAILQ_HEAD(pthread_queue, pthread);
Index: lib/librthread/rthread_sem.c
===
RCS file: /cvs/src/lib/librthread/rthread_sem.c,v
retrieving revision 1.9
diff -u -p -r1.9 rthread_sem.c
--- lib/librthread/rthread_sem.c1 Jun 2013 23:06:26 -   1.9
+++ lib/librthread/rthread_sem.c26 Oct 2013 01:34:03 -
@@ -1,6 +1,6 @@
 /* $OpenBSD: rthread_sem.c,v 1.9 2013/06/01 23:06:26 tedu Exp $ */
 /*
- * Copyright (c) 2004,2005 Ted Unangst 
+ * Copyright (c) 2004,2005,2013 Ted Unangst 
  * All Rights Reserved.
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -15,15 +15,39 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+#include 
+#include 
+#include 
+#include 
 
+#include 
+#include 
+#include 
+#include 
 #include 
+#include 
+#include 
 #include 
-#include 
 
 #include 
 
 #include "rthread.h"
 
+#define SHARED_IDENT ((void *)-1)
+
+/* SHA256_DIGEST_STRING_LENGTH includes nul */
+/* "/tmp/" + sha256 + ".sem" */
+#define SEM_PATH_SIZE (5 + SHA256_DIGEST_STRING_LENGTH + 4)
+
+/* long enough to be hard to guess */
+#define SEM_RANDOM_NAME_LEN160
+
+/*
+ * Size of memory to be mmap()'ed by named semaphores.
+ * Should be >= SEM_PATH_SIZE and page-aligned.
+ */
+#define SEM_MMAP_SIZE  PAGE_SIZE
+
 /*
  * Internal implementation of semaphores
  */
@@ -31,8 +55,14 @@ int
 _sem_wait(sem_t sem, int tryonly, const struct timespec *abstime,
 int *delayed_cancel)
 {
+   void *ident = (void *)&sem->waitcount;
int r;
 
+   if (sem->shared) {
+   sem = sem->shared;
+   ident = SHARED_IDENT;
+   }
+
_spinlock(&sem->lock);
if (sem->value) {
sem->value--;
@@ -42,7 +72,7 @@ _sem_wait(sem_t sem, int tryonly, const 
} else {
sem->waitcount++;
do {
-   r = __thrsleep(&sem->waitcount, CLOCK_REALTIME |
+   r = __thrsleep(ident, CLOCK_REALTIME |
_USING_TICKETS, abstime, &sem->lock.ticket,
delayed_cancel);
_spinlock(&sem->lock);
@@ -63,12 +93,18 @@ _sem_wait(sem_t sem, int tryonly, const 
 int
 _sem_post(sem_t sem)
 {
+   void *ident = (void *)&sem->waitcount;
int rv = 0;
 
+   if (sem->shared) {
+   sem = sem->shared;
+   ident = SHARED_IDENT;
+   }
+
_spinlock(&sem->lock);
sem->value++;
if (sem->waitcount) {
-   __thrwakeup(&sem->waitcount, 1);
+   __thrwakeup(ident, 1);
rv = 1;
}
_spinunlock(&sem->lock);
@@ -81,11 +117,39 @@ _sem_post(sem_t sem)
 int
 sem_i

Re: sem_open

2013-10-25 Thread Vadim Zhukov
2013/10/26 Ted Unangst :
> This may or may not be a working implementation of sem_open.
>
> Using tricks similar to those used in shm_open, we create a semaphore
> in a tmp file shared by mmap. This lets other processes share the
> spinlock and counter. Our thrsleep and thrwakeup syscalls don't really
> work between processes, so we have to synchronize all processes on the
> same in kernel address. This will cause spurious wakeups, but it
> shouldn't be the end of the world for light use.
>
> Index: sys/kern/kern_synch.c
> ===
> RCS file: /cvs/src/sys/kern/kern_synch.c,v
> retrieving revision 1.108
> diff -u -p -r1.108 kern_synch.c
> --- sys/kern/kern_synch.c   14 Sep 2013 01:35:01 -  1.108
> +++ sys/kern/kern_synch.c   25 Oct 2013 20:20:47 -
> @@ -419,6 +419,7 @@ thrsleep_unlock(void *lock, int lockflag
> return (error);
>  }
>
> +static int magicnumber;
>
>  int
>  thrsleep(struct proc *p, struct sys___thrsleep_args *v)
> @@ -482,9 +483,13 @@ thrsleep(struct proc *p, struct sys___th
>
> if (p->p_thrslpid == 0)
> error = 0;
> -   else
> -   error = tsleep(&p->p_thrslpid, PUSER | PCATCH, "thrsleep",
> +   else {
> +   void *sleepaddr = &p->p_thrslpid;
> +   if (ident == -1)
> +   sleepaddr = &magicnumber;
> +   error = tsleep(sleepaddr, PUSER | PCATCH, "thrsleep",
> (int)to_ticks);
> +   }
>
>  out:
> p->p_thrslpid = 0;
> @@ -535,6 +540,8 @@ sys___thrwakeup(struct proc *p, void *v,
>
> if (ident == 0)
> *retval = EINVAL;
> +   else if (ident == -1)
> +   wakeup(&magicnumber);
> else {
> TAILQ_FOREACH(q, &p->p_p->ps_threads, p_thr_link) {
> if (q->p_thrslpid == ident) {
> Index: lib/librthread/rthread.h
> ===
> RCS file: /cvs/src/lib/librthread/rthread.h,v
> retrieving revision 1.45
> diff -u -p -r1.45 rthread.h
> --- lib/librthread/rthread.h21 Jun 2013 06:08:50 -  1.45
> +++ lib/librthread/rthread.h25 Oct 2013 20:20:47 -
> @@ -64,7 +64,7 @@ struct __sem {
> struct _spinlock lock;
> volatile int waitcount;
> volatile int value;
> -   int __pad;
> +   struct __sem *shared;
>  };
>
>  TAILQ_HEAD(pthread_queue, pthread);
> Index: lib/librthread/rthread_sem.c
> ===
> RCS file: /cvs/src/lib/librthread/rthread_sem.c,v
> retrieving revision 1.9
> diff -u -p -r1.9 rthread_sem.c
> --- lib/librthread/rthread_sem.c1 Jun 2013 23:06:26 -   1.9
> +++ lib/librthread/rthread_sem.c25 Oct 2013 20:20:47 -
> @@ -1,6 +1,6 @@
>  /* $OpenBSD: rthread_sem.c,v 1.9 2013/06/01 23:06:26 tedu Exp $ */
>  /*
> - * Copyright (c) 2004,2005 Ted Unangst 
> + * Copyright (c) 2004,2005,2013 Ted Unangst 
>   * All Rights Reserved.
>   *
>   * Permission to use, copy, modify, and distribute this software for any
> @@ -15,15 +15,25 @@
>   * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
>   * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>   */
> +#include 
> +#include 
> +#include 
> +#include 
>
> +#include 
> +#include 
> +#include 
>  #include 
> +#include 
> +#include 
>  #include 
> -#include 
>
>  #include 
>
>  #include "rthread.h"
>
> +#define SHARED_IDENT ((void *)-1)
> +
>  /*
>   * Internal implementation of semaphores
>   */
> @@ -31,8 +41,14 @@ int
>  _sem_wait(sem_t sem, int tryonly, const struct timespec *abstime,
>  int *delayed_cancel)
>  {
> +   void *ident = (void *)&sem->waitcount;
> int r;
>
> +   if (sem->shared) {
> +   sem = sem->shared;
> +   ident = SHARED_IDENT;
> +   }
> +
> _spinlock(&sem->lock);
> if (sem->value) {
> sem->value--;
> @@ -42,7 +58,7 @@ _sem_wait(sem_t sem, int tryonly, const
> } else {
> sem->waitcount++;
> do {
> -   r = __thrsleep(&sem->waitcount, CLOCK_REALTIME |
> +   r = __thrsleep(ident, CLOCK_REALTIME |
> _USING_TICKETS, abstime, &sem->lock.ticket,
> delayed_cancel);
> _spinlock(&sem->lock);
> @@ -63,12 +79,18 @@ _sem_wait(sem_t sem, int tryonly, const
>  int
>  _sem_post(sem_t sem)
>  {
> +   void *ident = (void *)&sem->waitcount;
> int rv = 0;
>
> +   if (sem->shared) {
> +   sem = sem->shared;
> +   ident = SHARED_IDENT;
> +   }
> +
> _spinlock(&sem->lock);
> sem->value++;
> if (sem->waitcount) {
> -   __thrwakeup(&sem->waitcount, 1);
> +   __thrwakeup(ident, 1);
> rv = 1;
> }
>

Re: sem_open

2013-10-25 Thread Theo de Raadt
> On Sat, Oct 26, 2013 at 00:54, Vadim Zhukov wrote:
> >> +/* SHA256_DIGEST_STRING_LENGTH includes nul */
> >> +/* "/tmp/" + sha256 + ".sem" */
> > 
> > Shouldn't this respect the TMPDIR envvar?
> 
> No, it's an internal artifact of the implementation.

And furthermore, making additional library functions honour
environment variables?  tsk tsk.



Re: sem_open

2013-10-25 Thread Ted Unangst
On Sat, Oct 26, 2013 at 00:54, Vadim Zhukov wrote:
>> +/* SHA256_DIGEST_STRING_LENGTH includes nul */
>> +/* "/tmp/" + sha256 + ".sem" */
> 
> Shouldn't this respect the TMPDIR envvar?

No, it's an internal artifact of the implementation.



Re: sem_open

2013-10-25 Thread Vadim Zhukov
2013/10/26 Ted Unangst :
> This may or may not be a working implementation of sem_open.
>
> Using tricks similar to those used in shm_open, we create a semaphore
> in a tmp file shared by mmap. This lets other processes share the
> spinlock and counter. Our thrsleep and thrwakeup syscalls don't really
> work between processes, so we have to synchronize all processes on the
> same in kernel address. This will cause spurious wakeups, but it
> shouldn't be the end of the world for light use.
>
> Index: sys/kern/kern_synch.c
> ===
> RCS file: /cvs/src/sys/kern/kern_synch.c,v
> retrieving revision 1.108
> diff -u -p -r1.108 kern_synch.c
> --- sys/kern/kern_synch.c   14 Sep 2013 01:35:01 -  1.108
> +++ sys/kern/kern_synch.c   25 Oct 2013 20:20:47 -
> @@ -419,6 +419,7 @@ thrsleep_unlock(void *lock, int lockflag
> return (error);
>  }
>
> +static int magicnumber;
>
>  int
>  thrsleep(struct proc *p, struct sys___thrsleep_args *v)
> @@ -482,9 +483,13 @@ thrsleep(struct proc *p, struct sys___th
>
> if (p->p_thrslpid == 0)
> error = 0;
> -   else
> -   error = tsleep(&p->p_thrslpid, PUSER | PCATCH, "thrsleep",
> +   else {
> +   void *sleepaddr = &p->p_thrslpid;
> +   if (ident == -1)
> +   sleepaddr = &magicnumber;
> +   error = tsleep(sleepaddr, PUSER | PCATCH, "thrsleep",
> (int)to_ticks);
> +   }
>
>  out:
> p->p_thrslpid = 0;
> @@ -535,6 +540,8 @@ sys___thrwakeup(struct proc *p, void *v,
>
> if (ident == 0)
> *retval = EINVAL;
> +   else if (ident == -1)
> +   wakeup(&magicnumber);
> else {
> TAILQ_FOREACH(q, &p->p_p->ps_threads, p_thr_link) {
> if (q->p_thrslpid == ident) {
> Index: lib/librthread/rthread.h
> ===
> RCS file: /cvs/src/lib/librthread/rthread.h,v
> retrieving revision 1.45
> diff -u -p -r1.45 rthread.h
> --- lib/librthread/rthread.h21 Jun 2013 06:08:50 -  1.45
> +++ lib/librthread/rthread.h25 Oct 2013 20:20:47 -
> @@ -64,7 +64,7 @@ struct __sem {
> struct _spinlock lock;
> volatile int waitcount;
> volatile int value;
> -   int __pad;
> +   struct __sem *shared;
>  };
>
>  TAILQ_HEAD(pthread_queue, pthread);
> Index: lib/librthread/rthread_sem.c
> ===
> RCS file: /cvs/src/lib/librthread/rthread_sem.c,v
> retrieving revision 1.9
> diff -u -p -r1.9 rthread_sem.c
> --- lib/librthread/rthread_sem.c1 Jun 2013 23:06:26 -   1.9
> +++ lib/librthread/rthread_sem.c25 Oct 2013 20:20:47 -
> @@ -1,6 +1,6 @@
>  /* $OpenBSD: rthread_sem.c,v 1.9 2013/06/01 23:06:26 tedu Exp $ */
>  /*
> - * Copyright (c) 2004,2005 Ted Unangst 
> + * Copyright (c) 2004,2005,2013 Ted Unangst 
>   * All Rights Reserved.
>   *
>   * Permission to use, copy, modify, and distribute this software for any
> @@ -15,15 +15,25 @@
>   * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
>   * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>   */
> +#include 
> +#include 
> +#include 
> +#include 
>
> +#include 
> +#include 
> +#include 
>  #include 
> +#include 
> +#include 
>  #include 
> -#include 
>
>  #include 
>
>  #include "rthread.h"
>
> +#define SHARED_IDENT ((void *)-1)
> +
>  /*
>   * Internal implementation of semaphores
>   */
> @@ -31,8 +41,14 @@ int
>  _sem_wait(sem_t sem, int tryonly, const struct timespec *abstime,
>  int *delayed_cancel)
>  {
> +   void *ident = (void *)&sem->waitcount;
> int r;
>
> +   if (sem->shared) {
> +   sem = sem->shared;
> +   ident = SHARED_IDENT;
> +   }
> +
> _spinlock(&sem->lock);
> if (sem->value) {
> sem->value--;
> @@ -42,7 +58,7 @@ _sem_wait(sem_t sem, int tryonly, const
> } else {
> sem->waitcount++;
> do {
> -   r = __thrsleep(&sem->waitcount, CLOCK_REALTIME |
> +   r = __thrsleep(ident, CLOCK_REALTIME |
> _USING_TICKETS, abstime, &sem->lock.ticket,
> delayed_cancel);
> _spinlock(&sem->lock);
> @@ -63,12 +79,18 @@ _sem_wait(sem_t sem, int tryonly, const
>  int
>  _sem_post(sem_t sem)
>  {
> +   void *ident = (void *)&sem->waitcount;
> int rv = 0;
>
> +   if (sem->shared) {
> +   sem = sem->shared;
> +   ident = SHARED_IDENT;
> +   }
> +
> _spinlock(&sem->lock);
> sem->value++;
> if (sem->waitcount) {
> -   __thrwakeup(&sem->waitcount, 1);
> +   __thrwakeup(ident, 1);
> rv = 1;
> }
>

sem_open

2013-10-25 Thread Ted Unangst
This may or may not be a working implementation of sem_open.

Using tricks similar to those used in shm_open, we create a semaphore
in a tmp file shared by mmap. This lets other processes share the
spinlock and counter. Our thrsleep and thrwakeup syscalls don't really
work between processes, so we have to synchronize all processes on the
same in kernel address. This will cause spurious wakeups, but it
shouldn't be the end of the world for light use.

Index: sys/kern/kern_synch.c
===
RCS file: /cvs/src/sys/kern/kern_synch.c,v
retrieving revision 1.108
diff -u -p -r1.108 kern_synch.c
--- sys/kern/kern_synch.c   14 Sep 2013 01:35:01 -  1.108
+++ sys/kern/kern_synch.c   25 Oct 2013 20:20:47 -
@@ -419,6 +419,7 @@ thrsleep_unlock(void *lock, int lockflag
return (error);
 }
 
+static int magicnumber;
 
 int
 thrsleep(struct proc *p, struct sys___thrsleep_args *v)
@@ -482,9 +483,13 @@ thrsleep(struct proc *p, struct sys___th
 
if (p->p_thrslpid == 0)
error = 0;
-   else
-   error = tsleep(&p->p_thrslpid, PUSER | PCATCH, "thrsleep",
+   else {
+   void *sleepaddr = &p->p_thrslpid;
+   if (ident == -1)
+   sleepaddr = &magicnumber;
+   error = tsleep(sleepaddr, PUSER | PCATCH, "thrsleep",
(int)to_ticks);
+   }
 
 out:
p->p_thrslpid = 0;
@@ -535,6 +540,8 @@ sys___thrwakeup(struct proc *p, void *v,
 
if (ident == 0)
*retval = EINVAL;
+   else if (ident == -1)
+   wakeup(&magicnumber);
else {
TAILQ_FOREACH(q, &p->p_p->ps_threads, p_thr_link) {
if (q->p_thrslpid == ident) {
Index: lib/librthread/rthread.h
===
RCS file: /cvs/src/lib/librthread/rthread.h,v
retrieving revision 1.45
diff -u -p -r1.45 rthread.h
--- lib/librthread/rthread.h21 Jun 2013 06:08:50 -  1.45
+++ lib/librthread/rthread.h25 Oct 2013 20:20:47 -
@@ -64,7 +64,7 @@ struct __sem {
struct _spinlock lock;
volatile int waitcount;
volatile int value;
-   int __pad;
+   struct __sem *shared;
 };
 
 TAILQ_HEAD(pthread_queue, pthread);
Index: lib/librthread/rthread_sem.c
===
RCS file: /cvs/src/lib/librthread/rthread_sem.c,v
retrieving revision 1.9
diff -u -p -r1.9 rthread_sem.c
--- lib/librthread/rthread_sem.c1 Jun 2013 23:06:26 -   1.9
+++ lib/librthread/rthread_sem.c25 Oct 2013 20:20:47 -
@@ -1,6 +1,6 @@
 /* $OpenBSD: rthread_sem.c,v 1.9 2013/06/01 23:06:26 tedu Exp $ */
 /*
- * Copyright (c) 2004,2005 Ted Unangst 
+ * Copyright (c) 2004,2005,2013 Ted Unangst 
  * All Rights Reserved.
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -15,15 +15,25 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+#include 
+#include 
+#include 
+#include 
 
+#include 
+#include 
+#include 
 #include 
+#include 
+#include 
 #include 
-#include 
 
 #include 
 
 #include "rthread.h"
 
+#define SHARED_IDENT ((void *)-1)
+
 /*
  * Internal implementation of semaphores
  */
@@ -31,8 +41,14 @@ int
 _sem_wait(sem_t sem, int tryonly, const struct timespec *abstime,
 int *delayed_cancel)
 {
+   void *ident = (void *)&sem->waitcount;
int r;
 
+   if (sem->shared) {
+   sem = sem->shared;
+   ident = SHARED_IDENT;
+   }
+
_spinlock(&sem->lock);
if (sem->value) {
sem->value--;
@@ -42,7 +58,7 @@ _sem_wait(sem_t sem, int tryonly, const 
} else {
sem->waitcount++;
do {
-   r = __thrsleep(&sem->waitcount, CLOCK_REALTIME |
+   r = __thrsleep(ident, CLOCK_REALTIME |
_USING_TICKETS, abstime, &sem->lock.ticket,
delayed_cancel);
_spinlock(&sem->lock);
@@ -63,12 +79,18 @@ _sem_wait(sem_t sem, int tryonly, const 
 int
 _sem_post(sem_t sem)
 {
+   void *ident = (void *)&sem->waitcount;
int rv = 0;
 
+   if (sem->shared) {
+   sem = sem->shared;
+   ident = SHARED_IDENT;
+   }
+
_spinlock(&sem->lock);
sem->value++;
if (sem->waitcount) {
-   __thrwakeup(&sem->waitcount, 1);
+   __thrwakeup(ident, 1);
rv = 1;
}
_spinunlock(&sem->lock);
@@ -136,6 +158,9 @@ sem_getvalue(sem_t *semp, int *sval)
return (-1);
}
 
+   if (sem->shared)
+   sem = sem->shared;
+
_spinlock(&sem->lock);
*sval = sem->value;
_spinunlock(&sem->lock);
@@ -227,27 +252,88 @@

Genesys Logic GL620USB-A, USB PC-to-PC link cable

2013-10-25 Thread SASANO Takayoshi
Hello,

I wrote a driver for Genesys Logic's GL620USB-A to test my USB
PC-to-PC link cable. This controller is old (USB 1.1 age!) but
GL620USB-A based link cable is still sold at eBay.

To support GL620USB-A, I modified sys/dev/usb/if_upl.c (Prolific
PL-2301/2302 driver) and added some stuffs. These kind of devices
simply provide communication pipes on USB, and I heard that PL-2301
driver can drive GL620USB-A with adding idVendor/idProduct. [1]

This is simple resolution but it limits the peer to OpenBSD box. So I
wrote GL620USB-A driver as new one to be compatible with Linux's
usbnet driver. [2]

I named the driver ugl(if_ugl.c) and tested it on
OpenBSD-current/amd64 with Slackware-14.0. The patch is at
http://www2192ue.sakura.ne.jp/~uaa/gomitext/2013/20131023/20131026.diff

Is anyone interested in the driver for such an old device?
Any comments and advices are appreciated.

[1] 
http://circuithijacker.blogspot.jp/2007/02/usb-host-to-host-cables-with-slax-linux.html
[2] http://www.linux-usb.org/usbnet/

Best regards,
-- 
SASANO Takayoshi 



Re: Stairstep mouse motion

2013-10-25 Thread Edd Barrett
On Thu, Oct 24, 2013 at 10:33:22PM +0300, Henri Kemppainen wrote:
> What happens when priv->swap_axes is set, and the ax && ay branch is
> taken along with the wsWheelEmuFilterMotion() branch.  Following
> continue another event is processed and now the axes are swapped again
> (ax and ay were not reset after use) and then what?  Not very likely
> I know.

Ah, yes, there is the possibility of posting an inconsistent pointer sample
in this case. Perhaps we should only update the old_ax/old_ay if the
wsWheelEmuFilterMotion branch is not taken?

What do you think? And yes, this is a very very unlikely case. You could
argue it wouldn't matter even if it did happen.

-- 
Best Regards
Edd Barrett

http://www.theunixzoo.co.uk