diff options
author | Andrew Zaborowski <andrew.zaborowski@intel.com> | 2020-03-18 15:45:26 +0100 |
---|---|---|
committer | Denis Kenzior <denkenz@gmail.com> | 2020-03-17 15:45:07 -0500 |
commit | 60bb42087aedefe679c127d4dd8ffb2226da1dc7 (patch) | |
tree | 719150072a6c9a222a0c4a90ca2310f39efbd961 | |
parent | f1aa208edf65377dfdbba9c34b56c666b92490c4 (diff) | |
download | iwd-60bb42087aedefe679c127d4dd8ffb2226da1dc7.tar.gz |
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).
-rw-r--r-- | src/frame-xchg.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/src/frame-xchg.c b/src/frame-xchg.c index 63610e0eb..992149ee8 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); } |