Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

k_delayed_work_cancel documentation inconsistent with behavior #22803

Closed
pabigot opened this issue Feb 13, 2020 · 3 comments · Fixed by #22810
Closed

k_delayed_work_cancel documentation inconsistent with behavior #22803

pabigot opened this issue Feb 13, 2020 · 3 comments · Fixed by #22810
Labels
area: Kernel bug The issue is a bug, or the PR is fixing a bug

Comments

@pabigot
Copy link
Collaborator

pabigot commented Feb 13, 2020

* @retval -EINVAL Work item is being processed or has completed its work.
inaccurately documents the behavior of k_delayed_work_cancel(). Specifically, if the work item has already completed the function will return zero, rather than -EINVAL. Assuming the states of a work item:

  • never submitted
  • delayed
  • pending
  • processing
  • completed
  • cancelled

the only time -EINVAL would be observed is in never-submitted, cancelled, or if it transitioned from pending to processing during the cancellation attempt.

The intent may have been to implement to the documentation; in that case the work_q value must be set to null after processing (which may be risky), and possibly other conditions need to be reviewed.

This had an impact in #22756 where it is not possible to determine whether a pending operation has been completed without maintaining an external flag.

@pabigot pabigot added bug The issue is a bug, or the PR is fixing a bug area: Kernel labels Feb 13, 2020
@pabigot
Copy link
Collaborator Author

pabigot commented Feb 13, 2020

@joerchan

@joerchan
Copy link
Contributor

Thanks.

For my use-case I think a function similar to k_work_pending for k_delayed_work would have been very useful. Between the timeout running out (k_delayed_work_remaining_get) and the timeout handler submitting (or not processed) it's no possible to check if the delayed work has been submitted, but not completed.

@Vudentz
Copy link
Contributor

Vudentz commented Feb 13, 2020

So I was with the right impression on this one and the documentation is wrong in one way or the other, the question is shall we change the implementation to reflect what is stated in the documentation? That would mean cancel would return an error if neither the timer or pending flag is set.

Something like this:

diff --git a/kernel/work_q.c b/kernel/work_q.c
index 7023f70f07..d9b259b50b 100644
--- a/kernel/work_q.c
+++ b/kernel/work_q.c
@@ -65,7 +65,11 @@ static int work_cancel(struct k_delayed_work *work)
                        return -EINVAL;
                }
        } else {
-               (void)z_abort_timeout(&work->timeout);
+               int err = z_abort_timeout(&work->timeout);
+
+               if (err) {
+                       return err;
+               }
        }
 
        /* Detach from workqueue */

Vudentz added a commit to Vudentz/zephyr that referenced this issue Feb 17, 2020
This is aligned with the documentation which states that an error shall
be returned if the work has been completed:

  '-EINVAL Work item is being processed or has completed its work.'

Though in order to be able to resubmit from the handler itself it needs
to be able to distinct when the work is already completed so instead of
-EINVAL it return -EALREADY when the work is considered to be completed.

Fixes zephyrproject-rtos#22803

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
jhedberg pushed a commit that referenced this issue Feb 17, 2020
This is aligned with the documentation which states that an error shall
be returned if the work has been completed:

  '-EINVAL Work item is being processed or has completed its work.'

Though in order to be able to resubmit from the handler itself it needs
to be able to distinct when the work is already completed so instead of
-EINVAL it return -EALREADY when the work is considered to be completed.

Fixes #22803

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: Kernel bug The issue is a bug, or the PR is fixing a bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants