Author: kmoore
Date: Fri Aug 16 12:51:12 2013
New Revision: 396859

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=396859
Log:
Resolve merge conflict

Modified:
    team/kmoore/parking_unload/   (props changed)
    team/kmoore/parking_unload/apps/app_queue.c
    team/kmoore/parking_unload/channels/chan_sip.c
    team/kmoore/parking_unload/include/asterisk/astobj2.h
    team/kmoore/parking_unload/include/asterisk/utils.h
    team/kmoore/parking_unload/main/bridge_channel.c
    team/kmoore/parking_unload/main/cdr.c
    team/kmoore/parking_unload/main/data.c
    team/kmoore/parking_unload/main/db.c
    team/kmoore/parking_unload/main/features.c
    team/kmoore/parking_unload/main/file.c
    team/kmoore/parking_unload/main/format.c
    team/kmoore/parking_unload/main/hashtab.c
    team/kmoore/parking_unload/main/indications.c
    team/kmoore/parking_unload/main/loader.c
    team/kmoore/parking_unload/main/manager.c
    team/kmoore/parking_unload/main/message.c
    team/kmoore/parking_unload/main/pbx.c
    team/kmoore/parking_unload/main/pickup.c
    team/kmoore/parking_unload/main/rtp_engine.c
    team/kmoore/parking_unload/main/sounds_index.c
    team/kmoore/parking_unload/main/stasis.c
    team/kmoore/parking_unload/main/stasis_cache.c
    team/kmoore/parking_unload/main/stasis_cache_pattern.c
    team/kmoore/parking_unload/main/stasis_channels.c
    team/kmoore/parking_unload/main/xmldoc.c
    team/kmoore/parking_unload/res/parking/parking_bridge_features.c
    team/kmoore/parking_unload/res/parking/parking_tests.c
    team/kmoore/parking_unload/res/parking/res_parking.h
    team/kmoore/parking_unload/res/res_parking.c
    team/kmoore/parking_unload/res/res_rtp_asterisk.c
    team/kmoore/parking_unload/tests/test_abstract_jb.c
    team/kmoore/parking_unload/tests/test_cdr.c
    team/kmoore/parking_unload/tests/test_cel.c
    team/kmoore/parking_unload/tests/test_jitterbuf.c
    team/kmoore/parking_unload/tests/test_stasis.c
    team/kmoore/parking_unload/tests/test_voicemail_api.c

Propchange: team/kmoore/parking_unload/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Fri Aug 16 12:51:12 2013
@@ -1,1 +1,1 @@
-/trunk:1-396803
+/trunk:1-396858

Modified: team/kmoore/parking_unload/apps/app_queue.c
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/apps/app_queue.c?view=diff&rev=396859&r1=396858&r2=396859
==============================================================================
--- team/kmoore/parking_unload/apps/app_queue.c (original)
+++ team/kmoore/parking_unload/apps/app_queue.c Fri Aug 16 12:51:12 2013
@@ -2060,7 +2060,8 @@
 }
 
 /*!
- * \internal \brief Determine if a queue member is available
+ * \internal
+ * \brief Determine if a queue member is available
  * \retval 1 if the member is available
  * \retval 0 if the member is not available
  */

Modified: team/kmoore/parking_unload/channels/chan_sip.c
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/channels/chan_sip.c?view=diff&rev=396859&r1=396858&r2=396859
==============================================================================
--- team/kmoore/parking_unload/channels/chan_sip.c (original)
+++ team/kmoore/parking_unload/channels/chan_sip.c Fri Aug 16 12:51:12 2013
@@ -7724,7 +7724,10 @@
        return res;
 }
 
-/*! \internal \brief Create and initialize UDPTL for the specified dialog
+/*!
+ * \internal
+ * \brief Create and initialize UDPTL for the specified dialog
+ *
  * \param p SIP private structure to create UDPTL object for
  * \pre p is locked
  * \pre p->owner is locked
@@ -14443,7 +14446,10 @@
        return 0;
 }
 
-/*! \internal \brief Find the channel that is causing the RINGING update, 
ref'd */
+/*!
+ * \internal
+ * \brief Find the channel that is causing the RINGING update, ref'd
+ */
 static struct ast_channel *find_ringing_channel(struct ao2_container 
*device_state_info, struct sip_pvt *p)
 {
        struct ao2_iterator citer;
@@ -16386,7 +16392,10 @@
        }
 }
 
-/*! \internal \brief Create a new route
+/*!
+ * \internal
+ * \brief Create a new route
+ *
  * \retval NULL on error
  * \retval sip_route on success
  */
@@ -16415,7 +16424,10 @@
        return route;
 }
 
-/*! \internal \brief copy route-set
+/*!
+ * \internal
+ * \brief copy route-set
+ *
  * \retval non-zero on failure
  * \retval 0 on success
  */
@@ -17045,7 +17057,9 @@
        ast_sockaddr_split_hostport(*hostport, hostport, &dont_care, 
PARSE_PORT_IGNORE);
 }
 
-/*! \internal \brief Helper function to update a peer's lastmsgssent value
+/*!
+ * \internal
+ * \brief Helper function to update a peer's lastmsgssent value
  */
 static void update_peer_lastmsgssent(struct sip_peer *peer, int value, int 
locked)
 {
@@ -17059,13 +17073,16 @@
 }
 
 
-/*! \brief Verify registration of user
-       - Registration is done in several steps, first a REGISTER without auth
-         to get a challenge (nonce) then a second one with auth
-       - Registration requests are only matched with peers that are marked as 
"dynamic"
+/*!
+ * \brief Verify registration of user
+ *
+ * \details
+ * - Registration is done in several steps, first a REGISTER without auth
+ *   to get a challenge (nonce) then a second one with auth
+ * - Registration requests are only matched with peers that are marked as 
"dynamic"
  */
 static enum check_auth_result register_verify(struct sip_pvt *p, struct 
ast_sockaddr *addr,
-                                             struct sip_request *req, const 
char *uri)
+       struct sip_request *req, const char *uri)
 {
        enum check_auth_result res = AUTH_NOT_FOUND;
        struct sip_peer *peer;
@@ -27207,7 +27224,10 @@
        return handler_result;
 }
 
-/*! \internal \brief Subscribe to MWI events for the specified peer
+/*!
+ * \internal
+ * \brief Subscribe to MWI events for the specified peer
+ *
  * \note The peer cannot be locked during this method.  sip_send_mwi_peer will
  * attempt to lock the peer after the event subscription lock is held; if the 
peer is locked during
  * this method then we will attempt to lock the event subscription lock but 
after the peer, creating

Modified: team/kmoore/parking_unload/include/asterisk/astobj2.h
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/include/asterisk/astobj2.h?view=diff&rev=396859&r1=396858&r2=396859
==============================================================================
--- team/kmoore/parking_unload/include/asterisk/astobj2.h (original)
+++ team/kmoore/parking_unload/include/asterisk/astobj2.h Fri Aug 16 12:51:12 
2013
@@ -509,6 +509,25 @@
 #define ao2_ref(o,delta)       __ao2_ref((o), (delta))
 
 #endif
+
+/*!
+ * \since 12
+ * \brief Bump refcount on an AO2 object by one, returning the object.
+ *
+ * This is useful for inlining a ref bump, and you don't care about the ref
+ * count. Also \c NULL safe, for even more convenience.
+ *
+ * \param obj AO2 object to bump the refcount on.
+ * \retval The given \a obj pointer.
+ */
+#define ao2_bump(obj)                                          \
+       ({                                                      \
+               typeof(obj) __obj_ ## __LINE__ = (obj);         \
+               if (__obj_ ## __LINE__) {                       \
+                       ao2_ref(__obj_ ## __LINE__, +1);        \
+               }                                               \
+               __obj_ ## __LINE__;                             \
+       })
 
 int __ao2_ref_debug(void *o, int delta, const char *tag, const char *file, int 
line, const char *func);
 int __ao2_ref(void *o, int delta);

Modified: team/kmoore/parking_unload/include/asterisk/utils.h
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/include/asterisk/utils.h?view=diff&rev=396859&r1=396858&r2=396859
==============================================================================
--- team/kmoore/parking_unload/include/asterisk/utils.h (original)
+++ team/kmoore/parking_unload/include/asterisk/utils.h Fri Aug 16 12:51:12 2013
@@ -25,6 +25,7 @@
 
 #include "asterisk/network.h"
 
+#include <execinfo.h>
 #include <time.h>      /* we want to override localtime_r */
 #include <unistd.h>
 #include <string.h>
@@ -483,8 +484,27 @@
 
 #ifndef __AST_DEBUG_MALLOC
 
+/*
+ * This buffer is in static memory. We never intend to read it,
+ * nor do we care about multiple threads writing to it at the
+ * same time. We only want to know if we're recursing too deep
+ * already. 60 entries should be more than enough.  Function
+ * call depth rarely exceeds 20 or so.
+ */
+#define _AST_MEM_BACKTRACE_BUFLEN 60
+extern void *_ast_mem_backtrace_buffer[_AST_MEM_BACKTRACE_BUFLEN];
+
+/*
+ * Ok, this sucks. But if we're already out of mem, we don't
+ * want the logger to create infinite recursion (and a crash).
+ */
 #define MALLOC_FAILURE_MSG \
-       ast_log(LOG_ERROR, "Memory Allocation Failure in function %s at line %d 
of %s\n", func, lineno, file);
+       do { \
+               if (backtrace(_ast_mem_backtrace_buffer, 
_AST_MEM_BACKTRACE_BUFLEN) < _AST_MEM_BACKTRACE_BUFLEN) { \
+                       ast_log(LOG_ERROR, "Memory Allocation Failure in 
function %s at line %d of %s\n", func, lineno, file); \
+               } \
+       } while (0)
+
 /*!
  * \brief A wrapper for malloc()
  *
@@ -501,8 +521,9 @@
 {
        void *p;
 
-       if (!(p = malloc(len)))
+       if (!(p = malloc(len))) {
                MALLOC_FAILURE_MSG;
+       }
 
        return p;
 }
@@ -524,8 +545,9 @@
 {
        void *p;
 
-       if (!(p = calloc(num, len)))
+       if (!(p = calloc(num, len))) {
                MALLOC_FAILURE_MSG;
+       }
 
        return p;
 }
@@ -560,8 +582,9 @@
 {
        void *newp;
 
-       if (!(newp = realloc(p, len)))
+       if (!(newp = realloc(p, len))) {
                MALLOC_FAILURE_MSG;
+       }
 
        return newp;
 }
@@ -588,8 +611,9 @@
        char *newstr = NULL;
 
        if (str) {
-               if (!(newstr = strdup(str)))
+               if (!(newstr = strdup(str))) {
                        MALLOC_FAILURE_MSG;
+               }
        }
 
        return newstr;
@@ -617,8 +641,9 @@
        char *newstr = NULL;
 
        if (str) {
-               if (!(newstr = strndup(str, len)))
+               if (!(newstr = strndup(str, len))) {
                        MALLOC_FAILURE_MSG;
+               }
        }
 
        return newstr;
@@ -656,8 +681,9 @@
 {
        int res;
 
-       if ((res = vasprintf(ret, fmt, ap)) == -1)
+       if ((res = vasprintf(ret, fmt, ap)) == -1) {
                MALLOC_FAILURE_MSG;
+       }
 
        return res;
 }

Modified: team/kmoore/parking_unload/main/bridge_channel.c
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/main/bridge_channel.c?view=diff&rev=396859&r1=396858&r2=396859
==============================================================================
--- team/kmoore/parking_unload/main/bridge_channel.c (original)
+++ team/kmoore/parking_unload/main/bridge_channel.c Fri Aug 16 12:51:12 2013
@@ -108,7 +108,10 @@
        ast_bridge_channel_unlock(bridge_channel);
 }
 
-/*! \internal \brief Poke the bridge_channel thread */
+/*!
+ * \internal
+ * \brief Poke the bridge_channel thread
+ */
 static void bridge_channel_poke(struct ast_bridge_channel *bridge_channel)
 {
        if (!pthread_equal(pthread_self(), bridge_channel->thread)) {
@@ -487,7 +490,10 @@
        return ast_bridge_channel_write_control_data(bridge_channel, 
AST_CONTROL_UNHOLD, NULL, 0);
 }
 
-/*! \internal \brief Helper function to kick off a PBX app on a bridge_channel 
*/
+/*!
+ * \internal
+ * \brief Helper function to kick off a PBX app on a bridge_channel
+ */
 static int run_app_helper(struct ast_channel *chan, const char *app_name, 
const char *app_args)
 {
        int res = 0;
@@ -979,7 +985,10 @@
        }
 }
 
-/*! \internal \brief Write a DTMF stream out to a channel */
+/*!
+ * \internal
+ * \brief Write a DTMF stream out to a channel
+ */
 static int bridge_channel_write_dtmf_stream(struct ast_bridge_channel 
*bridge_channel, const char *dtmf)
 {
        return bridge_channel_write_action_data(bridge_channel,
@@ -1095,7 +1104,10 @@
        }
 }
 
-/*! \internal \brief Indicate that a bridge_channel is talking */
+/*!
+ * \internal
+ * \brief Indicate that a bridge_channel is talking
+ */
 static void bridge_channel_talking(struct ast_bridge_channel *bridge_channel, 
int talking)
 {
        struct ast_bridge_features *features = bridge_channel->features;
@@ -1136,7 +1148,10 @@
        char context[AST_MAX_CONTEXT];
 };
 
-/*! \internal \brief Execute after bridge actions on a channel when it leaves 
a bridge */
+/*!
+ * \internal
+ * \brief Execute after bridge actions on a channel when it leaves a bridge
+ */
 static void after_bridge_move_channel(struct ast_channel *chan_bridged, void 
*data)
 {
        RAII_VAR(struct ast_channel *, chan_target, data, ao2_cleanup);
@@ -1173,7 +1188,10 @@
        ast_party_connected_line_free(&connected_target);
 }
 
-/*! \internal \brief Execute logic to cleanup when after bridge fails */
+/*!
+ * \internal
+ * \brief Execute logic to cleanup when after bridge fails
+ */
 static void after_bridge_move_channel_fail(enum ast_bridge_after_cb_reason 
reason, void *data)
 {
        RAII_VAR(struct ast_channel *, chan_target, data, ao2_cleanup);
@@ -1183,7 +1201,10 @@
        ast_softhangup(chan_target, AST_SOFTHANGUP_DEV);
 }
 
-/*! \internal \brief Perform a blind transfer on a channel in a bridge */
+/*!
+ * \internal
+ * \brief Perform a blind transfer on a channel in a bridge
+ */
 static void bridge_channel_blind_transfer(struct ast_bridge_channel 
*bridge_channel,
                struct blind_transfer_data *blind_data)
 {
@@ -1191,7 +1212,10 @@
        bridge_channel_handle_hangup(bridge_channel);
 }
 
-/*! \internal \brief Perform an attended transfer on a channel in a bridge */
+/*!
+ * \internal
+ * \brief Perform an attended transfer on a channel in a bridge
+ */
 static void bridge_channel_attended_transfer(struct ast_bridge_channel 
*bridge_channel,
                const char *target_chan_name)
 {
@@ -1473,27 +1497,20 @@
        struct ast_channel *chan;
        struct ast_option_header *aoh;
        int is_caller;
-       int intercept_failed;
 
        chan = bridge_channel->chan;
        switch (fr->subclass.integer) {
        case AST_CONTROL_REDIRECTING:
                is_caller = !ast_test_flag(ast_channel_flags(chan), 
AST_FLAG_OUTGOING);
-               bridge_channel_suspend(bridge_channel);
-               intercept_failed = ast_channel_redirecting_sub(NULL, chan, fr, 
1)
-                       && ast_channel_redirecting_macro(NULL, chan, fr, 
is_caller, 1);
-               bridge_channel_unsuspend(bridge_channel);
-               if (intercept_failed) {
+               if (ast_channel_redirecting_sub(NULL, chan, fr, 1) &&
+                       ast_channel_redirecting_macro(NULL, chan, fr, 
is_caller, 1)) {
                        ast_indicate_data(chan, fr->subclass.integer, 
fr->data.ptr, fr->datalen);
                }
                break;
        case AST_CONTROL_CONNECTED_LINE:
                is_caller = !ast_test_flag(ast_channel_flags(chan), 
AST_FLAG_OUTGOING);
-               bridge_channel_suspend(bridge_channel);
-               intercept_failed = ast_channel_connected_line_sub(NULL, chan, 
fr, 1)
-                       && ast_channel_connected_line_macro(NULL, chan, fr, 
is_caller, 1);
-               bridge_channel_unsuspend(bridge_channel);
-               if (intercept_failed) {
+               if (ast_channel_connected_line_sub(NULL, chan, fr, 1) &&
+                       ast_channel_connected_line_macro(NULL, chan, fr, 
is_caller, 1)) {
                        ast_indicate_data(chan, fr->subclass.integer, 
fr->data.ptr, fr->datalen);
                }
                break;

Modified: team/kmoore/parking_unload/main/cdr.c
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/main/cdr.c?view=diff&rev=396859&r1=396858&r2=396859
==============================================================================
--- team/kmoore/parking_unload/main/cdr.c (original)
+++ team/kmoore/parking_unload/main/cdr.c Fri Aug 16 12:51:12 2013
@@ -1545,7 +1545,10 @@
        return 1;
 }
 
-/*! \internal \brief Convert a dial status to a CDR disposition */
+/*!
+ * \internal
+ * \brief Convert a dial status to a CDR disposition
+ */
 static enum ast_cdr_disposition dial_status_to_disposition(const char 
*dial_status)
 {
        RAII_VAR(struct module_config *, mod_cfg,
@@ -1898,13 +1901,19 @@
        return 0;
 }
 
-/*! \internal \brief Filter channel snapshots by technology */
+/*!
+ * \internal
+ * \brief Filter channel snapshots by technology
+ */
 static int filter_channel_snapshot(struct ast_channel_snapshot *snapshot)
 {
        return snapshot->tech_properties & AST_CHAN_TP_INTERNAL;
 }
 
-/*! \internal \brief Filter a channel cache update */
+/*!
+ * \internal
+ * \brief Filter a channel cache update
+ */
 static int filter_channel_cache_message(struct ast_channel_snapshot 
*old_snapshot,
                struct ast_channel_snapshot *new_snapshot)
 {
@@ -2209,7 +2218,9 @@
 }
 
 /*!
- * \internal \brief Build and add bridge candidates based on a CDR
+ * \internal
+ * \brief Build and add bridge candidates based on a CDR
+ *
  * \param bridge_id The ID of the bridge we need candidates for
  * \param candidates The container of \ref bridge_candidate objects
  * \param cdr The \ref cdr_object that is our candidate
@@ -2303,7 +2314,9 @@
 }
 
 /*!
- * \internal \brief Create a new CDR, append it to an existing CDR, and update 
its snapshots
+ * \internal
+ * \brief Create a new CDR, append it to an existing CDR, and update its 
snapshots
+ *
  * \note The new CDR will be automatically transitioned to the bridge state
  */
 static void bridge_candidate_add_to_cdr(struct cdr_object *cdr,

Modified: team/kmoore/parking_unload/main/data.c
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/main/data.c?view=diff&rev=396859&r1=396858&r2=396859
==============================================================================
--- team/kmoore/parking_unload/main/data.c (original)
+++ team/kmoore/parking_unload/main/data.c Fri Aug 16 12:51:12 2013
@@ -3302,7 +3302,10 @@
 
 #endif
 
-/*! \internal \brief Clean up resources on Asterisk shutdown */
+/*!
+ * \internal
+ * \brief Clean up resources on Asterisk shutdown
+ */
 static void data_shutdown(void)
 {
        ast_manager_unregister("DataGet");

Modified: team/kmoore/parking_unload/main/db.c
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/main/db.c?view=diff&rev=396859&r1=396858&r2=396859
==============================================================================
--- team/kmoore/parking_unload/main/db.c (original)
+++ team/kmoore/parking_unload/main/db.c Fri Aug 16 12:51:12 2013
@@ -982,7 +982,10 @@
        return NULL;
 }
 
-/*! \internal \brief Clean up resources on Asterisk shutdown */
+/*!
+ * \internal
+ * \brief Clean up resources on Asterisk shutdown
+ */
 static void astdb_atexit(void)
 {
        ast_cli_unregister_multiple(cli_database, ARRAY_LEN(cli_database));

Modified: team/kmoore/parking_unload/main/features.c
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/main/features.c?view=diff&rev=396859&r1=396858&r2=396859
==============================================================================
--- team/kmoore/parking_unload/main/features.c (original)
+++ team/kmoore/parking_unload/main/features.c Fri Aug 16 12:51:12 2013
@@ -232,8 +232,6 @@
        </manager>
  ***/
 
-/* TODO Scrape all of the parking stuff out of features.c */
-
 typedef enum {
        FEATURE_INTERPRET_DETECT, /* Used by ast_feature_detect */
        FEATURE_INTERPRET_DO,     /* Used by feature_interpret */
@@ -1441,7 +1439,10 @@
        return 0;
 }
 
-/*! \internal \brief Clean up resources on Asterisk shutdown */
+/*!
+ * \internal
+ * \brief Clean up resources on Asterisk shutdown
+ */
 static void features_shutdown(void)
 {
        ast_features_config_shutdown();

Modified: team/kmoore/parking_unload/main/file.c
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/main/file.c?view=diff&rev=396859&r1=396858&r2=396859
==============================================================================
--- team/kmoore/parking_unload/main/file.c (original)
+++ team/kmoore/parking_unload/main/file.c Fri Aug 16 12:51:12 2013
@@ -343,7 +343,10 @@
        return 0;
 }
 
-/*! \internal \brief Close the file stream by canceling any pending read / 
write callbacks */
+/*!
+ * \internal
+ * \brief Close the file stream by canceling any pending read / write callbacks
+ */
 static void filestream_close(struct ast_filestream *f)
 {
        enum ast_format_type format_type = 
AST_FORMAT_GET_TYPE(f->fmt->format.id);

Modified: team/kmoore/parking_unload/main/format.c
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/main/format.c?view=diff&rev=396859&r1=396858&r2=396859
==============================================================================
--- team/kmoore/parking_unload/main/format.c (original)
+++ team/kmoore/parking_unload/main/format.c Fri Aug 16 12:51:12 2013
@@ -1071,7 +1071,10 @@
        return 0;
 }
 
-/*! \internal \brief Clean up resources on Asterisk shutdown */
+/*!
+ * \internal
+ * \brief Clean up resources on Asterisk shutdown
+ */
 static void format_list_shutdown(void)
 {
        ast_rwlock_destroy(&format_list_array_lock);
@@ -1105,7 +1108,10 @@
        return -1;
 }
 
-/*! \internal \brief Clean up resources on Asterisk shutdown */
+/*!
+ * \internal
+ * \brief Clean up resources on Asterisk shutdown
+ */
 static void format_attr_shutdown(void)
 {
        ast_cli_unregister_multiple(my_clis, ARRAY_LEN(my_clis));

Modified: team/kmoore/parking_unload/main/hashtab.c
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/main/hashtab.c?view=diff&rev=396859&r1=396858&r2=396859
==============================================================================
--- team/kmoore/parking_unload/main/hashtab.c (original)
+++ team/kmoore/parking_unload/main/hashtab.c Fri Aug 16 12:51:12 2013
@@ -42,6 +42,10 @@
 #include "asterisk/linkedlists.h"
 #include "asterisk/hashtab.h"
 
+
+#ifndef __AST_DEBUG_MALLOC
+void *_ast_mem_backtrace_buffer[_AST_MEM_BACKTRACE_BUFLEN];
+#endif
 
 #if (defined(MALLOC_DEBUG) && !defined(STANDALONE))
 static void _ast_hashtab_resize(struct ast_hashtab *tab, const char *file, int 
lineno, const char *func);

Modified: team/kmoore/parking_unload/main/indications.c
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/main/indications.c?view=diff&rev=396859&r1=396858&r2=396859
==============================================================================
--- team/kmoore/parking_unload/main/indications.c (original)
+++ team/kmoore/parking_unload/main/indications.c Fri Aug 16 12:51:12 2013
@@ -1149,7 +1149,10 @@
        return 0;
 }
 
-/*! \internal \brief Clean up resources on Asterisk shutdown */
+/*!
+ * \internal
+ * \brief Clean up resources on Asterisk shutdown
+ */
 static void indications_shutdown(void)
 {
        ast_cli_unregister_multiple(cli_indications, 
ARRAY_LEN(cli_indications));

Modified: team/kmoore/parking_unload/main/loader.c
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/main/loader.c?view=diff&rev=396859&r1=396858&r2=396859
==============================================================================
--- team/kmoore/parking_unload/main/loader.c (original)
+++ team/kmoore/parking_unload/main/loader.c Fri Aug 16 12:51:12 2013
@@ -56,6 +56,7 @@
 #include "asterisk/heap.h"
 #include "asterisk/app.h"
 #include "asterisk/test.h"
+#include "asterisk/sounds_index.h"
 
 #include <dlfcn.h>
 
@@ -319,6 +320,7 @@
        { "indications", ast_indications_reload },
        { "cel",        ast_cel_engine_reload },
        { "plc",        ast_plc_reload },
+       { "sounds",     ast_sounds_reindex },
        { NULL,         NULL }
 };
 

Modified: team/kmoore/parking_unload/main/manager.c
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/main/manager.c?view=diff&rev=396859&r1=396858&r2=396859
==============================================================================
--- team/kmoore/parking_unload/main/manager.c (original)
+++ team/kmoore/parking_unload/main/manager.c Fri Aug 16 12:51:12 2013
@@ -7678,7 +7678,10 @@
 
 #endif
 
-/*! \internal \brief Free a user record.  Should already be removed from the 
list */
+/*!
+ * \internal
+ * \brief Free a user record.  Should already be removed from the list
+ */
 static void manager_free_user(struct ast_manager_user *user)
 {
        if (user->a1_hash) {
@@ -7696,7 +7699,10 @@
        ast_free(user);
 }
 
-/*! \internal \brief Clean up resources on Asterisk shutdown */
+/*!
+ * \internal
+ * \brief Clean up resources on Asterisk shutdown
+ */
 static void manager_shutdown(void)
 {
        struct ast_manager_user *user;

Modified: team/kmoore/parking_unload/main/message.c
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/main/message.c?view=diff&rev=396859&r1=396858&r2=396859
==============================================================================
--- team/kmoore/parking_unload/main/message.c (original)
+++ team/kmoore/parking_unload/main/message.c Fri Aug 16 12:51:12 2013
@@ -1301,10 +1301,14 @@
        }
 }
 
-/*! \internal \brief Clean up other resources on Asterisk shutdown
+/*!
+ * \internal
+ * \brief Clean up other resources on Asterisk shutdown
+ *
  * \note This does not include the msg_q_tp object, which must be disposed
  * of prior to Asterisk checking for channel destruction in its shutdown
- * sequence.  The atexit handlers are executed after this occurs. */
+ * sequence.  The atexit handlers are executed after this occurs.
+ */
 static void message_shutdown(void)
 {
        ast_custom_function_unregister(&msg_function);

Modified: team/kmoore/parking_unload/main/pbx.c
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/main/pbx.c?view=diff&rev=396859&r1=396858&r2=396859
==============================================================================
--- team/kmoore/parking_unload/main/pbx.c (original)
+++ team/kmoore/parking_unload/main/pbx.c Fri Aug 16 12:51:12 2013
@@ -4841,7 +4841,10 @@
        return "Unknown";
 }
 
-/*! \internal \brief Check extension state for an extension by using hint */
+/*!
+ * \internal
+ * \brief Check extension state for an extension by using hint
+ */
 static int internal_extension_state_extended(struct ast_channel *c, const char 
*context, const char *exten,
        struct ao2_container *device_state_info)
 {
@@ -5226,7 +5229,10 @@
        }
 }
 
-/*! \internal \brief Add watcher for extension states with destructor */
+/*!
+ * \internal
+ * \brief Add watcher for extension states with destructor
+ */
 static int extension_state_add_destroy(const char *context, const char *exten,
        ast_state_cb_type change_cb, ast_state_cb_destroy_type destroy_cb, void 
*data, int extended)
 {
@@ -7281,6 +7287,81 @@
        return CLI_SUCCESS;
 }
 
+#if 0
+/* This code can be used to test if the system survives running out of memory.
+ * It might be an idea to put this in only if ENABLE_AUTODESTRUCT_TESTS is 
enabled.
+ *
+ * If you want to test this, these Linux sysctl flags might be appropriate:
+ *   vm.overcommit_memory = 2
+ *   vm.swappiness = 0
+ *
+ * <@Corydon76-home> I envision 'core eat disk space' and 'core eat file 
descriptors' now
+ * <@mjordan> egads
+ * <@mjordan> it's literally the 'big red' auto-destruct button
+ * <@mjordan> if you were wondering who even builds such a thing.... well, now 
you know
+ * ...
+ * <@Corydon76-home> What about if they lived only if you defined 
TEST_FRAMEWORK?  Shouldn't have those on production machines
+ * <@mjordan> I think accompanied with an update to one of our README files 
that "no, really, TEST_FRAMEWORK isn't for you", I'd be fine
+ */
+static char *handle_eat_memory(struct ast_cli_entry *e, int cmd, struct 
ast_cli_args *a)
+{
+       void **blocks;
+       int blocks_pos = 0;
+       const int blocks_max = 50000;
+       long long int allocated = 0;
+       int sizes[] = {
+               100 * 1024 * 1024,
+               100 * 1024,
+               2 * 1024,
+               400,
+               0
+       };
+       int i;
+
+       switch (cmd) {
+       case CLI_INIT:
+               /* To do: add method to free memory again? 5 minutes? */
+               e->command = "core eat memory";
+               e->usage =
+                       "Usage: core eat memory\n"
+                       "       Eats all available memory so you can test if 
the system survives\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       blocks = ast_malloc(sizeof(void*) * blocks_max);
+       if (!blocks) {
+               ast_log(LOG_ERROR, "Already out of mem?\n");
+               return CLI_SUCCESS;
+       }
+
+       for (i = 0; sizes[i]; ++i) {
+               int alloc_size = sizes[i];
+               ast_log(LOG_WARNING, "Allocating %d sized blocks (got %d blocks 
already)\n", alloc_size, blocks_pos);
+               while (1) {
+                       void *block;
+                       if (blocks_pos >= blocks_max) {
+                               ast_log(LOG_ERROR, "Memory buffer too small? 
Run me again :)\n");
+                               break;
+                       }
+
+                       block = ast_malloc(alloc_size);
+                       if (!block) {
+                               break;
+                       }
+
+                       blocks[blocks_pos++] = block;
+                       allocated += alloc_size;
+               }
+       }
+
+       /* No freeing of the mem! */
+       ast_log(LOG_WARNING, "Allocated %lld bytes total!\n", allocated);
+       return CLI_SUCCESS;
+}
+#endif
+
 static char *handle_show_applications(struct ast_cli_entry *e, int cmd, struct 
ast_cli_args *a)
 {
        struct ast_app *aa;
@@ -8162,6 +8243,9 @@
  * CLI entries for upper commands ...
  */
 static struct ast_cli_entry pbx_cli[] = {
+#if 0
+       AST_CLI_DEFINE(handle_eat_memory, "Eats all available memory"),
+#endif
        AST_CLI_DEFINE(handle_show_applications, "Shows registered dialplan 
applications"),
        AST_CLI_DEFINE(handle_show_functions, "Shows registered dialplan 
functions"),
        AST_CLI_DEFINE(handle_show_switches, "Show alternative switches"),
@@ -11353,8 +11437,12 @@
        AST_DATA_ENTRY("asterisk/core/hints", &hints_data_provider),
 };
 
-/*! \internal \brief Clean up resources on Asterisk shutdown.
- * \note Cleans up resources allocated in load_pbx */
+/*!
+ * \internal
+ * \brief Clean up resources on Asterisk shutdown.
+ *
+ * \note Cleans up resources allocated in load_pbx
+ */
 static void unload_pbx(void)
 {
        int x;

Modified: team/kmoore/parking_unload/main/pickup.c
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/main/pickup.c?view=diff&rev=396859&r1=396858&r2=396859
==============================================================================
--- team/kmoore/parking_unload/main/pickup.c (original)
+++ team/kmoore/parking_unload/main/pickup.c Fri Aug 16 12:51:12 2013
@@ -383,7 +383,10 @@
        return res;
 }
 
-/*! \internal \brief Clean up resources on Asterisk shutdown */
+/*!
+ * \internal
+ * \brief Clean up resources on Asterisk shutdown
+ */
 static void pickup_shutdown(void)
 {
        STASIS_MESSAGE_TYPE_CLEANUP(ast_call_pickup_type);

Modified: team/kmoore/parking_unload/main/rtp_engine.c
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/main/rtp_engine.c?view=diff&rev=396859&r1=396858&r2=396859
==============================================================================
--- team/kmoore/parking_unload/main/rtp_engine.c (original)
+++ team/kmoore/parking_unload/main/rtp_engine.c Fri Aug 16 12:51:12 2013
@@ -1671,7 +1671,10 @@
        return 0;
 }
 
-/*! \internal \brief \ref stasis message payload for RTCP messages */
+/*!
+ * \internal
+ * \brief \ref stasis message payload for RTCP messages
+ */
 struct rtcp_message_payload {
        struct ast_channel_snapshot *snapshot;  /*< The channel snapshot, if 
available */
        struct ast_rtp_rtcp_report *report;     /*< The RTCP report */

Modified: team/kmoore/parking_unload/main/sounds_index.c
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/main/sounds_index.c?view=diff&rev=396859&r1=396858&r2=396859
==============================================================================
--- team/kmoore/parking_unload/main/sounds_index.c (original)
+++ team/kmoore/parking_unload/main/sounds_index.c Fri Aug 16 12:51:12 2013
@@ -162,20 +162,22 @@
        int formats_shown = 0;
        RAII_VAR(struct ast_media_index *, local_index, ast_sounds_get_index(), 
ao2_cleanup);
        RAII_VAR(struct ast_format_cap *, cap, NULL, ast_format_cap_destroy);
-       const char *description = ast_media_get_description(local_index, 
a->argv[2], language);
+       const char *description = ast_media_get_description(local_index, 
a->argv[3], language);
 
        ast_cli(a->fd, "  Language %s:\n", language);
        if (!ast_strlen_zero(description)) {
                ast_cli(a->fd, "    Description: %s\n", description);
        }
 
-       cap = ast_media_get_format_cap(local_index, a->argv[2], language);
-        ast_format_cap_iter_start(cap);
-        while (!ast_format_cap_iter_next(cap, &format)) {
-               ast_cli(a->fd, "    Format: %s\n", ast_getformatname(&format));
-               formats_shown = 1;
-        }
-        ast_format_cap_iter_end(cap);
+       cap = ast_media_get_format_cap(local_index, a->argv[3], language);
+       if (cap) {
+               ast_format_cap_iter_start(cap);
+               while (!ast_format_cap_iter_next(cap, &format)) {
+                       ast_cli(a->fd, "    Format: %s\n", 
ast_getformatname(&format));
+                       formats_shown = 1;
+               }
+               ast_format_cap_iter_end(cap);
+       }
 
        if (!formats_shown) {
                ast_cli(a->fd, "    No Formats Available\n");
@@ -184,42 +186,43 @@
        return 0;
 }
 
-/*! \brief Allow for reloading of sounds via the command line */
-static char *handle_cli_sounds_reload(struct ast_cli_entry *e, int cmd, struct 
ast_cli_args *a)
+/*! \brief Show a list of sounds available on the system */
+static char *handle_cli_sounds_show(struct ast_cli_entry *e, int cmd, struct 
ast_cli_args *a)
 {
        switch (cmd) {
        case CLI_INIT:
-               e->command = "sounds reload";
+               e->command = "core show sounds";
                e->usage =
-                       "Usage: sounds reload\n"
-                       "       Reloads the index of sound files and their 
descriptions.\n";
+                       "Usage: core show sounds\n"
+                       "       Shows a listing of sound files available on the 
system.\n";
                return NULL;
        case CLI_GENERATE:
                return NULL;
        }
 
-       if (a->argc != 2) {
-               return CLI_SHOWUSAGE;
-       }
-
-       if (ast_sounds_reindex()) {
-               ast_cli(a->fd, "Sound re-indexing failed.\n");
-               return CLI_FAILURE;
-       }
-
-       ast_cli(a->fd, "Sound files re-indexed.\n");
-       return CLI_SUCCESS;
-}
-
-/*! \brief Allow for reloading of sounds via the command line */
-static char *handle_cli_sounds_show(struct ast_cli_entry *e, int cmd, struct 
ast_cli_args *a)
+       if (a->argc == 3) {
+               RAII_VAR(struct ao2_container *, sound_files, 
ast_media_get_media(sounds_index), ao2_cleanup);
+               if (!sound_files) {
+                       return CLI_FAILURE;
+               }
+
+               ast_cli(a->fd, "Available audio files:\n");
+               ao2_callback(sound_files, OBJ_MULTIPLE | OBJ_NODATA, 
show_sounds_cb, a);
+               return CLI_SUCCESS;
+       }
+
+       return CLI_SHOWUSAGE;
+}
+
+/*! \brief Show details about a sound available in the system */
+static char *handle_cli_sound_show(struct ast_cli_entry *e, int cmd, struct 
ast_cli_args *a)
 {
        switch (cmd) {
        case CLI_INIT:
-               e->command = "sounds show";
+               e->command = "core show sound";
                e->usage =
-                       "Usage: sounds show [soundid]\n"
-                       "       Shows a listing of sound files or information 
about the specified sound.\n";
+                       "Usage: core show sound [soundid]\n"
+                       "       Shows information about the specified sound.\n";
                return NULL;
        case CLI_GENERATE:
        {
@@ -247,25 +250,14 @@
        }
        }
 
-       if (a->argc == 2) {
-               RAII_VAR(struct ao2_container *, sound_files, 
ast_media_get_media(sounds_index), ao2_cleanup);
-               if (!sound_files) {
+       if (a->argc == 4) {
+               RAII_VAR(struct ao2_container *, variants, 
ast_media_get_variants(sounds_index, a->argv[3]), ao2_cleanup);
+               if (!variants || !ao2_container_count(variants)) {
+                       ast_cli(a->fd, "ERROR: File %s not found in index\n", 
a->argv[3]);
                        return CLI_FAILURE;
                }
 
-               ast_cli(a->fd, "Available audio files:\n");
-               ao2_callback(sound_files, OBJ_MULTIPLE | OBJ_NODATA, 
show_sounds_cb, a);
-               return CLI_SUCCESS;
-       }
-
-       if (a->argc == 3) {
-               RAII_VAR(struct ao2_container *, variants, 
ast_media_get_variants(sounds_index, a->argv[2]), ao2_cleanup);
-               if (!variants || !ao2_container_count(variants)) {
-                       ast_cli(a->fd, "ERROR: File %s not found in index\n", 
a->argv[2]);
-                       return CLI_FAILURE;
-               }
-
-               ast_cli(a->fd, "Indexed Information for %s:\n", a->argv[2]);
+               ast_cli(a->fd, "Indexed Information for %s:\n", a->argv[3]);
                ao2_callback(variants, OBJ_MULTIPLE | OBJ_NODATA, 
show_sound_info_cb, a);
                return CLI_SUCCESS;
        }
@@ -276,7 +268,7 @@
 /*! \brief Struct for registering CLI commands */
 static struct ast_cli_entry cli_sounds[] = {
        AST_CLI_DEFINE(handle_cli_sounds_show, "Shows available sounds"),
-       AST_CLI_DEFINE(handle_cli_sounds_reload, "Reload sounds index"),
+       AST_CLI_DEFINE(handle_cli_sound_show, "Shows details about a specific 
sound"),
 };
 
 static void sounds_cleanup(void)

Modified: team/kmoore/parking_unload/main/stasis.c
URL: 
http://svnview.digium.com/svn/asterisk/team/kmoore/parking_unload/main/stasis.c?view=diff&rev=396859&r1=396858&r2=396859
==============================================================================
--- team/kmoore/parking_unload/main/stasis.c (original)
+++ team/kmoore/parking_unload/main/stasis.c Fri Aug 16 12:51:12 2013
@@ -39,6 +39,95 @@
 #include "asterisk/utils.h"
 #include "asterisk/uuid.h"
 
+/*!
+ * \page stasis-impl Stasis Implementation Notes
+ *
+ * \par Reference counting
+ *
+ * Stasis introduces a number of objects, which are tightly related to one
+ * another. Because we rely on ref-counting for memory management, 
understanding
+ * these relationships is important to understanding this code.
+ *
+ * \code{.txt}
+ *
+ *   stasis_topic <----> stasis_subscription
+ *             ^          ^
+ *              \        /
+ *               \      /
+ *               dispatch
+ *                  |
+ *                  |
+ *                  v
+ *            stasis_message
+ *                  |
+ *                  |
+ *                  v
+ *          stasis_message_type
+ *
+ * \endcode
+ *
+ * The most troubling thing in this chart is the cyclic reference between
+ * stasis_topic and stasis_subscription. This is both unfortunate, and
+ * necessary. Topics need the subscription in order to dispatch messages;
+ * subscriptions need the topics to unsubscribe and check subscription status.
+ *
+ * The cycle is broken by stasis_unsubscribe(). The unsubscribe will remove the
+ * topic's reference to a subscription. When the subcription is destroyed, it
+ * will remove its reference to the topic.
+ *
+ * This means that until a subscription has be explicitly unsubscribed, it will
+ * not be destroyed. Neither will a topic be destroyed while it has 
subscribers.
+ * The destructors of both have assertions regarding this to catch ref-counting
+ * problems where a subscription or topic has had an extra ao2_cleanup().
+ *
+ * The \ref dispatch object is a transient object, which is posted to a
+ * subscription's taskprocessor to send a message to the subscriber. They have
+ * short life cycles, allocated on one thread, destroyed on another.
+ *
+ * During shutdown, or the deletion of a domain object, there are a flurry of
+ * ao2_cleanup()s on subscriptions and topics, as the final in-flight messages
+ * are processed. Any one of these cleanups could be the one to actually 
destroy
+ * a given object, so care must be taken to ensure that an object isn't
+ * referenced after an ao2_cleanup(). This includes the implicit ao2_unlock()
+ * that might happen when a RAII_VAR() goes out of scope.
+ *
+ * \par Typical life cycles
+ *
+ *  \li stasis_topic - There are several topics which live for the duration of
+ *      the Asterisk process (ast_channel_topic_all(), etc.) but most of these
+ *      are actually fed by shorter-lived topics whose lifetime is associated
+ *      with some domain object (like ast_channel_topic() for a given
+ *      ast_channel).
+ *
+ *  \li stasis_subscription - Subscriptions have a similar mix of lifetimes as
+ *      topics, for similar reasons.
+ *
+ *  \li dispatch - Very short lived; just long enough to post a message to a
+ *      subscriber.
+ *
+ *  \li stasis_message - Short to intermediate lifetimes, but that is mostly
+ *      irrelevant. Messages are strictly data and have no behavior associated
+ *      with them, so it doesn't really matter if/when they are destroyed. By
+ *      design, a component could hold a ref to a message forever without any
+ *      ill consequences (aside from consuming more memory).
+ *
+ *  \li stasis_message_type - Long life cycles, typically only destroyed on
+ *      module unloading or _clean_ process exit.
+ *
+ * \par Subscriber shutdown sequencing
+ *
+ * Subscribers are sensitive to shutdown sequencing, specifically in how the
+ * reference message types. This is fully detailed on the wiki at
+ * https://wiki.asterisk.org/wiki/x/K4BqAQ.
+ *
+ * In short, the lifetime of the \a data (and \a callback, if in a module) must
+ * be held until the stasis_subscription_final_message() has been received.
+ * Depending on the structure of the subscriber code, this can be handled by
+ * using stasis_subscription_final_message() to free resources on the final
+ * message, or using stasis_subscription_join()/stasis_unsubscribe_and_join() 
to
+ * block until the unsubscribe has completed.
+ */
+

[... 2232 lines stripped ...]

--
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

svn-commits mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/svn-commits

Reply via email to