res_pjsip_refer: Refactor progress locking and serialization
Although refer_progress_notify() always runs in the progress serializer, the pjproject evsub module itself can cause the subscription to be destroyed which then triggers refer_progress_on_evsub_state() to clean it up. In this case, it's possible that refer_progress_notify() could get the subscription pulled out from under it while it's trying to use it. At one point we tried to have refer_progress_on_evsub_state() push the cleanup to the serializer and wait for its return before returning to pjproject but since pjproject calls its state callbacks with the dialog locked, this required us to unlock the dialog while waiting for the serialized cleanup, then lock it again before returning to pjproject. There were also still some cases where other callers of refer_progress_notify() weren't using the serializer and crashes were resulting. Although all callers of refer_progress_notify() now use the progress serializer, we decided to simplify the locking so we didn't have to unlock and relock the dialog in refer_progress_on_evsub_state(). Now, refer_progress_notify() holds the dialog lock for its duration and since pjproject also holds the dialog lock while calling refer_progress_on_evsub_state() (which does the cleanup), there should be no more chances for the subscription to be cleaned up while still being used to send NOTIFYs. To be extra safe, we also now increment the session count on the dialog when we create a progress object and decrement the count when the progress is destroyed. ASTERISK-29313 Change-Id: I97a8bb01771a3c85345649b8124507f7622a8480
Loading
Please register or sign in to comment