aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2009-11-17 10:16:46 +0100
committerHolger Hans Peter Freyther <zecke@selfish.org>2009-11-17 10:16:46 +0100
commitfe9da827fd29b8e153a43d44865a37ff36ae446d (patch)
tree30ac0d0942a5f035d5f55fae0ccf577cb932925b
parent1059deb7829e93bbe5baf156d6cfbd1eea36ece0 (diff)
[paging] In expiration handling remove the request before doing the callback
Not doing this could lead to a double deletion due the paging request being removed during the callback and afterwards as well. Change the code to save the callback data, remove the request, do the callback. A patch was proposed by Andreas Eversberg and this one is based on it.
-rw-r--r--openbsc/src/paging.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/openbsc/src/paging.c b/openbsc/src/paging.c
index 87c7e7d38..69902e8b1 100644
--- a/openbsc/src/paging.c
+++ b/openbsc/src/paging.c
@@ -197,6 +197,8 @@ static void paging_T3113_expired(void *data)
{
struct gsm_paging_request *req = (struct gsm_paging_request *)data;
struct paging_signal_data sig_data;
+ void *cbfn_param;
+ gsm_cbfn *cbfn;
DEBUGP(DPAG, "T3113 expired for request %p (%s)\n",
req, req->subscr->imsi);
@@ -205,11 +207,15 @@ static void paging_T3113_expired(void *data)
sig_data.bts = req->bts;
sig_data.lchan = NULL;
- dispatch_signal(SS_PAGING, S_PAGING_COMPLETED, &sig_data);
- if (req->cbfn)
- req->cbfn(GSM_HOOK_RR_PAGING, GSM_PAGING_EXPIRED, NULL, NULL,
- req->cbfn_param);
+ /* must be destroyed before calling cbfn, to prevent double free */
+ cbfn_param = req->cbfn_param;
+ cbfn = req->cbfn;
paging_remove_request(&req->bts->paging, req);
+
+ dispatch_signal(SS_PAGING, S_PAGING_COMPLETED, &sig_data);
+ if (cbfn)
+ cbfn(GSM_HOOK_RR_PAGING, GSM_PAGING_EXPIRED, NULL, NULL,
+ cbfn_param);
}
static int _paging_request(struct gsm_bts *bts, struct gsm_subscriber *subscr,