mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-08 19:08:14 +00:00
Merged revisions 85994 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r85994 | russell | 2007-10-16 17:14:36 -0500 (Tue, 16 Oct 2007) | 16 lines Some locking errors exposed the fact that the lock debugging code itself was not thread safe. How ironic! Anyway, these changes ensure that the code that is accessing the lock debugging data is thread-safe. Many thanks to Ivan for finding and fixing the core issue here, and also thanks to those that tested the patch and provided test results. (closes issue #10571) (closes issue #10886) (closes issue #10875) (might close some others, as well ...) Patches: (from issue #10571) ivan_ast_1_4_12_rel_patch_lock.h.diff uploaded by Ivan (license 229) - a few small changes by me ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@85995 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -118,6 +118,7 @@ struct ast_mutex_info {
|
|||||||
int reentrancy;
|
int reentrancy;
|
||||||
const char *func[AST_MAX_REENTRANCY];
|
const char *func[AST_MAX_REENTRANCY];
|
||||||
pthread_t thread[AST_MAX_REENTRANCY];
|
pthread_t thread[AST_MAX_REENTRANCY];
|
||||||
|
pthread_mutex_t reentr_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct ast_mutex_info ast_mutex_t;
|
typedef struct ast_mutex_info ast_mutex_t;
|
||||||
@@ -166,11 +167,45 @@ static void __attribute__((constructor)) init_empty_mutex(void)
|
|||||||
memset(&empty_mutex, 0, sizeof(empty_mutex));
|
memset(&empty_mutex, 0, sizeof(empty_mutex));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void reentrancy_lock_cs(ast_mutex_t *p_ast_mutex)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&p_ast_mutex->reentr_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void reentrancy_unlock_cs(ast_mutex_t *p_ast_mutex)
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&p_ast_mutex->reentr_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void init_reentrancy_cs(ast_mutex_t *p_ast_mutex)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
static pthread_mutexattr_t reentr_attr;
|
||||||
|
|
||||||
|
for (i = 0; i < AST_MAX_REENTRANCY; i++) {
|
||||||
|
p_ast_mutex->file[i] = NULL;
|
||||||
|
p_ast_mutex->lineno[i] = 0;
|
||||||
|
p_ast_mutex->func[i] = NULL;
|
||||||
|
p_ast_mutex->thread[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p_ast_mutex->reentrancy = 0;
|
||||||
|
|
||||||
|
pthread_mutexattr_init(&reentr_attr);
|
||||||
|
pthread_mutexattr_settype(&reentr_attr, AST_MUTEX_KIND);
|
||||||
|
pthread_mutex_init(&p_ast_mutex->reentr_mutex, &reentr_attr);
|
||||||
|
pthread_mutexattr_destroy(&reentr_attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void delete_reentrancy_cs(ast_mutex_t * p_ast_mutex)
|
||||||
|
{
|
||||||
|
pthread_mutex_destroy(&p_ast_mutex->reentr_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
static inline int __ast_pthread_mutex_init_attr(int track, const char *filename, int lineno, const char *func,
|
static inline int __ast_pthread_mutex_init_attr(int track, const char *filename, int lineno, const char *func,
|
||||||
const char *mutex_name, ast_mutex_t *t,
|
const char *mutex_name, ast_mutex_t *t,
|
||||||
pthread_mutexattr_t *attr)
|
pthread_mutexattr_t *attr)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
|
#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
|
||||||
int canlog = strcmp(filename, "logger.c");
|
int canlog = strcmp(filename, "logger.c");
|
||||||
|
|
||||||
@@ -186,13 +221,7 @@ static inline int __ast_pthread_mutex_init_attr(int track, const char *filename,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < AST_MAX_REENTRANCY; i++) {
|
init_reentrancy_cs(t);
|
||||||
t->file[i] = NULL;
|
|
||||||
t->lineno[i] = 0;
|
|
||||||
t->func[i] = NULL;
|
|
||||||
t->thread[i] = 0;
|
|
||||||
}
|
|
||||||
t->reentrancy = 0;
|
|
||||||
t->track = track;
|
t->track = track;
|
||||||
|
|
||||||
return pthread_mutex_init(&t->mutex, attr);
|
return pthread_mutex_init(&t->mutex, attr);
|
||||||
@@ -237,8 +266,10 @@ static inline int __ast_pthread_mutex_destroy(const char *filename, int lineno,
|
|||||||
case EBUSY:
|
case EBUSY:
|
||||||
__ast_mutex_logger("%s line %d (%s): Error: attempt to destroy locked mutex '%s'.\n",
|
__ast_mutex_logger("%s line %d (%s): Error: attempt to destroy locked mutex '%s'.\n",
|
||||||
filename, lineno, func, mutex_name);
|
filename, lineno, func, mutex_name);
|
||||||
|
reentrancy_lock_cs(t);
|
||||||
__ast_mutex_logger("%s line %d (%s): Error: '%s' was locked here.\n",
|
__ast_mutex_logger("%s line %d (%s): Error: '%s' was locked here.\n",
|
||||||
t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
|
t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
|
||||||
|
reentrancy_unlock_cs(t);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,9 +280,14 @@ static inline int __ast_pthread_mutex_destroy(const char *filename, int lineno,
|
|||||||
else
|
else
|
||||||
t->mutex = PTHREAD_MUTEX_INIT_VALUE;
|
t->mutex = PTHREAD_MUTEX_INIT_VALUE;
|
||||||
#endif
|
#endif
|
||||||
|
reentrancy_lock_cs(t);
|
||||||
t->file[0] = filename;
|
t->file[0] = filename;
|
||||||
t->lineno[0] = lineno;
|
t->lineno[0] = lineno;
|
||||||
t->func[0] = func;
|
t->func[0] = func;
|
||||||
|
t->reentrancy=0;
|
||||||
|
t->thread[0] = 0;
|
||||||
|
reentrancy_unlock_cs(t);
|
||||||
|
delete_reentrancy_cs(t);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -290,9 +326,11 @@ static inline int __ast_pthread_mutex_lock(const char *filename, int lineno, con
|
|||||||
if ((current - seconds) && (!((current - seconds) % 5))) {
|
if ((current - seconds) && (!((current - seconds) % 5))) {
|
||||||
__ast_mutex_logger("%s line %d (%s): Deadlock? waited %d sec for mutex '%s'?\n",
|
__ast_mutex_logger("%s line %d (%s): Deadlock? waited %d sec for mutex '%s'?\n",
|
||||||
filename, lineno, func, (int)(current - seconds), mutex_name);
|
filename, lineno, func, (int)(current - seconds), mutex_name);
|
||||||
|
reentrancy_lock_cs(t);
|
||||||
__ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
|
__ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
|
||||||
t->file[t->reentrancy-1], t->lineno[t->reentrancy-1],
|
t->file[t->reentrancy-1], t->lineno[t->reentrancy-1],
|
||||||
t->func[t->reentrancy-1], mutex_name);
|
t->func[t->reentrancy-1], mutex_name);
|
||||||
|
reentrancy_unlock_cs(t);
|
||||||
}
|
}
|
||||||
usleep(200);
|
usleep(200);
|
||||||
}
|
}
|
||||||
@@ -309,8 +347,7 @@ static inline int __ast_pthread_mutex_lock(const char *filename, int lineno, con
|
|||||||
#endif /* DETECT_DEADLOCKS */
|
#endif /* DETECT_DEADLOCKS */
|
||||||
|
|
||||||
if (!res) {
|
if (!res) {
|
||||||
if (t->track)
|
reentrancy_lock_cs(t);
|
||||||
ast_mark_lock_acquired();
|
|
||||||
if (t->reentrancy < AST_MAX_REENTRANCY) {
|
if (t->reentrancy < AST_MAX_REENTRANCY) {
|
||||||
t->file[t->reentrancy] = filename;
|
t->file[t->reentrancy] = filename;
|
||||||
t->lineno[t->reentrancy] = lineno;
|
t->lineno[t->reentrancy] = lineno;
|
||||||
@@ -321,6 +358,9 @@ static inline int __ast_pthread_mutex_lock(const char *filename, int lineno, con
|
|||||||
__ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
|
__ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
|
||||||
filename, lineno, func, mutex_name);
|
filename, lineno, func, mutex_name);
|
||||||
}
|
}
|
||||||
|
reentrancy_unlock_cs(t);
|
||||||
|
if (t->track)
|
||||||
|
ast_mark_lock_acquired();
|
||||||
} else {
|
} else {
|
||||||
if (t->track)
|
if (t->track)
|
||||||
ast_remove_lock_info(&t->mutex);
|
ast_remove_lock_info(&t->mutex);
|
||||||
@@ -350,8 +390,7 @@ static inline int __ast_pthread_mutex_trylock(const char *filename, int lineno,
|
|||||||
ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, &t->mutex);
|
ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, &t->mutex);
|
||||||
|
|
||||||
if (!(res = pthread_mutex_trylock(&t->mutex))) {
|
if (!(res = pthread_mutex_trylock(&t->mutex))) {
|
||||||
if (t->track)
|
reentrancy_lock_cs(t);
|
||||||
ast_mark_lock_acquired();
|
|
||||||
if (t->reentrancy < AST_MAX_REENTRANCY) {
|
if (t->reentrancy < AST_MAX_REENTRANCY) {
|
||||||
t->file[t->reentrancy] = filename;
|
t->file[t->reentrancy] = filename;
|
||||||
t->lineno[t->reentrancy] = lineno;
|
t->lineno[t->reentrancy] = lineno;
|
||||||
@@ -362,6 +401,9 @@ static inline int __ast_pthread_mutex_trylock(const char *filename, int lineno,
|
|||||||
__ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
|
__ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
|
||||||
filename, lineno, func, mutex_name);
|
filename, lineno, func, mutex_name);
|
||||||
}
|
}
|
||||||
|
reentrancy_unlock_cs(t);
|
||||||
|
if (t->track)
|
||||||
|
ast_mark_lock_acquired();
|
||||||
} else if (t->track) {
|
} else if (t->track) {
|
||||||
ast_remove_lock_info(&t->mutex);
|
ast_remove_lock_info(&t->mutex);
|
||||||
}
|
}
|
||||||
@@ -382,6 +424,7 @@ static inline int __ast_pthread_mutex_unlock(const char *filename, int lineno, c
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
reentrancy_lock_cs(t);
|
||||||
if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
|
if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
|
||||||
__ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
|
__ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
|
||||||
filename, lineno, func, mutex_name);
|
filename, lineno, func, mutex_name);
|
||||||
@@ -402,6 +445,7 @@ static inline int __ast_pthread_mutex_unlock(const char *filename, int lineno, c
|
|||||||
t->func[t->reentrancy] = NULL;
|
t->func[t->reentrancy] = NULL;
|
||||||
t->thread[t->reentrancy] = 0;
|
t->thread[t->reentrancy] = 0;
|
||||||
}
|
}
|
||||||
|
reentrancy_unlock_cs(t);
|
||||||
|
|
||||||
if (t->track)
|
if (t->track)
|
||||||
ast_remove_lock_info(&t->mutex);
|
ast_remove_lock_info(&t->mutex);
|
||||||
@@ -453,6 +497,7 @@ static inline int __ast_cond_wait(const char *filename, int lineno, const char *
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
reentrancy_lock_cs(t);
|
||||||
if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
|
if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
|
||||||
__ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
|
__ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
|
||||||
filename, lineno, func, mutex_name);
|
filename, lineno, func, mutex_name);
|
||||||
@@ -473,6 +518,7 @@ static inline int __ast_cond_wait(const char *filename, int lineno, const char *
|
|||||||
t->func[t->reentrancy] = NULL;
|
t->func[t->reentrancy] = NULL;
|
||||||
t->thread[t->reentrancy] = 0;
|
t->thread[t->reentrancy] = 0;
|
||||||
}
|
}
|
||||||
|
reentrancy_unlock_cs(t);
|
||||||
|
|
||||||
if (t->track)
|
if (t->track)
|
||||||
ast_remove_lock_info(&t->mutex);
|
ast_remove_lock_info(&t->mutex);
|
||||||
@@ -482,9 +528,7 @@ static inline int __ast_cond_wait(const char *filename, int lineno, const char *
|
|||||||
filename, lineno, func, strerror(res));
|
filename, lineno, func, strerror(res));
|
||||||
DO_THREAD_CRASH;
|
DO_THREAD_CRASH;
|
||||||
} else {
|
} else {
|
||||||
if (t->track)
|
reentrancy_lock_cs(t);
|
||||||
ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, &t->mutex);
|
|
||||||
|
|
||||||
if (t->reentrancy < AST_MAX_REENTRANCY) {
|
if (t->reentrancy < AST_MAX_REENTRANCY) {
|
||||||
t->file[t->reentrancy] = filename;
|
t->file[t->reentrancy] = filename;
|
||||||
t->lineno[t->reentrancy] = lineno;
|
t->lineno[t->reentrancy] = lineno;
|
||||||
@@ -495,6 +539,10 @@ static inline int __ast_cond_wait(const char *filename, int lineno, const char *
|
|||||||
__ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
|
__ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
|
||||||
filename, lineno, func, mutex_name);
|
filename, lineno, func, mutex_name);
|
||||||
}
|
}
|
||||||
|
reentrancy_unlock_cs(t);
|
||||||
|
|
||||||
|
if (t->track)
|
||||||
|
ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, &t->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
@@ -514,6 +562,7 @@ static inline int __ast_cond_timedwait(const char *filename, int lineno, const c
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
reentrancy_lock_cs(t);
|
||||||
if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
|
if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
|
||||||
__ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
|
__ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
|
||||||
filename, lineno, func, mutex_name);
|
filename, lineno, func, mutex_name);
|
||||||
@@ -534,6 +583,7 @@ static inline int __ast_cond_timedwait(const char *filename, int lineno, const c
|
|||||||
t->func[t->reentrancy] = NULL;
|
t->func[t->reentrancy] = NULL;
|
||||||
t->thread[t->reentrancy] = 0;
|
t->thread[t->reentrancy] = 0;
|
||||||
}
|
}
|
||||||
|
reentrancy_unlock_cs(t);
|
||||||
|
|
||||||
if (t->track)
|
if (t->track)
|
||||||
ast_remove_lock_info(&t->mutex);
|
ast_remove_lock_info(&t->mutex);
|
||||||
@@ -543,9 +593,7 @@ static inline int __ast_cond_timedwait(const char *filename, int lineno, const c
|
|||||||
filename, lineno, func, strerror(res));
|
filename, lineno, func, strerror(res));
|
||||||
DO_THREAD_CRASH;
|
DO_THREAD_CRASH;
|
||||||
} else {
|
} else {
|
||||||
if (t->track)
|
reentrancy_lock_cs(t);
|
||||||
ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, &t->mutex);
|
|
||||||
|
|
||||||
if (t->reentrancy < AST_MAX_REENTRANCY) {
|
if (t->reentrancy < AST_MAX_REENTRANCY) {
|
||||||
t->file[t->reentrancy] = filename;
|
t->file[t->reentrancy] = filename;
|
||||||
t->lineno[t->reentrancy] = lineno;
|
t->lineno[t->reentrancy] = lineno;
|
||||||
@@ -556,6 +604,10 @@ static inline int __ast_cond_timedwait(const char *filename, int lineno, const c
|
|||||||
__ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
|
__ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
|
||||||
filename, lineno, func, mutex_name);
|
filename, lineno, func, mutex_name);
|
||||||
}
|
}
|
||||||
|
reentrancy_unlock_cs(t);
|
||||||
|
|
||||||
|
if (t->track)
|
||||||
|
ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, &t->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|||||||
Reference in New Issue
Block a user