mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-11-03 20:38:59 +00:00 
			
		
		
		
	res_pjsip_pubsub: Postpone destruction of old subscriptions on RLS update
Set termination state to old subscriptions to prevent queueing and sending NOTIFY messages on exten/device state changes. Postpone destruction of old subscriptions until all already queued tasks that may be using old subscriptions have completed. ASTERISK-29906 Change-Id: I96582aad3a26515ca73a8460ee6756f56f6ba23b
This commit is contained in:
		
				
					committed by
					
						
						Friendly Automation
					
				
			
			
				
	
			
			
			
						parent
						
							155c796203
						
					
				
				
					commit
					12c4c1bf5f
				
			@@ -296,7 +296,8 @@ static int notify_task(void *obj)
 | 
				
			|||||||
		.body_data = &task_data->exten_state_data,
 | 
							.body_data = &task_data->exten_state_data,
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Terminated subscriptions are no longer associated with a valid tree, and sending
 | 
						/* The subscription was terminated while notify_task was in queue.
 | 
				
			||||||
 | 
						   Terminated subscriptions are no longer associated with a valid tree, and sending
 | 
				
			||||||
	 * NOTIFY messages on a subscription which has already been terminated won't work.
 | 
						 * NOTIFY messages on a subscription which has already been terminated won't work.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (ast_sip_subscription_is_terminated(task_data->exten_state_sub->sip_sub)) {
 | 
						if (ast_sip_subscription_is_terminated(task_data->exten_state_sub->sip_sub)) {
 | 
				
			||||||
@@ -339,6 +340,13 @@ static int state_changed(const char *context, const char *exten,
 | 
				
			|||||||
	struct notify_task_data *task_data;
 | 
						struct notify_task_data *task_data;
 | 
				
			||||||
	struct exten_state_subscription *exten_state_sub = data;
 | 
						struct exten_state_subscription *exten_state_sub = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Terminated subscriptions are no longer associated with a valid tree.
 | 
				
			||||||
 | 
						 * Do not queue notify_task.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (ast_sip_subscription_is_terminated(exten_state_sub->sip_sub)) {
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!(task_data = alloc_notify_task_data(exten, exten_state_sub, info))) {
 | 
						if (!(task_data = alloc_notify_task_data(exten, exten_state_sub, info))) {
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3994,6 +3994,15 @@ static int cmp_subscription_childrens(struct ast_sip_subscription *s1, struct as
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int destroy_subscriptions_task(void *obj)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ast_sip_subscription *sub = (struct ast_sip_subscription *) obj;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						destroy_subscriptions(sub);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*!
 | 
					/*!
 | 
				
			||||||
 * \brief Called whenever an in-dialog SUBSCRIBE is received
 | 
					 * \brief Called whenever an in-dialog SUBSCRIBE is received
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@@ -4067,8 +4076,19 @@ static void pubsub_on_rx_refresh(pjsip_evsub *evsub, pjsip_rx_data *rdata,
 | 
				
			|||||||
							AST_SCHED_DEL_UNREF(sched, sub_tree->notify_sched_id, ao2_ref(sub_tree, -1));
 | 
												AST_SCHED_DEL_UNREF(sched, sub_tree->notify_sched_id, ao2_ref(sub_tree, -1));
 | 
				
			||||||
							sub_tree->send_scheduled_notify = 0;
 | 
												sub_tree->send_scheduled_notify = 0;
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											/* Terminate old subscriptions to stop sending NOTIFY messages on exten/device state changes */
 | 
				
			||||||
 | 
											set_state_terminated(old_root);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											/* Shutdown old subscriptions to remove exten/device state change callbacks
 | 
				
			||||||
 | 
											 that can queue tasks for old subscriptions */
 | 
				
			||||||
						shutdown_subscriptions(old_root);
 | 
											shutdown_subscriptions(old_root);
 | 
				
			||||||
						destroy_subscriptions(old_root);
 | 
					
 | 
				
			||||||
 | 
											/* Postpone destruction until all already queued tasks that may be using old subscriptions have completed */
 | 
				
			||||||
 | 
											if (ast_sip_push_task(sub_tree->serializer, destroy_subscriptions_task, old_root)) {
 | 
				
			||||||
 | 
												ast_log(LOG_ERROR, "Failed to push task to destroy old subscriptions for RLS '%s->%s'.\n",
 | 
				
			||||||
 | 
													ast_sorcery_object_get_id(endpoint), old_root->resource);
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
					} else {
 | 
										} else {
 | 
				
			||||||
						destroy_subscriptions(new_root);
 | 
											destroy_subscriptions(new_root);
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user