xiaoxiang781216 commented on a change in pull request #5204:
URL: https://github.com/apache/incubator-nuttx/pull/5204#discussion_r821674599



##########
File path: drivers/input/ajoystick.c
##########
@@ -526,12 +461,7 @@ static ssize_t ajoy_read(FAR struct file *filep, FAR char 
*buffer,
 
   /* Get exclusive access to the driver structure */
 
-  ret = ajoy_takesem(&priv->au_exclsem);
-  if (ret < 0)
-    {
-      ierr("ERROR: ajoy_takesem failed: %d\n", ret);
-      return ret;
-    }
+  flags = enter_critical_section();

Review comment:
       > So what is not handled in this case?
   > 
   > 1. Thread A just enter ajoy_close and switch to thread B. -- I assume that 
this is done either before `ajoy_takesem(&priv->au_exclsem);` or inside the 
`ajoy_takesem(&priv->au_exclsem);` call.
   
   I mean before take au_exclsem.
   
   > 2. Thread B just enter ajoy_read and switch to thread A again. -- This 
will either switch before `ret = ajoy_takesem(&priv->au_exclsem);` or inside 
the `ret = ajoy_takesem(&priv->au_exclsem);` call.
   
   I mean before take au_exclsem too.
   
   > 3. Thread A continue ajoy_close and release opriv -- Yes, so in this case 
we need to access `filep->f_priv` (`opriv`) after `ret = 
ajoy_takesem(&priv->au_exclsem);` is successful and `filep->f_priv` should be 
set to `NULL` after memory is freed.
   
   Yes.
   
   > 4. Thread B resume and touch the freed memory -- this will not happen if 
`ajoy_takesem(&priv->au_exclsem);` is successfully taken and `filep->f_priv` is 
accessed after that.
   > 
   
   Once ajoy_close return at the step 3, filep may be reused by VFS layer and 
then f_priv may point to a different struct, which make the check of 
filep->f_priv useless.
   
   > My assumption is next: The `priv->au_exclsem` protects any modification of 
`node->i_private` data and `filep->f_priv` data. If there is no modification, 
then we do not need to take `priv->au_exclsem`. We can try to leverage critical 
section approach. In other words the `ajoy_read` should look like:
   > 
   > ```
   >   /* Get exclusive access to the driver structure */
   > 
   >   if (ret >= 0)
   >     {
   >       flags = enter_critical_section();
   > 
   >       DEBUGASSERT(filep && filep->f_inode);
   >       opriv = filep->f_priv;
   > 
   >       if (opriv != NULL)
   >         {
   >           opriv->ao_pollpending = false;
   >           ret = sizeof(struct ajoy_sample_s);
   >         }
   >       else
   >         {
   >           ret = -EPIPE;
   >         }
   > 
   >       leave_critical_section(flags);
   >     }
   > 
   >   return (ssize_t)ret;
   > }
   > ```
   
   neither semaphore nor critical section can resolve the above sequence.
   To handle the race condition between destruct and other paired functions, 
the best approach is the reference count and delay release, other methods may 
look like work, but not work really.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscr...@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


Reply via email to