Merge "pjproject_bundled: Add MALLOC_DEBUG capability"
authorJoshua Colp <jcolp@digium.com>
Mon, 10 Oct 2016 23:06:30 +0000 (18:06 -0500)
committerGerrit Code Review <gerrit2@gerrit.digium.api>
Mon, 10 Oct 2016 23:06:30 +0000 (18:06 -0500)
contrib/ast-db-manage/cdr/env.py [changed from file to symlink]
contrib/ast-db-manage/config/env.py [changed from file to symlink]
contrib/ast-db-manage/env.py [new file with mode: 0755]
contrib/ast-db-manage/voicemail/env.py [changed from file to symlink]
include/asterisk/vector.h
main/translate.c
res/res_pjsip_config_wizard.c

deleted file mode 100755 (executable)
index 6740d5906d532e5b34fc3f9dae80641289ff5f7f..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,74 +0,0 @@
-from __future__ import with_statement
-from alembic import context
-from sqlalchemy import engine_from_config, pool
-from logging.config import fileConfig
-
-# this is the Alembic Config object, which provides
-# access to the values within the .ini file in use.
-config = context.config
-
-# Interpret the config file for Python logging.
-# This line sets up loggers basically.
-try:
-    fileConfig(config.config_file_name)
-except:
-    pass
-
-# add your model's MetaData object here
-# for 'autogenerate' support
-# from myapp import mymodel
-# target_metadata = mymodel.Base.metadata
-target_metadata = None
-
-# other values from the config, defined by the needs of env.py,
-# can be acquired:
-# my_important_option = config.get_main_option("my_important_option")
-# ... etc.
-
-def run_migrations_offline():
-    """Run migrations in 'offline' mode.
-
-    This configures the context with just a URL
-    and not an Engine, though an Engine is acceptable
-    here as well.  By skipping the Engine creation
-    we don't even need a DBAPI to be available.
-
-    Calls to context.execute() here emit the given string to the
-    script output.
-
-    """
-    url = config.get_main_option("sqlalchemy.url")
-    context.configure(url=url)
-
-    with context.begin_transaction():
-        context.run_migrations()
-
-def run_migrations_online():
-    """Run migrations in 'online' mode.
-
-    In this scenario we need to create an Engine
-    and associate a connection with the context.
-
-    """
-    engine = engine_from_config(
-                config.get_section(config.config_ini_section),
-                prefix='sqlalchemy.',
-                poolclass=pool.NullPool)
-
-    connection = engine.connect()
-    context.configure(
-                connection=connection,
-                target_metadata=target_metadata
-                )
-
-    try:
-        with context.begin_transaction():
-            context.run_migrations()
-    finally:
-        connection.close()
-
-if context.is_offline_mode():
-    run_migrations_offline()
-else:
-    run_migrations_online()
-
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..74b15c9300802dada9b88f05bd1fbea7f50d6e87
--- /dev/null
@@ -0,0 +1 @@
+../env.py
\ No newline at end of file
deleted file mode 100755 (executable)
index 6740d5906d532e5b34fc3f9dae80641289ff5f7f..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,74 +0,0 @@
-from __future__ import with_statement
-from alembic import context
-from sqlalchemy import engine_from_config, pool
-from logging.config import fileConfig
-
-# this is the Alembic Config object, which provides
-# access to the values within the .ini file in use.
-config = context.config
-
-# Interpret the config file for Python logging.
-# This line sets up loggers basically.
-try:
-    fileConfig(config.config_file_name)
-except:
-    pass
-
-# add your model's MetaData object here
-# for 'autogenerate' support
-# from myapp import mymodel
-# target_metadata = mymodel.Base.metadata
-target_metadata = None
-
-# other values from the config, defined by the needs of env.py,
-# can be acquired:
-# my_important_option = config.get_main_option("my_important_option")
-# ... etc.
-
-def run_migrations_offline():
-    """Run migrations in 'offline' mode.
-
-    This configures the context with just a URL
-    and not an Engine, though an Engine is acceptable
-    here as well.  By skipping the Engine creation
-    we don't even need a DBAPI to be available.
-
-    Calls to context.execute() here emit the given string to the
-    script output.
-
-    """
-    url = config.get_main_option("sqlalchemy.url")
-    context.configure(url=url)
-
-    with context.begin_transaction():
-        context.run_migrations()
-
-def run_migrations_online():
-    """Run migrations in 'online' mode.
-
-    In this scenario we need to create an Engine
-    and associate a connection with the context.
-
-    """
-    engine = engine_from_config(
-                config.get_section(config.config_ini_section),
-                prefix='sqlalchemy.',
-                poolclass=pool.NullPool)
-
-    connection = engine.connect()
-    context.configure(
-                connection=connection,
-                target_metadata=target_metadata
-                )
-
-    try:
-        with context.begin_transaction():
-            context.run_migrations()
-    finally:
-        connection.close()
-
-if context.is_offline_mode():
-    run_migrations_offline()
-else:
-    run_migrations_online()
-
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..74b15c9300802dada9b88f05bd1fbea7f50d6e87
--- /dev/null
@@ -0,0 +1 @@
+../env.py
\ No newline at end of file
diff --git a/contrib/ast-db-manage/env.py b/contrib/ast-db-manage/env.py
new file mode 100755 (executable)
index 0000000..a903451
--- /dev/null
@@ -0,0 +1,140 @@
+from __future__ import with_statement
+from alembic import context
+from alembic.script import ScriptDirectory
+from alembic.operations import Operations
+from sqlalchemy import engine_from_config, pool
+from logging.config import fileConfig
+import logging
+
+# this is the Alembic Config object, which provides
+# access to the values within the .ini file in use.
+config = context.config
+
+# Interpret the config file for Python logging.
+# This line sets up loggers basically.
+try:
+    fileConfig(config.config_file_name)
+except:
+    pass
+
+logger = logging.getLogger('alembic.runtime.setup')
+# add your model's MetaData object here
+# for 'autogenerate' support
+# from myapp import mymodel
+# target_metadata = mymodel.Base.metadata
+target_metadata = None
+
+# other values from the config, defined by the needs of env.py,
+# can be acquired:
+# my_important_option = config.get_main_option("my_important_option")
+# ... etc.
+
+def run_migrations_offline():
+    """Run migrations in 'offline' mode.
+
+    This configures the context with just a URL
+    and not an Engine, though an Engine is acceptable
+    here as well.  By skipping the Engine creation
+    we don't even need a DBAPI to be available.
+
+    Calls to context.execute() here emit the given string to the
+    script output.
+
+    """
+    url = config.get_main_option("sqlalchemy.url")
+    context.configure(url=url)
+
+    with context.begin_transaction():
+        context.run_migrations()
+
+def run_migrations_online():
+    """Run migrations in 'online' mode.
+
+    In this scenario we need to create an Engine
+    and associate a connection with the context.
+
+    """
+    engine = engine_from_config(
+                config.get_section(config.config_ini_section),
+                prefix='sqlalchemy.',
+                poolclass=pool.NullPool)
+
+    logger.info('Testing for an old alembic_version table.')
+
+    connection = engine.connect()
+    context.configure(
+                connection=connection,
+                target_metadata=target_metadata,
+                version_table='alembic_version'
+                )
+
+    script_location = config.get_main_option('script_location')
+    found = False
+    mc = context.get_context()
+    current_db_revision = mc.get_current_revision()
+    script = ScriptDirectory.from_config(config)
+    """ If there was an existing alembic_version table, we need to
+    check that it's current revision is in the history for the tree
+    we're working with.
+    """
+    for x in script.iterate_revisions('head', 'base'):
+        if x.revision == current_db_revision:
+            """ An alembic_versions table was found and it belongs to
+            this alembic tree
+            """
+            logger.info(
+                ('An old alembic_version table at revision %s was '
+                 'found for %s.  Renaming to alembic_version_%s.'),
+                        current_db_revision, script_location,
+                        script_location)
+            op = Operations(mc)
+            try:
+                with context.begin_transaction():
+                    op.rename_table(
+                        'alembic_version', 'alembic_version_%s'
+                        % script_location)
+                found = True
+            except:
+                logger.error(('Unable to rename alembic_version to '
+                             'alembic_version_%s.'),
+                             script_location)
+                connection.close()
+                return
+
+            break
+
+    if not found:
+        logger.info('Didn\'t find an old alembic_version table.')
+    logger.info('Trying alembic_version_%s.' % script_location)
+
+    """ We MAY have an alembic_version table that doesn't belong to
+    this tree but if we still don't have an alembic_version_<tree>
+    table, alembic will create it.
+    """
+    context.configure(
+                connection=connection,
+                target_metadata=target_metadata,
+                version_table='alembic_version_' + script_location
+                )
+    mc = context.get_context()
+    current_db_revision = mc.get_current_revision()
+    if current_db_revision:
+        logger.info(
+            'Using the alembic_version_%s table at revision %s.',
+            script_location, current_db_revision)
+    else:
+        logger.info('Creating new alembic_version_%s table.',
+                    script_location)
+
+    try:
+        with context.begin_transaction():
+            context.run_migrations()
+    finally:
+        connection.close()
+
+
+if context.is_offline_mode():
+    run_migrations_offline()
+else:
+    run_migrations_online()
+
deleted file mode 100755 (executable)
index 6740d5906d532e5b34fc3f9dae80641289ff5f7f..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,74 +0,0 @@
-from __future__ import with_statement
-from alembic import context
-from sqlalchemy import engine_from_config, pool
-from logging.config import fileConfig
-
-# this is the Alembic Config object, which provides
-# access to the values within the .ini file in use.
-config = context.config
-
-# Interpret the config file for Python logging.
-# This line sets up loggers basically.
-try:
-    fileConfig(config.config_file_name)
-except:
-    pass
-
-# add your model's MetaData object here
-# for 'autogenerate' support
-# from myapp import mymodel
-# target_metadata = mymodel.Base.metadata
-target_metadata = None
-
-# other values from the config, defined by the needs of env.py,
-# can be acquired:
-# my_important_option = config.get_main_option("my_important_option")
-# ... etc.
-
-def run_migrations_offline():
-    """Run migrations in 'offline' mode.
-
-    This configures the context with just a URL
-    and not an Engine, though an Engine is acceptable
-    here as well.  By skipping the Engine creation
-    we don't even need a DBAPI to be available.
-
-    Calls to context.execute() here emit the given string to the
-    script output.
-
-    """
-    url = config.get_main_option("sqlalchemy.url")
-    context.configure(url=url)
-
-    with context.begin_transaction():
-        context.run_migrations()
-
-def run_migrations_online():
-    """Run migrations in 'online' mode.
-
-    In this scenario we need to create an Engine
-    and associate a connection with the context.
-
-    """
-    engine = engine_from_config(
-                config.get_section(config.config_ini_section),
-                prefix='sqlalchemy.',
-                poolclass=pool.NullPool)
-
-    connection = engine.connect()
-    context.configure(
-                connection=connection,
-                target_metadata=target_metadata
-                )
-
-    try:
-        with context.begin_transaction():
-            context.run_migrations()
-    finally:
-        connection.close()
-
-if context.is_offline_mode():
-    run_migrations_offline()
-else:
-    run_migrations_online()
-
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..74b15c9300802dada9b88f05bd1fbea7f50d6e87
--- /dev/null
@@ -0,0 +1 @@
+../env.py
\ No newline at end of file
index be90912..b4a8a2c 100644 (file)
        AST_VECTOR_REMOVE(vec, idx, 1)
 
 /*!
+ * \brief Remove all elements from a vector that matches the given comparison
+ *
+ * \param vec Vector to remove from.
+ * \param value Value to pass into comparator.
+ * \param cmp Comparator function/macros (called as \c cmp(elem, value))
+ * \param cleanup How to cleanup a removed element macro/function.
+ *
+ * \return the number of deleted elements.
+ */
+#define AST_VECTOR_REMOVE_ALL_CMP_UNORDERED(vec, value, cmp, cleanup) ({       \
+       int count = 0;                                                  \
+       size_t idx;                                                     \
+       typeof(value) __value = (value);                                \
+       for (idx = 0; idx < (vec)->current; ++idx) {                    \
+               if (cmp((vec)->elems[idx], __value)) {                  \
+                       cleanup((vec)->elems[idx]);                     \
+                       AST_VECTOR_REMOVE_UNORDERED((vec), idx);        \
+                       ++count;                                        \
+               }                                                       \
+       }                                                               \
+       count;                                                          \
+})
+
+/*!
  * \brief Remove an element from a vector that matches the given comparison
  *
  * \param vec Vector to remove from.
 })
 
 /*!
+ * \brief Remove all elements from a vector that matches the given comparison while maintaining order
+ *
+ * \param vec Vector to remove from.
+ * \param value Value to pass into comparator.
+ * \param cmp Comparator function/macros (called as \c cmp(elem, value))
+ * \param cleanup How to cleanup a removed element macro/function.
+ *
+ * \return the number of deleted elements.
+ */
+#define AST_VECTOR_REMOVE_ALL_CMP_ORDERED(vec, value, cmp, cleanup) ({ \
+       int count = 0;                                                  \
+       size_t idx;                                                     \
+       typeof(value) __value = (value);                                \
+       for (idx = 0; idx < (vec)->current; ++idx) {                    \
+               if (cmp((vec)->elems[idx], __value)) {                  \
+                       cleanup((vec)->elems[idx]);                     \
+                       AST_VECTOR_REMOVE_ORDERED((vec), idx);  \
+                       ++count;                                        \
+               }                                                       \
+       }                                                               \
+       oount;                                                          \
+})
+
+/*!
  * \brief Remove an element from a vector that matches the given comparison while maintaining order
  *
  * \param vec Vector to remove from.
index 45113aa..43e6e29 100644 (file)
 
 ASTERISK_REGISTER_FILE()
 
-#include <sys/resource.h>               /* for rusage, getrusage, etc */
-#include <sys/time.h>                   /* for timeval */
-
-#include "asterisk/astobj2.h"           /* for ao2_ref, ao2_cleanup, etc */
-#include "asterisk/cli.h"               /* for ast_cli_args, ast_cli, etc */
-#include "asterisk/codec.h"             /* for ast_codec, etc */
-#include "asterisk/format.h"            /* for ast_format_get_name, etc */
-#include "asterisk/format_cache.h"      /* for ast_format_cache_get, etc */
-#include "asterisk/format_cap.h"        /* for ast_format_cap_count, etc */
-#include "asterisk/frame.h"             /* for ast_frame, etc */
-#include "asterisk/linkedlists.h"       /* for AST_RWLIST_UNLOCK, etc */
-#include "asterisk/lock.h"              /* for ast_rwlock_unlock, etc */
-#include "asterisk/logger.h"            /* for ast_log, LOG_WARNING, etc */
-#include "asterisk/module.h"            /* for ast_module_unref, etc */
-#include "asterisk/strings.h"           /* for ast_str_append, etc */
-#include "asterisk/term.h"              /* for term_color, COLOR_BLACK, etc */
-#include "asterisk/time.h"              /* for ast_tvzero, ast_tv, etc */
-#include "asterisk/translate.h"         /* for ast_translator, etc */
-#include "asterisk/utils.h"             /* for ast_free, RAII_VAR, etc */
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <math.h>
+
+#include "asterisk/lock.h"
+#include "asterisk/channel.h"
+#include "asterisk/translate.h"
+#include "asterisk/module.h"
+#include "asterisk/frame.h"
+#include "asterisk/sched.h"
+#include "asterisk/cli.h"
+#include "asterisk/term.h"
+#include "asterisk/format.h"
+#include "asterisk/linkedlists.h"
 
 /*! \todo
  * TODO: sample frames for each supported input format.
@@ -363,7 +358,6 @@ static struct ast_trans_pvt *newpvt(struct ast_translator *t, struct ast_format
        pvt->f.offset = AST_FRIENDLY_OFFSET;
        pvt->f.src = pvt->t->name;
        pvt->f.data.ptr = pvt->outbuf.c;
-       pvt->f.seqno = 0x10000;
 
        /*
         * If the translator has not provided a format
@@ -530,58 +524,13 @@ struct ast_trans_pvt *ast_translator_build_path(struct ast_format *dst, struct a
 /*! \brief do the actual translation */
 struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f, int consume)
 {
-       const unsigned int rtp_seqno_max_value = 0xffff;
-       struct ast_frame *out_last, *out = NULL;
-       struct ast_trans_pvt *step;
+       struct ast_trans_pvt *p = path;
+       struct ast_frame *out;
        struct timeval delivery;
        int has_timing_info;
        long ts;
        long len;
-       int seqno, frames_missing;
-
-       /* Determine the amount of lost packets for PLC */
-       /* But not when Signed Linear is involved = frame created internally */
-       /* But not at start with first frame = path->f.seqno is still 0x10000 */
-       /* But not when there is no sequence number = frame created internally */
-       if (!ast_format_cache_is_slinear(f->subclass.format) &&
-               path->f.seqno <= rtp_seqno_max_value &&
-               path->f.seqno != f->seqno) {
-               if (f->seqno < path->f.seqno) { /* seqno overrun situation */
-                       frames_missing = rtp_seqno_max_value + f->seqno - path->f.seqno - 1;
-               } else {
-                       frames_missing = f->seqno - path->f.seqno - 1;
-               }
-               /* Out-of-order packet - more precise: late packet */
-               if ((rtp_seqno_max_value + 1) / 2 < frames_missing) {
-                       if (consume) {
-                               ast_frfree(f);
-                       }
-                       /*
-                        * Do not pass late packets to any transcoding module, because that
-                        * confuses the state of any library (packets inter-depend). With
-                        * the next packet, this one is going to be treated as lost packet.
-                        */
-                       if (frames_missing > 96) { /* with 20 msec per frame, around 2 seconds late */
-                               struct ast_str *str = ast_str_alloca(256);
-
-                               /* Might indicate an error in the detection of Late Frames, report! */
-                               ast_log(LOG_NOTICE, "Late Frame; got Sequence Number %d expected %d %s\n",
-                                                 f->seqno, rtp_seqno_max_value & (path->f.seqno + 1),
-                                                 ast_translate_path_to_str(path, &str));
-                       }
-                       return NULL;
-               }
-
-               if (frames_missing > 96) {
-                       struct ast_str *str = ast_str_alloca(256);
-
-                       /* not DEBUG but NOTICE because of WARNING in main/cannel.c:__ast_queue_frame */
-                       ast_log(LOG_NOTICE, "%d lost frame(s) %d/%d %s\n", frames_missing,
-                                       f->seqno, path->f.seqno, ast_translate_path_to_str(path, &str));
-               }
-       } else {
-               frames_missing = 0;
-       }
+       int seqno;
 
        has_timing_info = ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO);
        ts = f->ts;
@@ -611,93 +560,18 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f,
                         f->samples, ast_format_get_sample_rate(f->subclass.format)));
        }
        delivery = f->delivery;
-
-       for (out_last = NULL; frames_missing + 1; frames_missing--) {
-               struct ast_frame *frame_to_translate, *inner_head;
-               struct ast_frame missed = {
-                       .frametype = AST_FRAME_VOICE,
-                       .subclass.format = f->subclass.format,
-                       .datalen = 0,
-                       /* In RTP, the amount of samples might change anytime  */
-                       /* If that happened while frames got lost, what to do? */
-                       .samples = f->samples, /* FIXME */
-                       .src = __FUNCTION__,
-                       .data.uint32 = 0,
-                       .delivery.tv_sec = 0,
-                       .delivery.tv_usec = 0,
-                       .flags = 0,
-                       /* RTP sequence number is between 0x0001 and 0xffff */
-                       .seqno = (rtp_seqno_max_value + 1 + f->seqno - frames_missing) & rtp_seqno_max_value,
-               };
-
-               if (frames_missing) {
-                       frame_to_translate = &missed;
-               } else {
-                       frame_to_translate = f;
-               }
-
-               /* The translation path from one format to another might contain several steps */
-               /* out* collects the result for missed frame(s) and input frame(s) */
-               /* out is the result of the conversion of all frames, translated into the destination format */
-               /* out_last is the last frame in that list, to add frames faster */
-               for (step = path, inner_head = frame_to_translate; inner_head && step; step = step->next) {
-                       struct ast_frame *current, *inner_last, *inner_prev = frame_to_translate;
-
-                       /* inner* collects the result of each conversion step, the input for the next step */
-                       /* inner_head is a list of frames created by each conversion step */
-                       /* inner_last is the last frame in that list, to add frames faster */
-                       for (inner_last = NULL, current = inner_head; current; current = AST_LIST_NEXT(current, frame_list)) {
-                               struct ast_frame *tmp;
-
-                               framein(step, current);
-                               tmp = step->t->frameout(step);
-
-                               if (!tmp) {
-                                       continue;
-                               } else if (inner_last) {
-                                       struct ast_frame *t;
-
-                                       /* Determine the last frame of the list before appending to it */
-                                       while ((t = AST_LIST_NEXT(inner_last, frame_list))) {
-                                               inner_last = t;
-                                       }
-                                       AST_LIST_NEXT(inner_last, frame_list) = tmp;
-                               } else {
-                                       inner_prev = inner_head;
-                                       inner_head = tmp;
-                                       inner_last = tmp;
-                               }
-                       }
-
-                       /* The current step did not create any frames = no frames for the next step */
-                       /* The steps are not lost because framein buffered those for the next input frame */
-                       if (!inner_last) {
-                               inner_prev = inner_head;
-                               inner_head = NULL;
-                       }
-                       if (inner_prev != frame_to_translate) {
-                               ast_frfree(inner_prev); /* Frees just the intermediate lists */
-                       }
-               }
-
-               /* This frame created no frames after translation = continue with next frame */
-               /* The frame is not lost because framein buffered it to be combined with the next frame */
-               if (!inner_head) {
-                       continue;
-               } else if (out_last) {
-                       struct ast_frame *t;
-
-                       /* Determine the last frame of the list before appending to it */
-                       while ((t = AST_LIST_NEXT(out_last, frame_list))) {
-                               out_last = t;
-                       }
-                       AST_LIST_NEXT(out_last, frame_list) = inner_head;
-               } else {
-                       out = inner_head;
-                       out_last = inner_head;
+       for (out = f; out && p ; p = p->next) {
+               struct ast_frame *current = out;
+
+               do {
+                       framein(p, current);
+                       current = AST_LIST_NEXT(current, frame_list);
+               } while (current);
+               if (out != f) {
+                       ast_frfree(out);
                }
+               out = p->t->frameout(p);
        }
-
        if (out) {
                /* we have a frame, play with times */
                if (!ast_tvzero(delivery)) {
index cf09a54..aec923d 100644 (file)
@@ -989,7 +989,7 @@ static int wizard_apply_handler(const struct ast_sorcery *sorcery, struct object
                rc = handle_registrations(sorcery, otw, wiz, &remote_hosts_vector);
        }
 
-       AST_VECTOR_REMOVE_CMP_UNORDERED(&remote_hosts_vector, NULL, NOT_EQUALS, ast_free);
+       AST_VECTOR_REMOVE_ALL_CMP_UNORDERED(&remote_hosts_vector, NULL, NOT_EQUALS, ast_free);
        AST_VECTOR_FREE(&remote_hosts_vector);
 
        ast_debug(4, "%s handler complete.  rc: %d\n", otw->object_type, rc);
@@ -1293,7 +1293,7 @@ static int unload_module(void)
 {
        ast_cli_unregister_multiple(config_wizard_cli, ARRAY_LEN(config_wizard_cli));
        ast_sorcery_global_observer_remove(&global_observer);
-       AST_VECTOR_REMOVE_CMP_UNORDERED(&object_type_wizards, NULL, NOT_EQUALS, OTW_DELETE_CB);
+       AST_VECTOR_REMOVE_ALL_CMP_UNORDERED(&object_type_wizards, NULL, NOT_EQUALS, OTW_DELETE_CB);
        AST_VECTOR_RW_FREE(&object_type_wizards);
 
        return 0;