* \note Stored after aor_name in space reserved when struct allocated.
*/
char *contact_name;
+ /*! Indicates that the monitor is in the process of removing a contact */
+ int removing;
/*! AOR name the contact is associated */
char aor_name[0];
};
}
ao2_lock(aor);
+
+ /*
+ * We're now locked so check again to make sure some other thread is not
+ * currently removing the contact, or already has.
+ */
+ if (monitor->removing) {
+ ao2_unlock(aor);
+ ao2_ref(aor, -1);
+ ao2_ref(monitor, -1);
+ return 0;
+ }
+
+ monitor->removing = 1;
+
contact = ast_sip_location_retrieve_contact(monitor->contact_name);
if (contact) {
ast_sip_location_delete_contact(contact);
{
struct contact_transport_monitor *monitor = data;
+ /*
+ * It's possible for this shutdown handler to get called multiple times for the
+ * same monitor from different threads. Only one of the calls needs to do the
+ * actual removing of the contact, so if one is currently removing then any
+ * subsequent calls can skip.
+ *
+ * We'll call it non locked here, but check again once locked just in case the
+ * flag was updated (see register_contact_transport_remove_cb).
+ */
+ if (monitor->removing) {
+ return;
+ }
+
/*
* Push off to a default serializer. This is in case sorcery
* does database accesses for contacts. Database accesses may