Browse code

modules_k/dialog: Delay dialog deletion to absorb late in-dialog requests

- When a dialog's state transitions to DLG_STATE_DELETED, register
a tm callback for TMCB_DESTROY to absorb late in-dialog requests
(no more "unable to find dialog for <REQUEST TYPE>" log
messages).
- On callback, unreference and, in consequence, destroy the
dialog.

Timo Reimann authored on 28/06/2010 08:50:05
Showing 1 changed files
... ...
@@ -764,6 +764,20 @@ static void unreference_dialog(void *dialog)
764 764
 
765 765
 
766 766
 /*!
767
+ * \brief Unreference a dialog from tm callback (another wrapper)
768
+ * \param t transaction, unused
769
+ * \param type type of the entered callback
770
+ * \param param saved dialog structure in the callback
771
+ */
772
+static void unref_dlg_from_cb(struct cell* t, int type, struct tmcb_params *param)
773
+{
774
+    struct dlg_cell *dlg = (struct dlg_cell *)(*param->param);
775
+
776
+    unref_dlg(dlg, 1);
777
+}
778
+
779
+
780
+/*!
767 781
  * \brief Function that is registered as RR callback for dialog tracking
768 782
  * 
769 783
  * Function that is registered as RR callback for dialog tracking. It
... ...
@@ -886,6 +900,17 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
886 886
 	set_current_dialog( req, dlg);
887 887
 	_dlg_ctx.dlg = dlg;
888 888
 
889
+	/* delay deletion of dialog until transaction has died off in order
890
+	 * to absorb in-air messages */
891
+	if (new_state==DLG_STATE_DELETED && old_state!=DLG_STATE_DELETED) {
892
+		if ( d_tmb.register_tmcb(req, NULL, TMCB_DESTROY,
893
+					unref_dlg_from_cb, (void*)dlg, NULL)<0 ) {
894
+			LM_ERR("failed to register deletion delay function\n");
895
+		} else {
896
+			ref_dlg(dlg, 1);
897
+		}
898
+	}
899
+
889 900
 	/* run actions for the transition */
890 901
 	if (event==DLG_EVENT_REQBYE && new_state==DLG_STATE_DELETED &&
891 902
 	old_state!=DLG_STATE_DELETED) {