Skip to content

Commit

Permalink
tmr: prevent timer race condition on cancel
Browse files Browse the repository at this point in the history
If `tmr_cancel` is called from two threads it's enough to cancel once.
  • Loading branch information
sreimers committed Jan 12, 2024
1 parent db3ca95 commit f989f45
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 0 deletions.
2 changes: 2 additions & 0 deletions include/re_tmr.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@


#include "re_thread.h"
#include "re_atomic.h"

/**
* Defines the timeout handler
Expand All @@ -19,6 +20,7 @@ struct tmrl;
/** Defines a timer */
struct tmr {
struct le le; /**< Linked list element */
RE_ATOMIC bool active; /**< Timer is active */
mtx_t *lock; /**< Mutex lock */
tmr_h *th; /**< Timeout handler */
void *arg; /**< Handler argument */
Expand Down
7 changes: 7 additions & 0 deletions src/tmr/tmr.c
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,11 @@ static void tmr_startcont_dbg(struct tmr *tmr, uint64_t delay, bool syncnow,
if (!tmr || !tmrl)
return;

if (!re_atomic_acq(&tmr->active) && !th)
return;

re_atomic_rls_set(&tmr->active, false);

if (!tmr->lock || !tmr->le.list)
lock = tmrl->lock;
else
Expand Down Expand Up @@ -445,6 +450,8 @@ static void tmr_startcont_dbg(struct tmr *tmr, uint64_t delay, bool syncnow,
}
}

re_atomic_rls_set(&tmr->active, true);

mtx_unlock(lock);
}

Expand Down

0 comments on commit f989f45

Please sign in to comment.