1999-10-24 16:47:59 +00:00
|
|
|
/*
|
|
|
|
* Asterisk -- A telephony toolkit for Linux.
|
|
|
|
*
|
|
|
|
* General Definitions for Asterisk top level program
|
|
|
|
*
|
2006-04-24 17:11:45 +00:00
|
|
|
* Copyright (C) 1999-2006, Digium, Inc.
|
1999-10-24 16:47:59 +00:00
|
|
|
*
|
2005-06-06 20:27:51 +00:00
|
|
|
* Mark Spencer <markster@digium.com>
|
1999-10-24 16:47:59 +00:00
|
|
|
*
|
|
|
|
* This program is free software, distributed under the terms of
|
|
|
|
* the GNU General Public License
|
|
|
|
*/
|
|
|
|
|
2005-10-26 13:03:17 +00:00
|
|
|
/*! \file
|
|
|
|
* \brief Asterisk main include file. File version handling, generic pbx functions.
|
|
|
|
*/
|
|
|
|
|
1999-10-24 16:47:59 +00:00
|
|
|
#ifndef _ASTERISK_H
|
|
|
|
#define _ASTERISK_H
|
|
|
|
|
2006-06-07 19:05:35 +00:00
|
|
|
#include "asterisk/autoconfig.h"
|
2006-06-07 18:54:56 +00:00
|
|
|
|
2008-09-27 15:13:30 +00:00
|
|
|
#if !defined(NO_MALLOC_DEBUG) && !defined(STANDALONE_AEL) && defined(MALLOC_DEBUG)
|
2008-09-27 15:00:48 +00:00
|
|
|
#include "asterisk/astmm.h"
|
|
|
|
#endif
|
|
|
|
|
2006-04-24 17:11:45 +00:00
|
|
|
#include "asterisk/compat.h"
|
|
|
|
|
2006-08-22 21:45:15 +00:00
|
|
|
#include "asterisk/paths.h"
|
2006-06-09 20:40:10 +00:00
|
|
|
|
2000-01-09 19:58:18 +00:00
|
|
|
#define DEFAULT_LANGUAGE "en"
|
|
|
|
|
2006-03-29 02:12:31 +00:00
|
|
|
#define DEFAULT_SAMPLE_RATE 8000
|
|
|
|
#define DEFAULT_SAMPLES_PER_MS ((DEFAULT_SAMPLE_RATE)/1000)
|
2007-04-09 03:01:12 +00:00
|
|
|
#define setpriority __PLEASE_USE_ast_set_priority_INSTEAD_OF_setpriority__
|
|
|
|
#define sched_setscheduler __PLEASE_USE_ast_set_priority_INSTEAD_OF_sched_setscheduler__
|
2006-03-29 02:12:31 +00:00
|
|
|
|
2009-04-09 04:31:38 +00:00
|
|
|
#if defined(DEBUG_FD_LEAKS) && !defined(STANDALONE) && !defined(STANDALONE_AEL)
|
|
|
|
/* These includes are all about ordering */
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
|
|
|
#define open(a,...) __ast_fdleak_open(__FILE__,__LINE__,__PRETTY_FUNCTION__, a, __VA_ARGS__)
|
|
|
|
#define pipe(a) __ast_fdleak_pipe(a, __FILE__,__LINE__,__PRETTY_FUNCTION__)
|
|
|
|
#define socket(a,b,c) __ast_fdleak_socket(a, b, c, __FILE__,__LINE__,__PRETTY_FUNCTION__)
|
|
|
|
#define close(a) __ast_fdleak_close(a)
|
|
|
|
#define fopen(a,b) __ast_fdleak_fopen(a, b, __FILE__,__LINE__,__PRETTY_FUNCTION__)
|
|
|
|
#define fclose(a) __ast_fdleak_fclose(a)
|
|
|
|
#define dup2(a,b) __ast_fdleak_dup2(a, b, __FILE__,__LINE__,__PRETTY_FUNCTION__)
|
|
|
|
#define dup(a) __ast_fdleak_dup(a, __FILE__,__LINE__,__PRETTY_FUNCTION__)
|
|
|
|
|
2009-08-21 16:52:53 +00:00
|
|
|
#if defined(__cplusplus) || defined(c_plusplus)
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
2009-04-09 04:31:38 +00:00
|
|
|
int __ast_fdleak_open(const char *file, int line, const char *func, const char *path, int flags, ...);
|
|
|
|
int __ast_fdleak_pipe(int *fds, const char *file, int line, const char *func);
|
|
|
|
int __ast_fdleak_socket(int domain, int type, int protocol, const char *file, int line, const char *func);
|
|
|
|
int __ast_fdleak_close(int fd);
|
|
|
|
FILE *__ast_fdleak_fopen(const char *path, const char *mode, const char *file, int line, const char *func);
|
|
|
|
int __ast_fdleak_fclose(FILE *ptr);
|
|
|
|
int __ast_fdleak_dup2(int oldfd, int newfd, const char *file, int line, const char *func);
|
|
|
|
int __ast_fdleak_dup(int oldfd, const char *file, int line, const char *func);
|
2009-08-21 16:52:53 +00:00
|
|
|
#if defined(__cplusplus) || defined(c_plusplus)
|
|
|
|
}
|
|
|
|
#endif
|
2009-04-09 04:31:38 +00:00
|
|
|
#endif
|
|
|
|
|
2005-06-06 03:04:58 +00:00
|
|
|
/* provided in asterisk.c */
|
2006-06-09 20:40:10 +00:00
|
|
|
extern char ast_config_AST_CONFIG_DIR[PATH_MAX];
|
|
|
|
extern char ast_config_AST_CONFIG_FILE[PATH_MAX];
|
|
|
|
extern char ast_config_AST_MODULE_DIR[PATH_MAX];
|
|
|
|
extern char ast_config_AST_SPOOL_DIR[PATH_MAX];
|
|
|
|
extern char ast_config_AST_MONITOR_DIR[PATH_MAX];
|
|
|
|
extern char ast_config_AST_VAR_DIR[PATH_MAX];
|
|
|
|
extern char ast_config_AST_DATA_DIR[PATH_MAX];
|
|
|
|
extern char ast_config_AST_LOG_DIR[PATH_MAX];
|
|
|
|
extern char ast_config_AST_AGI_DIR[PATH_MAX];
|
|
|
|
extern char ast_config_AST_DB[PATH_MAX];
|
|
|
|
extern char ast_config_AST_KEY_DIR[PATH_MAX];
|
|
|
|
extern char ast_config_AST_PID[PATH_MAX];
|
|
|
|
extern char ast_config_AST_SOCKET[PATH_MAX];
|
|
|
|
extern char ast_config_AST_RUN_DIR[PATH_MAX];
|
|
|
|
extern char ast_config_AST_CTL_PERMISSIONS[PATH_MAX];
|
|
|
|
extern char ast_config_AST_CTL_OWNER[PATH_MAX];
|
|
|
|
extern char ast_config_AST_CTL_GROUP[PATH_MAX];
|
|
|
|
extern char ast_config_AST_CTL[PATH_MAX];
|
2006-02-14 23:42:36 +00:00
|
|
|
extern char ast_config_AST_SYSTEM_NAME[20];
|
1999-10-24 16:47:59 +00:00
|
|
|
|
2006-06-08 07:29:46 +00:00
|
|
|
int ast_set_priority(int); /*!< Provided by asterisk.c */
|
2006-08-21 22:23:26 +00:00
|
|
|
int load_modules(unsigned int); /*!< Provided by loader.c */
|
2006-06-08 07:29:46 +00:00
|
|
|
int load_pbx(void); /*!< Provided by pbx.c */
|
2006-06-09 02:20:25 +00:00
|
|
|
int init_logger(void); /*!< Provided by logger.c */
|
|
|
|
void close_logger(void); /*!< Provided by logger.c */
|
2006-06-08 07:29:46 +00:00
|
|
|
int reload_logger(int); /*!< Provided by logger.c */
|
|
|
|
int init_framer(void); /*!< Provided by frame.c */
|
2006-10-04 00:25:44 +00:00
|
|
|
int ast_term_init(void); /*!< Provided by term.c */
|
2006-06-08 07:29:46 +00:00
|
|
|
int astdb_init(void); /*!< Provided by db.c */
|
|
|
|
void ast_channels_init(void); /*!< Provided by channel.c */
|
|
|
|
void ast_builtins_init(void); /*!< Provided by cli.c */
|
|
|
|
int dnsmgr_init(void); /*!< Provided by dnsmgr.c */
|
|
|
|
void dnsmgr_start_refresh(void); /*!< Provided by dnsmgr.c */
|
|
|
|
int dnsmgr_reload(void); /*!< Provided by dnsmgr.c */
|
2007-01-04 22:51:01 +00:00
|
|
|
void threadstorage_init(void); /*!< Provided by threadstorage.c */
|
2007-09-13 18:45:59 +00:00
|
|
|
int astobj2_init(void); /*! Provided by astobj2.c */
|
Merge in some changes from team/russell/autoservice-nochans-1.4
These changes fix up some dubious code that I came across while auditing what
happens in the autoservice thread when there are no channels currently in
autoservice.
1) Change it so that autoservice thread doesn't keep looping around calling
ast_waitfor_n() on 0 channels twice a second. Instead, use a thread condition
so that the thread properly goes to sleep and does not wake up until a
channel is put into autoservice.
This actually fixes an interesting bug, as well. If the autoservice thread
is already running (almost always is the case), then when the thread goes
from having 0 channels to have 1 channel to autoservice, that channel would
have to wait for up to 1/2 of a second to have the first frame read from it.
2) Fix up the code in ast_waitfor_nandfds() for when it gets called with no
channels and no fds to poll() on, such as was the case with the previous code
for the autoservice thread. In this case, the code would call alloca(0), and
pass the result as the first argument to poll(). In this case, the 2nd
argument to poll() specified that there were no fds, so this invalid pointer
shouldn't actually get dereferenced, but, this code makes it explicit and
ensures the pointers are NULL unless we have valid data to put there.
(related to issue #12116)
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@105563 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2008-03-03 15:50:43 +00:00
|
|
|
void ast_autoservice_init(void); /*!< Provided by autoservice.c */
|
2009-04-09 04:31:38 +00:00
|
|
|
int ast_fd_init(void); /*!< Provided by astfd.c */
|
2003-01-30 15:03:20 +00:00
|
|
|
|
2006-08-21 02:11:39 +00:00
|
|
|
/* Many headers need 'ast_channel' to be defined */
|
|
|
|
struct ast_channel;
|
|
|
|
|
|
|
|
/* Many headers need 'ast_module' to be defined */
|
|
|
|
struct ast_module;
|
|
|
|
|
2006-04-14 14:08:19 +00:00
|
|
|
/*!
|
|
|
|
* \brief Reload asterisk modules.
|
|
|
|
* \param name the name of the module to reload
|
|
|
|
*
|
|
|
|
* This function reloads the specified module, or if no modules are specified,
|
|
|
|
* it will reload all loaded modules.
|
|
|
|
*
|
|
|
|
* \note Modules are reloaded using their reload() functions, not unloading
|
|
|
|
* them and loading them again.
|
|
|
|
*
|
|
|
|
* \return Zero if the specified module was not found, 1 if the module was
|
|
|
|
* found but cannot be reloaded, -1 if a reload operation is already in
|
|
|
|
* progress, and 2 if the specfied module was found and reloaded.
|
|
|
|
*/
|
|
|
|
int ast_module_reload(const char *name);
|
|
|
|
|
Safely handle AMI connections/reload requests that occur during startup.
During asterisk startup, a lock on the list of modules is obtained by the
primary thread while each module is initialized. Issue 13778 pointed out a
problem with this approach, however. Because the AMI is loaded before other
modules, it is possible for a module reload to be issued by a connected client
(via Action: Command), causing a deadlock.
The resolution for 13778 was to move initialization of the manager to happen
after the other modules had already been lodaded. While this fixed this
particular issue, it caused a problem for users (like FreePBX) who call AMI
scripts via an #exec in a configuration file (See issue 15189).
The solution I have come up with is to defer any reload requests that come in
until after the server is fully booted. When a call comes in to
ast_module_reload (from wherever) before we are fully booted, the request is
added to a queue of pending requests. Once we are done booting up, we then
execute these deferred requests in turn.
Note that I have tried to make this a bit more intelligent in that it will not
queue up more than 1 request for the same module to be reloaded, and if a
general reload request comes in ('module reload') the queue is flushed and we
only issue a single deferred reload for the entire system.
As for how this will impact existing installations - Before 13778, a reload
issued before module initialization was completed would result in a deadlock.
After 13778, you simply couldn't connect to the manager during startup (which
causes problems with #exec-that-calls-AMI configuration files). I believe this
is a good general purpose solution that won't negatively impact existing
installations.
(closes issue #15189)
(closes issue #13778)
Reported by: p_lindheimer
Patches:
06032009_15189_deferred_reloads.diff uploaded by seanbright (license 71)
Tested by: p_lindheimer, seanbright
Review: https://reviewboard.asterisk.org/r/272/
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@199022 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2009-06-04 14:14:57 +00:00
|
|
|
/*!
|
|
|
|
* \brief Process reload requests received during startup.
|
|
|
|
*
|
|
|
|
* This function requests that the loader execute the pending reload requests
|
|
|
|
* that were queued during server startup.
|
|
|
|
*
|
|
|
|
* \note This function will do nothing if the server has not completely started
|
|
|
|
* up. Once called, the reload queue is emptied, and further invocations
|
|
|
|
* will have no affect.
|
|
|
|
*/
|
|
|
|
void ast_process_pending_reloads(void);
|
|
|
|
|
2006-04-11 15:55:56 +00:00
|
|
|
/*!
|
|
|
|
* \brief Register a function to be executed before Asterisk exits.
|
|
|
|
* \param func The callback function to use.
|
2006-04-14 14:08:19 +00:00
|
|
|
*
|
2006-04-11 15:55:56 +00:00
|
|
|
* \return Zero on success, -1 on error.
|
|
|
|
*/
|
|
|
|
int ast_register_atexit(void (*func)(void));
|
2006-04-14 14:08:19 +00:00
|
|
|
|
|
|
|
/*!
|
2006-04-11 15:55:56 +00:00
|
|
|
* \brief Unregister a function registered with ast_register_atexit().
|
2006-04-14 14:08:19 +00:00
|
|
|
* \param func The callback function to unregister.
|
2006-04-11 15:55:56 +00:00
|
|
|
*/
|
|
|
|
void ast_unregister_atexit(void (*func)(void));
|
|
|
|
|
2006-10-04 21:04:21 +00:00
|
|
|
#if !defined(LOW_MEMORY)
|
2005-06-07 01:13:23 +00:00
|
|
|
/*!
|
|
|
|
* \brief Register the version of a source code file with the core.
|
|
|
|
* \param file the source file name
|
|
|
|
* \param version the version string (typically a CVS revision keyword string)
|
|
|
|
* \return nothing
|
|
|
|
*
|
|
|
|
* This function should not be called directly, but instead the
|
|
|
|
* ASTERISK_FILE_VERSION macro should be used to register a file with the core.
|
|
|
|
*/
|
2005-06-06 20:27:51 +00:00
|
|
|
void ast_register_file_version(const char *file, const char *version);
|
2005-06-07 01:13:23 +00:00
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Unregister a source code file from the core.
|
|
|
|
* \param file the source file name
|
|
|
|
* \return nothing
|
|
|
|
*
|
|
|
|
* This function should not be called directly, but instead the
|
|
|
|
* ASTERISK_FILE_VERSION macro should be used to automatically unregister
|
|
|
|
* the file when the module is unloaded.
|
|
|
|
*/
|
2005-06-06 20:27:51 +00:00
|
|
|
void ast_unregister_file_version(const char *file);
|
|
|
|
|
2005-06-07 01:13:23 +00:00
|
|
|
/*!
|
|
|
|
* \brief Register/unregister a source code file with the core.
|
|
|
|
* \param file the source file name
|
|
|
|
* \param version the version string (typically a CVS revision keyword string)
|
|
|
|
*
|
|
|
|
* This macro will place a file-scope constructor and destructor into the
|
|
|
|
* source of the module using it; this will cause the version of this file
|
|
|
|
* to registered with the Asterisk core (and unregistered) at the appropriate
|
|
|
|
* times.
|
|
|
|
*
|
|
|
|
* Example:
|
|
|
|
*
|
|
|
|
* \code
|
|
|
|
* ASTERISK_FILE_VERSION(__FILE__, "\$Revision\$")
|
|
|
|
* \endcode
|
2005-06-07 01:17:07 +00:00
|
|
|
*
|
|
|
|
* \note The dollar signs above have been protected with backslashes to keep
|
|
|
|
* CVS from modifying them in this file; under normal circumstances they would
|
|
|
|
* not be present and CVS would expand the Revision keyword into the file's
|
|
|
|
* revision number.
|
2005-06-07 01:13:23 +00:00
|
|
|
*/
|
2006-04-12 20:40:46 +00:00
|
|
|
#ifdef MTX_PROFILE
|
|
|
|
#define HAVE_MTX_PROFILE /* used in lock.h */
|
|
|
|
#define ASTERISK_FILE_VERSION(file, version) \
|
|
|
|
static int mtx_prof = -1; /* profile mutex */ \
|
|
|
|
static void __attribute__((constructor)) __register_file_version(void) \
|
|
|
|
{ \
|
|
|
|
mtx_prof = ast_add_profile("mtx_lock_" file, 0); \
|
|
|
|
ast_register_file_version(file, version); \
|
|
|
|
} \
|
|
|
|
static void __attribute__((destructor)) __unregister_file_version(void) \
|
|
|
|
{ \
|
|
|
|
ast_unregister_file_version(file); \
|
|
|
|
}
|
2006-10-04 21:04:21 +00:00
|
|
|
#else /* !MTX_PROFILE */
|
2005-06-06 22:12:19 +00:00
|
|
|
#define ASTERISK_FILE_VERSION(file, version) \
|
2005-06-06 20:27:51 +00:00
|
|
|
static void __attribute__((constructor)) __register_file_version(void) \
|
|
|
|
{ \
|
2005-06-06 22:12:19 +00:00
|
|
|
ast_register_file_version(file, version); \
|
2005-06-06 20:27:51 +00:00
|
|
|
} \
|
|
|
|
static void __attribute__((destructor)) __unregister_file_version(void) \
|
|
|
|
{ \
|
2005-06-06 22:12:19 +00:00
|
|
|
ast_unregister_file_version(file); \
|
2005-06-06 20:27:51 +00:00
|
|
|
}
|
2006-10-04 21:04:21 +00:00
|
|
|
#endif /* !MTX_PROFILE */
|
2005-06-07 16:07:06 +00:00
|
|
|
#else /* LOW_MEMORY */
|
|
|
|
#define ASTERISK_FILE_VERSION(file, x)
|
2006-10-04 21:04:21 +00:00
|
|
|
#endif /* LOW_MEMORY */
|
|
|
|
|
|
|
|
#if !defined(LOW_MEMORY)
|
|
|
|
/*!
|
|
|
|
* \brief support for event profiling
|
|
|
|
*
|
|
|
|
* (note, this must be documented a lot more)
|
|
|
|
* ast_add_profile allocates a generic 'counter' with a given name,
|
|
|
|
* which can be shown with the command 'show profile <name>'
|
|
|
|
*
|
|
|
|
* The counter accumulates positive or negative values supplied by
|
|
|
|
* ast_add_profile(), dividing them by the 'scale' value passed in the
|
|
|
|
* create call, and also counts the number of 'events'.
|
|
|
|
* Values can also be taked by the TSC counter on ia32 architectures,
|
|
|
|
* in which case you can mark the start of an event calling ast_mark(id, 1)
|
|
|
|
* and then the end of the event with ast_mark(id, 0).
|
|
|
|
* For non-i386 architectures, these two calls return 0.
|
|
|
|
*/
|
|
|
|
int ast_add_profile(const char *, uint64_t scale);
|
|
|
|
int64_t ast_profile(int, int64_t);
|
|
|
|
int64_t ast_mark(int, int start1_stop0);
|
|
|
|
#else /* LOW_MEMORY */
|
|
|
|
#define ast_add_profile(a, b) 0
|
|
|
|
#define ast_profile(a, b) do { } while (0)
|
|
|
|
#define ast_mark(a, b) do { } while (0)
|
|
|
|
#endif /* LOW_MEMORY */
|
2005-06-06 20:27:51 +00:00
|
|
|
|
|
|
|
#endif /* _ASTERISK_H */
|