Skip to content

Commit

Permalink
tmr: prevent race condition on cancel (#1048)
Browse files Browse the repository at this point in the history
* tmr: prevent timer race condition on cancel

If `tmr_cancel` is called from two threads it's enough to cancel once.

* tmr: rename lock to list lock and improve comments
  • Loading branch information
sreimers authored Jan 12, 2024
1 parent db3ca95 commit ba844d9
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 6 deletions.
4 changes: 3 additions & 1 deletion 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,7 +20,8 @@ struct tmrl;
/** Defines a timer */
struct tmr {
struct le le; /**< Linked list element */
mtx_t *lock; /**< Mutex lock */
RE_ATOMIC bool active; /**< Timer is active */
mtx_t *llock; /**< List Mutex lock */
tmr_h *th; /**< Timeout handler */
void *arg; /**< Handler argument */
uint64_t jfs; /**< Jiffies for timeout */
Expand Down
18 changes: 13 additions & 5 deletions src/tmr/tmr.c
Original file line number Diff line number Diff line change
Expand Up @@ -393,10 +393,16 @@ static void tmr_startcont_dbg(struct tmr *tmr, uint64_t delay, bool syncnow,
if (!tmr || !tmrl)
return;

if (!tmr->lock || !tmr->le.list)
lock = tmrl->lock;
/* Prevent multiple cancel race conditions */
if (!re_atomic_acq(&tmr->active) && !th)
return;

re_atomic_rls_set(&tmr->active, false);

if (!tmr->llock || !tmr->le.list)
lock = tmrl->lock; /* use current list lock */
else
lock = tmr->lock; /* use old lock for unlinking */
lock = tmr->llock; /* use old list lock for unlinking */

mtx_lock(lock);

Expand All @@ -413,10 +419,10 @@ static void tmr_startcont_dbg(struct tmr *tmr, uint64_t delay, bool syncnow,
tmr->arg = arg;
tmr->file = file;
tmr->line = line;
tmr->lock = tmrl->lock;
tmr->llock = tmrl->lock;

if (!th) {
tmr->lock = NULL;
tmr->llock = NULL;
mtx_unlock(lock);
return;
}
Expand Down Expand Up @@ -445,6 +451,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 ba844d9

Please sign in to comment.