aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Zaborowski <andrew.zaborowski@intel.com>2020-03-18 15:45:26 +0100
committerDenis Kenzior <denkenz@gmail.com>2020-03-17 15:45:07 -0500
commit60bb42087aedefe679c127d4dd8ffb2226da1dc7 (patch)
tree719150072a6c9a222a0c4a90ca2310f39efbd961
parentf1aa208edf65377dfdbba9c34b56c666b92490c4 (diff)
downloadiwd-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.c9
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);
}