From 60bb42087aedefe679c127d4dd8ffb2226da1dc7 Mon Sep 17 00:00:00 2001 From: Andrew Zaborowski Date: Wed, 18 Mar 2020 15:45:26 +0100 Subject: [PATCH] frame-xchg: Allow frame_xchg_stop calls inside frame callbacks Make sure a frame callback is free to call frame_xchg_stop without causing a crash. Frame callback here means the one that gets called if our tx frame was ACKed and triggered a respone frame that matched one of the provided prefixes, within the given time. All in all a frame callback is allowed to call either frame_xchg_stop or frame_xchg_startv or neither. Same applies to the final callback (called when no matching responses received). --- src/frame-xchg.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/frame-xchg.c b/src/frame-xchg.c index 63610e0e..992149ee 100644 --- a/src/frame-xchg.c +++ b/src/frame-xchg.c @@ -108,6 +108,7 @@ struct frame_xchg_data { unsigned int retry_interval; unsigned int resp_timeout; bool in_frame_cb : 1; + bool stale : 1; }; struct frame_xchg_watch_data { @@ -723,6 +724,7 @@ static void frame_xchg_wait_cancel(struct frame_xchg_data *fx) static void frame_xchg_reset(struct frame_xchg_data *fx) { fx->in_frame_cb = false; + fx->stale = false; frame_xchg_wait_cancel(fx); @@ -970,7 +972,7 @@ static void frame_xchg_resp_cb(const struct mmpdu_header *mpdu, fx->in_frame_cb = false; - if (done) { + if (done || fx->stale) { fx->cb = NULL; frame_xchg_done(fx, 0); return; @@ -1115,6 +1117,11 @@ void frame_xchg_stop(uint64_t wdev_id) if (!fx) return; + if (fx->in_frame_cb) { + fx->stale = true; + return; + } + frame_xchg_reset(fx); l_free(fx); }