[asterisk-commits] mmichelson: branch mmichelson/pool_shark r380649 - /team/mmichelson/pool_shar...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Jan 31 11:11:10 CST 2013


Author: mmichelson
Date: Thu Jan 31 11:11:07 2013
New Revision: 380649

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=380649
Log:
Add some doxygen to help clarify threading model in SIP.


Modified:
    team/mmichelson/pool_shark/include/asterisk/res_sip.h
    team/mmichelson/pool_shark/include/asterisk/res_sip_session.h

Modified: team/mmichelson/pool_shark/include/asterisk/res_sip.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pool_shark/include/asterisk/res_sip.h?view=diff&rev=380649&r1=380648&r2=380649
==============================================================================
--- team/mmichelson/pool_shark/include/asterisk/res_sip.h (original)
+++ team/mmichelson/pool_shark/include/asterisk/res_sip.h Thu Jan 31 11:11:07 2013
@@ -448,12 +448,69 @@
 int ast_sip_initialize_sorcery_transport(struct ast_sorcery *sorcery);
 
 /*!
+ * \page Threading model for SIP
+ *
+ * There are three major types of threads that SIP will have to deal with:
+ * \li Asterisk threads
+ * \li PJSIP threads
+ * \li SIP threadpool threads (a.k.a. "servants")
+ *
+ * \par Asterisk Threads
+ *
+ * Asterisk threads are those that originate from outside of SIP but within
+ * Asterisk. The most common of these threads are PBX (channel) threads and
+ * the autoservice thread. Most interaction with these threads will be through
+ * channel technology callbacks. Within these threads, it is fine to handle
+ * Asterisk data from outside of SIP, but any handling of SIP data should be
+ * left to servants, \b especially if you wish to call into PJSIP for anything.
+ * Asterisk threads are not registered with PJLIB, so attempting to call into
+ * PJSIP will cause an assertion to be triggered, thus causing the program to
+ * crash.
+ *
+ * \par PJSIP Threads
+ *
+ * PJSIP threads are those that originate from handling of PJSIP events, such
+ * as an incoming SIP request or response, or a transaction timeout. The role
+ * of these threads is to process information as quickly as possible. When your
+ * code gets called into from one of these threads, your goal should be to do
+ * as little as possible before handing the majority of processing off to a
+ * servant. Operations such as remote procedure calls or DNS lookups are never
+ * to be done in these threads since it can cause performance issues.
+ *
+ * \par Servants
+ *
+ * Servants are where the bulk of SIP work should be performed. These threads
+ * exist in order to do the work that Asterisk threads and PJSIP threads hand
+ * off to them. Servant threads register themselves with PJLIB, meaning that
+ * they are capable of calling PJSIP and PJLIB functions if they wish. 
+ *
+ * \par ast_sip_work
+ *
+ * Tasks are handed off to servant threads using the API call \ref ast_sip_push_task.
+ * The first parameter of this call is an \ref ast_sip_work pointer. If this pointer
+ * is NULL, then the work will be handed off to whatever servant can currently handle
+ * the task. If this pointer is non-NULL, then the task will not be executed until
+ * previous tasks pushed with the same \ref ast_sip_work have completed. In other words,
+ * an \ref ast_sip_work is a method of serializing tasks pushed to servants. This can
+ * have several benefits
+ * \li Tasks are executed in the same order they were pushed to servants
+ * \li Reduced contention for shared resources
+ *
+ * \note
+ *
+ * Do not make assumptions about individual threads based on corresponding \ref ast_sip_work.
+ * In other words, just because several tasks use the same \ref ast_sip_work when being pushed
+ * to servants, it does not mean that the same thread is necessarily going to execute those
+ * tasks, even though they are all guaranteed to be executed in sequence.
+ */
+
+/*!
  * \brief Create a new SIP work structure
  *
  * A SIP work is a means of grouping together SIP tasks. For instance, one
  * might create a SIP work so that all tasks for a given SIP dialog will
  * be grouped together. Grouping the work together ensures that the
- * threadpool will distribute the tasks in such a way so that grouped work
+ * servants will execute the tasks in such a way so that grouped work
  * will execute sequentially. Executing grouped tasks sequentially means
  * less contention for shared resources.
  *
@@ -470,11 +527,11 @@
 void ast_sip_destroy_work(struct ast_sip_work *work);
  
 /*!
- * \brief Pushes a task into the SIP threadpool
+ * \brief Pushes a task to SIP servants
  *
  * This uses the SIP work provided to determine how to push the task.
- * If the work param is NULL, then the task will be pushed into the
- * threadpool directly. If the work is non-NULL, then the task will be
+ * If the work param is NULL, then the task will be pushe to the
+ * servants directly. If the work is non-NULL, then the task will be
  * queued behind other tasks associated with the work.
  *
  * \param work The SIP work to which the task belongs. Can be NULL
@@ -486,9 +543,13 @@
 int ast_sip_push_task(struct ast_sip_work *work, int (*sip_task)(void *), void *task_data);
 
 /*!
- * \brief Push a task into the SIP threadpool and wait for it to complete
- *
- * Like ast_sip_push_task excepts that it blocks until the task completes.
+ * \brief Push a task to SIP servants and wait for it to complete
+ *
+ * Like \ref ast_sip_push_task except that it blocks until the task completes.
+ *
+ * \warning \b Never use this function in a SIP servant thread. This can potentially
+ * cause a deadlock. If you are in a SIP servant thread, just call your function
+ * in-line.
  *
  * \param work The SIP work to which the task belongs. May be NULL.
  * \param sip_task The task to execute

Modified: team/mmichelson/pool_shark/include/asterisk/res_sip_session.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pool_shark/include/asterisk/res_sip_session.h?view=diff&rev=380649&r1=380648&r2=380649
==============================================================================
--- team/mmichelson/pool_shark/include/asterisk/res_sip_session.h (original)
+++ team/mmichelson/pool_shark/include/asterisk/res_sip_session.h Thu Jan 31 11:11:07 2013
@@ -81,21 +81,40 @@
 struct ast_sip_session_supplement {
     /*! Method on which to call the callbacks. If NULL, call on all methods */
     const char *method;
-    /*! Notification that the session has begun */
+    /*!
+	 * \brief Notification that the session has begun
+	 * This method will always be called from a SIP servant thread.
+	 */
     void (*session_begin)(struct ast_sip_session *session);
-    /*! Notification that the session has ended */
+    /*! 
+	 * \brief Notification that the session has ended
+	 *
+	 * This method may or may not be called from a SIP servant thread. Do
+	 * not make assumptions about being able to call PJSIP methods from within
+	 * this method.
+	 */
     void (*session_end)(struct ast_sip_session *session);
     /*!
      * \brief Called on incoming SIP request
      * This method can indicate a failure in processing in its return. If there
      * is a failure, it is required that this method sends a response to the request.
+	 * This method is always called from a SIP servant thread.
      */
     int (*incoming_request)(struct ast_sip_session *session, struct pjsip_rx_data *rdata);
-    /*! Called on an incoming SIP response */
+    /*! 
+	 * \brief Called on an incoming SIP response
+	 * This method is always called from a SIP servant thread.
+	 */
     void (*incoming_response)(struct ast_sip_session *session, struct pjsip_rx_data *rdata);
-    /*! Called on an outgoing SIP request */
+    /*!
+	 * \brief Called on an outgoing SIP request
+	 * This method is always called from a SIP servant thread.
+	 */
     void (*outgoing_request)(struct ast_sip_session *session, struct pjsip_tx_data *tdata);
-    /*! Called on an outgoing SIP response */
+    /*! 
+	 * \brief Called on an outgoing SIP response
+	 * This method is always called from a SIP servant thread.
+	 */
     void (*outgoing_response)(struct ast_sip_session *session, struct pjsip_tx_data *tdata);
 	/*! Next item in the list */
 	AST_LIST_ENTRY(ast_sip_session_supplement) next;




More information about the asterisk-commits mailing list