From 0d90dae98e56d2b15fbd065cb9e8c060102b6073 Mon Sep 17 00:00:00 2001 From: patacongo Date: Fri, 13 May 2011 03:33:03 +0000 Subject: Fix possibly deadlock condition git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3601 42af7a65-404d-4744-a932-0658087f49c3 --- misc/drivers/rtl8187x/rtl8187x.c | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) (limited to 'misc/drivers/rtl8187x') diff --git a/misc/drivers/rtl8187x/rtl8187x.c b/misc/drivers/rtl8187x/rtl8187x.c index e84a98283..4c626e84a 100755 --- a/misc/drivers/rtl8187x/rtl8187x.c +++ b/misc/drivers/rtl8187x/rtl8187x.c @@ -986,36 +986,33 @@ static inline int rtl8187x_devinit(FAR struct rtl8187x_state_s *priv) { rtl8187x_takesem(&priv->exclsem); + /* Decrement the reference count */ + + priv->crefs--; + /* Handle a corner case where (1) open() has been called so the - * reference count is > 2, but the device has been disconnected. + * reference count was > 2, but the device has been disconnected. * In this case, the class instance needs to persist until close() * is called. */ - if (priv->crefs <= 2 && priv->disconnected) + if (priv->crefs <= 1 && priv->disconnected) { - /* We don't have to give the semaphore because it will be - * destroyed when usb_destroy is called. + /* The will cause the enumeration logic to disconnect + * the class driver. */ - - ret = -ENODEV; - } - else - { - /* Ready for normal operation as a network device */ - uvdbg("Successfully initialized\n"); - priv->crefs--; - rtl8187x_givesem(&priv->exclsem); + ret = -ENODEV; } - } - /* Disconnect on any errors detected during volume initialization */ + /* Release the semaphore... there is a race condition here. + * Decrementing the reference count and releasing the semaphore + * allows usbhost_destroy() to execute (on the worker thread); + * the class driver instance could get destoryed before we are + * ready to handle it! + */ - if (ret != OK) - { - udbg("ERROR! Aborting: %d\n", ret); - rtl8187x_destroy(priv); + rtl8187x_givesem(&priv->exclsem); } return ret; @@ -1375,6 +1372,10 @@ errout: * On success, zero (OK) is returned. On a failure, a negated errno value is * returned indicating the nature of the failure * + * NOTE that the class instance remains valid upon return with a failure. It is + * the responsibility of the higher level enumeration logic to call + * CLASS_DISCONNECTED to free up the class driver resources. + * * Assumptions: * - This function will *not* be called from an interrupt handler. * - If this function returns an error, the USB host controller driver -- cgit v1.2.3