[asterisk-commits] russell: branch russell/chan_refcount r99677 - /team/russell/chan_refcount/in...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Jan 22 15:17:18 CST 2008


Author: russell
Date: Tue Jan 22 15:17:17 2008
New Revision: 99677

URL: http://svn.digium.com/view/asterisk?view=rev&rev=99677
Log:
Write some docs on channel locking and reference tracking

Modified:
    team/russell/chan_refcount/include/asterisk/channel.h

Change Statistics:
 0 files changed

Modified: team/russell/chan_refcount/include/asterisk/channel.h
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/include/asterisk/channel.h?view=diff&rev=99677&r1=99676&r2=99677
==============================================================================
--- team/russell/chan_refcount/include/asterisk/channel.h (original)
+++ team/russell/chan_refcount/include/asterisk/channel.h Tue Jan 22 15:17:17 2008
@@ -390,10 +390,52 @@
 /*!
  * \page AstChannel ast_channel locking and reference tracking
  *
- * XXX /todo Write this.
- *
- * \par Internal Storage
- * A channel is allocated using the ast_channel_alloc() function.  When created,
+ * \par Creating Channels
+ * A channel is allocated using the ast_channel_alloc() function.  When created, it is
+ * automatically inserted into the main channels hash table that keeps track of all
+ * active channels in the system.  The hash key is based on the channel name.  Because
+ * of this, if you want to change the name, you _must_ use ast_change_name(), not change
+ * the name field directly.  When ast_channel_alloc() returns a channel pointer, you now
+ * hold a reference to that channel.  In most cases this reference is given to ast_pbx_run().
+ *
+ * \par Channel Locking
+ * There is a lock associated with every ast_channel.  It is allocated internally via astobj2.
+ * To lock or unlock a channel, you must use the ast_channel_lock() wrappers.
+ *
+ * Previously, before ast_channel was converted to astobj2, the channel lock was used in some
+ * additional ways that are no longer necessary.  Before, the only way to ensure that a channel
+ * did not disappear out from under you if you were working with a channel outside of the channel
+ * thread that owns it, is to hold the channel lock.  Now, that is no longer necessary.
+ * You simply must hold a reference to the channel to ensure it does not go away.
+ *
+ * The channel must be locked if you need to ensure that data that you reading from the channel
+ * does not change while you access it.  Further, you must hold the channel lock if you are
+ * making a non-atomic change to channel data.
+ *
+ * \par Channel References
+ * There are multiple ways to get a reference to a channel.  The first is that you hold a reference
+ * to a channel after creating it.  The other ways involve using the channel search or the channel
+ * traversal APIs.  These functions are the ast_channel_get_*() functions or ast_channel_iterator_*()
+ * functions.  Once a reference is retrieved by one of these methods, you know that the channel will
+ * not go away.  So, the channel should only get locked as needed for data access or modification.
+ * But, make sure that the reference gets released when you are done with it!
+ *
+ * There are different things you can do when you are done with a reference to a channel.  The first
+ * is to simple release the reference using ast_channel_unref().  The other option is to call
+ * ast_channel_release().  This function is generally used where ast_channel_free() was used in
+ * the past.  The release function releases a reference as well as ensures that the channel is no
+ * longer in the global channels container.  That way, the channel will get destroyed as soon as any
+ * other pending references get released.
+ *
+ * \par Exceptions to the rules
+ * Even though ast_channel is reference counted, there are some places where pointers to an ast_channel
+ * get stored, but the reference count does not reflect it.  The reason is mostly historical.
+ * The only places where this happens should be places where because of how the code works, we
+ * _know_ that the pointer to the channel will get removed before the channel goes away.  The main
+ * example of this is in channel drivers.  Channel drivers generally store a pointer to their owner
+ * ast_channel in their technology specific pvt struct.  In this case, the channel drivers _know_
+ * that this pointer to the channel will be removed in time, because the channel's hangup callback
+ * gets called before the channel goes away.
  */
 
 /*! \brief Main Channel structure associated with a channel. 
@@ -408,7 +450,12 @@
 	void *tech_pvt;					/*!< Private data used by the technology driver */
 
 	AST_DECLARE_STRING_FIELDS(
-		AST_STRING_FIELD(name);			/*!< ASCII unique channel name */
+		/*! ASCII unique channel name
+		 *
+		 * \note DO NOT change this directly!  You must use ast_change_name() so that the
+		 * hash value for this channel gets recalculated.
+		 */
+		AST_STRING_FIELD(name);
 		AST_STRING_FIELD(language);		/*!< Language requested for voice prompts */
 		AST_STRING_FIELD(musicclass);		/*!< Default music class */
 		AST_STRING_FIELD(accountcode);		/*!< Account code for billing */




More information about the asterisk-commits mailing list