From 75ca02dbaabcf714a16f582c6e580e7ffd095d27 Mon Sep 17 00:00:00 2001 From: "Kevin P. Fleming" Date: Tue, 23 May 2006 17:15:23 +0000 Subject: [PATCH] backport some mutex initialization and linked list handling fixes from trunk git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.2@29732 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- apps/app_sql_postgres.c | 7 +---- dnsmgr.c | 3 +- include/asterisk/linkedlists.h | 50 ++++++++++++++++++++++++++++------ include/asterisk/lock.h | 21 ++++++++++---- pbx.c | 1 + res/res_features.c | 3 +- 6 files changed, 60 insertions(+), 25 deletions(-) diff --git a/apps/app_sql_postgres.c b/apps/app_sql_postgres.c index d9ba1bfb78..6f554a6770 100644 --- a/apps/app_sql_postgres.c +++ b/apps/app_sql_postgres.c @@ -132,7 +132,7 @@ struct ast_PGSQL_id { AST_LIST_ENTRY(ast_PGSQL_id) entries; } *ast_PGSQL_id; -AST_LIST_HEAD(PGSQLidshead,ast_PGSQL_id) PGSQLidshead; +static AST_LIST_HEAD_STATIC(PGSQLidshead,ast_PGSQL_id); static void *find_identifier(int identifier,int identifier_type) { struct PGSQLidshead *headp; @@ -551,11 +551,6 @@ int unload_module(void) int load_module(void) { - struct PGSQLidshead *headp; - - headp=&PGSQLidshead; - - AST_LIST_HEAD_INIT(headp); return ast_register_application(app, PGSQL_exec, synopsis, descrip); } diff --git a/dnsmgr.c b/dnsmgr.c index f1a9dbe599..de83247417 100644 --- a/dnsmgr.c +++ b/dnsmgr.c @@ -57,7 +57,7 @@ struct ast_dnsmgr_entry { char name[1]; }; -static AST_LIST_HEAD(entry_list, ast_dnsmgr_entry) entry_list; +static AST_LIST_HEAD_STATIC(entry_list, ast_dnsmgr_entry); AST_MUTEX_DEFINE_STATIC(refresh_lock); @@ -289,7 +289,6 @@ int dnsmgr_init(void) ast_log(LOG_ERROR, "Unable to create schedule context.\n"); return -1; } - AST_LIST_HEAD_INIT(&entry_list); ast_cli_register(&cli_reload); ast_cli_register(&cli_status); return do_reload(1); diff --git a/include/asterisk/linkedlists.h b/include/asterisk/linkedlists.h index 5f8a57b167..fec406f6e4 100644 --- a/include/asterisk/linkedlists.h +++ b/include/asterisk/linkedlists.h @@ -100,6 +100,23 @@ struct name { \ struct type *last; \ } +/*! + \brief Defines initial values for a declaration of AST_LIST_HEAD +*/ +#define AST_LIST_HEAD_INIT_VALUE { \ + .first = NULL, \ + .last = NULL, \ + .lock = AST_MUTEX_INIT_VALUE, \ + } + +/*! + \brief Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK +*/ +#define AST_LIST_HEAD_NOLOCK_INIT_VALUE { \ + .first = NULL, \ + .last = NULL, \ + } + /*! \brief Defines a structure to be used to hold a list of specified type, statically initialized. \param name This will be the name of the defined structure. @@ -122,11 +139,18 @@ struct name { \ struct type *first; \ struct type *last; \ ast_mutex_t lock; \ -} name = { \ - .first = NULL, \ - .last = NULL, \ - .lock = AST_MUTEX_INIT_VALUE, \ -}; +} name = AST_LIST_HEAD_INIT_VALUE + +/*! + \brief Defines a structure to be used to hold a list of specified type, statically initialized. + + This is the same as AST_LIST_HEAD_STATIC, except without the lock included. +*/ +#define AST_LIST_HEAD_NOLOCK_STATIC(name, type) \ +struct name { \ + struct type *first; \ + struct type *last; \ +} name = AST_LIST_HEAD_NOLOCK_INIT_VALUE /*! \brief Initializes a list head structure with a specified first entry. @@ -183,6 +207,12 @@ struct { \ */ #define AST_LIST_FIRST(head) ((head)->first) +/*! + \brief Returns the last entry contained in a list. + \param head This is a pointer to the list tail structure + */ +#define AST_LIST_LAST(head) ((head)->last) + /*! \brief Returns the next entry in the list after the given entry. \param elm This is a pointer to the current entry. @@ -433,11 +463,13 @@ struct { \ (head)->last = NULL; \ } else { \ typeof(elm) curelm = (head)->first; \ - while (curelm->field.next != (elm)) \ + while (curelm && (curelm->field.next != (elm))) \ curelm = curelm->field.next; \ - curelm->field.next = (elm)->field.next; \ - if ((head)->last == (elm)) \ - (head)->last = curelm; \ + if (curelm) { \ + curelm->field.next = (elm)->field.next; \ + if ((head)->last == (elm)) \ + (head)->last = curelm; \ + } \ } \ (elm)->field.next = NULL; \ } while (0) diff --git a/include/asterisk/lock.h b/include/asterisk/lock.h index 38c4e64ac7..cf9549751b 100644 --- a/include/asterisk/lock.h +++ b/include/asterisk/lock.h @@ -97,6 +97,13 @@ typedef struct ast_mutex_info ast_mutex_t; typedef pthread_cond_t ast_cond_t; +static pthread_mutex_t empty_mutex; + +static void __attribute__((constructor)) init_empty_mutex(void) +{ + memset(&empty_mutex, 0, sizeof(empty_mutex)); +} + static inline int __ast_pthread_mutex_init_attr(const char *filename, int lineno, const char *func, const char *mutex_name, ast_mutex_t *t, pthread_mutexattr_t *attr) @@ -105,14 +112,16 @@ static inline int __ast_pthread_mutex_init_attr(const char *filename, int lineno int canlog = strcmp(filename, "logger.c"); if ((t->mutex) != ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) { - __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is already initialized.\n", - filename, lineno, func, mutex_name); - __ast_mutex_logger("%s line %d (%s): Error: previously initialization of mutex '%s'.\n", - t->file, t->lineno, t->func, mutex_name); + if ((t->mutex) != (empty_mutex)) { + __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is already initialized.\n", + filename, lineno, func, mutex_name); + __ast_mutex_logger("%s line %d (%s): Error: previously initialization of mutex '%s'.\n", + t->file, t->lineno, t->func, mutex_name); #ifdef THREAD_CRASH - DO_THREAD_CRASH; + DO_THREAD_CRASH; #endif - return 0; + return 0; + } } #endif diff --git a/pbx.c b/pbx.c index 3e0c417243..ee00f3a473 100644 --- a/pbx.c +++ b/pbx.c @@ -3706,6 +3706,7 @@ void ast_merge_contexts_and_delete(struct ast_context **extcontexts, const char int length; struct ast_state_cb *thiscb, *prevcb; + memset(&store, 0, sizeof(store)); AST_LIST_HEAD_INIT(&store); /* it is very important that this function hold the hintlock _and_ the conlock diff --git a/res/res_features.c b/res/res_features.c index 885f4a7d74..a122abf5ff 100644 --- a/res/res_features.c +++ b/res/res_features.c @@ -866,7 +866,7 @@ struct ast_call_feature builtin_features[] = }; -static AST_LIST_HEAD(feature_list,ast_call_feature) feature_list; +static AST_LIST_HEAD_STATIC(feature_list,ast_call_feature); /* register new feature into feature_list*/ void ast_register_feature(struct ast_call_feature *feature) @@ -2145,7 +2145,6 @@ int load_module(void) { int res; - AST_LIST_HEAD_INIT(&feature_list); memset(parking_ext, 0, sizeof(parking_ext)); memset(parking_con, 0, sizeof(parking_con));