USB HID mouse/keyboard: Fix a reference counting problem

This commit is contained in:
Gregory Nutt 2015-04-25 17:05:30 -06:00
parent 329ae78583
commit 3bae38a2d9
2 changed files with 20 additions and 21 deletions

View File

@ -55,6 +55,7 @@
#include <debug.h> #include <debug.h>
#include <nuttx/kmalloc.h> #include <nuttx/kmalloc.h>
#include <nuttx/kthread.h>
#include <nuttx/fs/fs.h> #include <nuttx/fs/fs.h>
#include <nuttx/arch.h> #include <nuttx/arch.h>
#include <nuttx/wqueue.h> #include <nuttx/wqueue.h>
@ -1022,9 +1023,10 @@ static int usbhost_kbdpoll(int argc, char *argv[])
* the start-up logic, and wait a bit to make sure that all of the class * the start-up logic, and wait a bit to make sure that all of the class
* creation logic has a chance to run to completion. * creation logic has a chance to run to completion.
* *
* NOTE: that the reference count is incremented here. Therefore, we know * NOTE: that the reference count is *not* incremented here. When the driver
* that the driver data structure will remain stable while this thread is * structure was created, it was created with a reference count of one. This
* running. * thread is responsible for that count. The count will be decrement when
* this thread exits.
*/ */
priv = g_priv; priv = g_priv;
@ -1032,7 +1034,6 @@ static int usbhost_kbdpoll(int argc, char *argv[])
hport = priv->usbclass.hport; hport = priv->usbclass.hport;
priv->polling = true; priv->polling = true;
priv->crefs++;
usbhost_givesem(&g_syncsem); usbhost_givesem(&g_syncsem);
sleep(1); sleep(1);
@ -1607,7 +1608,7 @@ static inline int usbhost_devinit(FAR struct usbhost_state_s *priv)
uvdbg("Start poll task\n"); uvdbg("Start poll task\n");
/* The inputs to a task started by task_create() are very awkard for this /* The inputs to a task started by kernel_thread() are very awkard for this
* purpose. They are really designed for command line tasks (argc/argv). So * purpose. They are really designed for command line tasks (argc/argv). So
* the following is kludge pass binary data when the keyboard poll task * the following is kludge pass binary data when the keyboard poll task
* is started. * is started.
@ -1619,9 +1620,9 @@ static inline int usbhost_devinit(FAR struct usbhost_state_s *priv)
usbhost_takesem(&g_exclsem); usbhost_takesem(&g_exclsem);
g_priv = priv; g_priv = priv;
priv->pollpid = task_create("kbdpoll", CONFIG_HIDKBD_DEFPRIO, priv->pollpid = kernel_thread("kbdpoll", CONFIG_HIDKBD_DEFPRIO,
CONFIG_HIDKBD_STACKSIZE, CONFIG_HIDKBD_STACKSIZE,
(main_t)usbhost_kbdpoll, (FAR char * const *)NULL); (main_t)usbhost_kbdpoll, (FAR char * const *)NULL);
if (priv->pollpid == ERROR) if (priv->pollpid == ERROR)
{ {
/* Failed to started the poll thread... probably due to memory resources */ /* Failed to started the poll thread... probably due to memory resources */
@ -1855,7 +1856,7 @@ static FAR struct usbhost_class_s *
priv->usbclass.disconnected = usbhost_disconnected; priv->usbclass.disconnected = usbhost_disconnected;
/* The initial reference count is 1... One reference is held by /* The initial reference count is 1... One reference is held by
* the driver. * the driver's usbhost_kbdpoll() task.
*/ */
priv->crefs = 1; priv->crefs = 1;

View File

@ -53,6 +53,7 @@
#include <debug.h> #include <debug.h>
#include <nuttx/kmalloc.h> #include <nuttx/kmalloc.h>
#include <nuttx/kthread.h>
#include <nuttx/fs/fs.h> #include <nuttx/fs/fs.h>
#include <nuttx/wqueue.h> #include <nuttx/wqueue.h>
@ -1058,9 +1059,10 @@ static int usbhost_mouse_poll(int argc, char *argv[])
* the start-up logic, and wait a bit to make sure that all of the class * the start-up logic, and wait a bit to make sure that all of the class
* creation logic has a chance to run to completion. * creation logic has a chance to run to completion.
* *
* NOTE: that the reference count is incremented here. Therefore, we know * NOTE: that the reference count is *not* incremented here. When the driver
* that the driver data structure will remain stable while this thread is * structure was created, it was created with a reference count of one. This
* running. * thread is responsible for that count. The count will be decrement when
* this thread exits.
*/ */
priv = g_priv; priv = g_priv;
@ -1068,7 +1070,6 @@ static int usbhost_mouse_poll(int argc, char *argv[])
hport = priv->usbclass.hport; hport = priv->usbclass.hport;
priv->polling = true; priv->polling = true;
priv->crefs++;
usbhost_givesem(&g_syncsem); usbhost_givesem(&g_syncsem);
sleep(1); sleep(1);
@ -1674,7 +1675,7 @@ static inline int usbhost_devinit(FAR struct usbhost_state_s *priv)
uvdbg("Start poll task\n"); uvdbg("Start poll task\n");
/* The inputs to a task started by task_create() are very awkward for this /* The inputs to a task started by kernel_thread() are very awkward for this
* purpose. They are really designed for command line tasks (argc/argv). So * purpose. They are really designed for command line tasks (argc/argv). So
* the following is kludge pass binary data when the mouse poll task * the following is kludge pass binary data when the mouse poll task
* is started. * is started.
@ -1686,9 +1687,9 @@ static inline int usbhost_devinit(FAR struct usbhost_state_s *priv)
usbhost_takesem(&g_exclsem); usbhost_takesem(&g_exclsem);
g_priv = priv; g_priv = priv;
priv->pollpid = task_create("mouse", CONFIG_HIDMOUSE_DEFPRIO, priv->pollpid = kernel_thread("mouse", CONFIG_HIDMOUSE_DEFPRIO,
CONFIG_HIDMOUSE_STACKSIZE, CONFIG_HIDMOUSE_STACKSIZE,
(main_t)usbhost_mouse_poll, (FAR char * const *)NULL); (main_t)usbhost_mouse_poll, (FAR char * const *)NULL);
if (priv->pollpid == ERROR) if (priv->pollpid == ERROR)
{ {
/* Failed to started the poll thread... probably due to memory resources */ /* Failed to started the poll thread... probably due to memory resources */
@ -1921,7 +1922,7 @@ static FAR struct usbhost_class_s *
priv->usbclass.disconnected = usbhost_disconnected; priv->usbclass.disconnected = usbhost_disconnected;
/* The initial reference count is 1... One reference is held by /* The initial reference count is 1... One reference is held by
* the driver. * the driver's usbhost_mouse_poll() task.
*/ */
priv->crefs = 1; priv->crefs = 1;
@ -1931,9 +1932,6 @@ static FAR struct usbhost_class_s *
sem_init(&priv->exclsem, 0, 1); sem_init(&priv->exclsem, 0, 1);
sem_init(&priv->waitsem, 0, 0); sem_init(&priv->waitsem, 0, 0);
/* Bind the driver to the storage class instance */
/* Return the instance of the USB mouse class driver */ /* Return the instance of the USB mouse class driver */
return &priv->usbclass; return &priv->usbclass;