drivers: gpio: fix mis-use of slist API in callback processing
The iterator over registered callbacks failed to account for the possibility that the callback would remove itself from the list. If this occurred any remaining callbacks would no longer be reachable from the node. Switch to the slist iterator that is safe for self-removal. Note that the slist API remains unsafe for removal of subsequent nodes. Even with the corrected code removal of the next callback registration (cached in tmp) will result in it being called anyway, with the remaining unremoved registrations not being called. If the next callback were removed and re-registered on a different device, the callbacks would be invoked for the wrong device. Resolve this by a documentation change describing the conditions under which a change to callback registration from within a callback are permitted. Add a similar note regarding the effect of adding a callback. The current event invocation behavior for callbacks added within an event is explicitly left unspecified, though in the current slist implementation newly added callbacks will not be invoked until the next event. Closes #10186 Signed-off-by: Peter A. Bigot <pab@pabigot.com>
This commit is contained in:
parent
b48478fef3
commit
d75495709d
5 changed files with 84 additions and 7 deletions
|
@ -260,6 +260,10 @@ static inline void gpio_init_callback(struct gpio_callback *callback,
|
|||
* @param callback A valid Application's callback structure pointer.
|
||||
* @return 0 if successful, negative errno code on failure.
|
||||
*
|
||||
* @note Callbacks may be added to the device from within a callback
|
||||
* handler invocation, but whether they are invoked for the current
|
||||
* GPIO event is not specified.
|
||||
*
|
||||
* Note: enables to add as many callback as needed on the same port.
|
||||
*/
|
||||
static inline int gpio_add_callback(struct device *port,
|
||||
|
@ -281,6 +285,13 @@ static inline int gpio_add_callback(struct device *port,
|
|||
* @param callback A valid application's callback structure pointer.
|
||||
* @return 0 if successful, negative errno code on failure.
|
||||
*
|
||||
* @warning It is explicitly permitted, within a callback handler, to
|
||||
* remove the registration for the callback that is running, i.e. @p
|
||||
* callback. Attempts to remove other registrations on the same
|
||||
* device may result in undefined behavior, including failure to
|
||||
* invoke callbacks that remain registered and unintended invocation
|
||||
* of removed callbacks.
|
||||
*
|
||||
* Note: enables to remove as many callbacks as added through
|
||||
* gpio_add_callback().
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue