Index: main/utils.c
===================================================================
--- main/utils.c	(revision 108895)
+++ main/utils.c	(working copy)
@@ -754,9 +754,9 @@
 		pthread_mutex_lock(&lock_info->lock);
 		for (i = 0; str && i < lock_info->num_locks; i++) {
 			int j;
-			ast_mutex_t *lock;
+			struct ast_mutex_lock_info *lock;
 
-			ast_str_append(&str, 0, "=== ---> %sLock #%d (%s): %s %d %s %s %p (%d)\n", 
+			ast_str_append(&str, 0, "=== ---> %s Lock #%d (%s): %s %d %s %s %p (%d)\n", 
 				lock_info->locks[i].pending > 0 ? "Waiting for " : 
 					lock_info->locks[i].pending < 0 ? "Tried and failed to get " : "", i,
 				lock_info->locks[i].file, 
@@ -1568,3 +1568,113 @@
 #endif
 	return 0;
 }
Index: include/asterisk/lock.h
===================================================================
--- include/asterisk/lock.h	(revision 108895)
+++ include/asterisk/lock.h	(working copy)
@@ -108,16 +108,19 @@
 
 #include <errno.h>
 
-#define AST_MUTEX_INIT_VALUE { PTHREAD_MUTEX_INIT_VALUE, 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INIT_VALUE }
+#define AST_MUTEX_INIT_VALUE { {PTHREAD_MUTEX_INIT_VALUE}, 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INIT_VALUE }
 #define AST_MUTEX_INIT_VALUE_NOTRACKING \
-                             { PTHREAD_MUTEX_INIT_VALUE, 0, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INIT_VALUE }
+                             { {PTHREAD_MUTEX_INIT_VALUE}, 0, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INIT_VALUE }
 
 #define AST_MAX_REENTRANCY 10
 
 struct ast_channel;
 
-struct ast_mutex_info {
-	pthread_mutex_t mutex;
+struct ast_mutex_lock_info {
+	union {
+		pthread_mutex_t mutex;
+		pthread_rwlock_t rwlock;
+	};
 	/*! Track which thread holds this lock */
 	unsigned int track:1;
 	const char *file[AST_MAX_REENTRANCY];
@@ -128,12 +131,10 @@
 	pthread_mutex_t reentr_mutex;
 };
 
-typedef struct ast_mutex_info ast_mutex_t;
+typedef struct ast_mutex_lock_info ast_mutex_t;
 
 typedef pthread_cond_t ast_cond_t;
 
-static pthread_mutex_t empty_mutex;
-
 enum ast_lock_type {
 	AST_MUTEX,
 	AST_RDLOCK,
@@ -169,44 +170,40 @@
  */
 void ast_remove_lock_info(void *lock_addr);
 
-static void __attribute__((constructor)) init_empty_mutex(void)
-{
-	memset(&empty_mutex, 0, sizeof(empty_mutex));
-}
 
-static inline void ast_reentrancy_lock(ast_mutex_t *p_ast_mutex)
+static inline void ast_reentrancy_lock(struct ast_mutex_lock_info *p_ast_lock)
 {
-	pthread_mutex_lock(&p_ast_mutex->reentr_mutex);
+	pthread_mutex_lock(&p_ast_lock->reentr_mutex);
 }
 
-static inline void ast_reentrancy_unlock(ast_mutex_t *p_ast_mutex)
+static inline void ast_reentrancy_unlock(struct ast_mutex_lock_info *p_ast_lock)
 {
-	pthread_mutex_unlock(&p_ast_mutex->reentr_mutex);
+	pthread_mutex_unlock(&p_ast_lock->reentr_mutex);
 }
 
-static inline void ast_reentrancy_init(ast_mutex_t *p_ast_mutex)
+static inline void ast_reentrancy_init(struct ast_mutex_lock_info *p_ast_lock)
 {
 	int i;
 	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_lock->file[i] = NULL;
+		p_ast_lock->lineno[i] = 0;
+		p_ast_lock->func[i] = NULL;
+		p_ast_lock->thread[i] = 0;
 	}
 
-	p_ast_mutex->reentrancy = 0;
+	p_ast_lock->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_mutex_init(&p_ast_lock->reentr_mutex, &reentr_attr);
 	pthread_mutexattr_destroy(&reentr_attr);
 }
 
-static inline void delete_reentrancy_cs(ast_mutex_t * p_ast_mutex)
+static inline void delete_reentrancy_cs(struct ast_mutex_lock_info * p_ast_lock)
 {
-	pthread_mutex_destroy(&p_ast_mutex->reentr_mutex);
+	pthread_mutex_destroy(&p_ast_lock->reentr_mutex);
 }
 
 static inline int __ast_pthread_mutex_init(int track, const char *filename, int lineno, const char *func,
@@ -672,10 +669,11 @@
 
 typedef pthread_mutex_t ast_mutex_t;
 
-#define AST_MUTEX_INIT_VALUE			((ast_mutex_t) PTHREAD_MUTEX_INIT_VALUE)
-#define AST_MUTEX_INIT_VALUE_NOTRACKING		((ast_mutex_t) PTHREAD_MUTEX_INIT_VALUE)
+#define AST_MUTEX_INIT_VALUE	((ast_mutex_t) PTHREAD_MUTEX_INIT_VALUE)
+#define AST_MUTEX_INIT_VALUE_NOTRACKING \
+	((ast_mutex_t) PTHREAD_MUTEX_INIT_VALUE)
 
-#define ast_mutex_init_notracking(m)		ast_mutex_init(m)
+#define ast_mutex_init_notracking(m) ast_mutex_init(m)
 
 static inline int ast_mutex_init(ast_mutex_t *pmutex)
 {
@@ -760,14 +758,14 @@
 	else							\
 		ast_mutex_init_notracking(&mutex);		\
 }								\
-								\
 static void  __attribute__ ((destructor)) fini_##mutex(void)	\
 {								\
 	ast_mutex_destroy(&mutex);				\
 }
 #else /* !AST_MUTEX_INIT_W_CONSTRUCTORS */
 /* By default, use static initialization of mutexes. */ 
-#define __AST_MUTEX_DEFINE(scope, mutex, init_val, track)	scope ast_mutex_t mutex = init_val
+#define __AST_MUTEX_DEFINE(scope, mutex, init_val, track) \
+	scope ast_mutex_t mutex = init_val
 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
 
 #ifndef __CYGWIN__	/* temporary disabled for cygwin */
@@ -797,89 +795,104 @@
 #define pthread_create __use_ast_pthread_create_instead__
 #endif
 
+
 /*
  * Same as above, definitions of ast_rwlock_t for the various cases:
  * simple wrappers for the pthread equivalent in the non-debug case,
  * more sophisticated tracking in the debug case.
  */
 
-typedef pthread_rwlock_t ast_rwlock_t;
+#ifdef DEBUG_THREADS
 
 #ifdef HAVE_PTHREAD_RWLOCK_INITIALIZER
-#define AST_RWLOCK_INIT_VALUE PTHREAD_RWLOCK_INITIALIZER
+#define _RWLOCK_INIT_VALUE PTHREAD_RWLOCK_INITIALIZER
 #else
-#define AST_RWLOCK_INIT_VALUE { 0 }
+#define _RWLOCK_INIT_VALUE { 0 }
 #endif
 
-#ifdef DEBUG_THREADS
+#define AST_RWLOCK_INIT_VALUE \
+	{ {_RWLOCK_INIT_VALUE}, 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INIT_VALUE }
+#define AST_RWLOCK_INIT_VALUE_NOTRACKING \
+	{ {_RWLOCK_INIT_VALUE}, 0, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INIT_VALUE }
 
-#define ast_rwlock_init(rwlock)		__ast_rwlock_init(__FILE__, __LINE__, __PRETTY_FUNCTION__, #rwlock, rwlock)
-#define ast_rwlock_destroy(rwlock)	__ast_rwlock_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, #rwlock, rwlock)
-#define ast_rwlock_unlock(a)		_ast_rwlock_unlock(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
-#define ast_rwlock_rdlock(a)		_ast_rwlock_rdlock(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
-#define ast_rwlock_wrlock(a)		_ast_rwlock_wrlock(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
-#define ast_rwlock_tryrdlock(a)		_ast_rwlock_tryrdlock(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
-#define ast_rwlock_trywrlock(a) _ast_rwlock_trywrlock(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+typedef struct ast_mutex_lock_info ast_rwlock_t;
 
+#define ast_rwlock_init(rwlock) __ast_rwlock_init(1, __FILE__, __LINE__, __PRETTY_FUNCTION__, #rwlock, rwlock)
+#define ast_rwlock_init_notracking(rwlock) __ast_rwlock_init(0, __FILE__, __LINE__, __PRETTY_FUNCTION__, #rwlock, rwlock)
 
-static inline int __ast_rwlock_init(const char *filename, int lineno, const char *func, const char *rwlock_name, ast_rwlock_t *prwlock)
+static inline int __ast_rwlock_init(int track, const char *filename, int lineno, const char *func, const char *rwlock_name, ast_rwlock_t *t)
 {
 	int res;
 	pthread_rwlockattr_t attr;
 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
         int canlog = strcmp(filename, "logger.c");
 
-        if (*prwlock != ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
+	if (t->rwlock != ((pthread_rwlock_t) _RWLOCK_INIT_VALUE)) {
 		__ast_mutex_logger("%s line %d (%s): Warning: rwlock '%s' is already initialized.\n",
 				filename, lineno, func, rwlock_name);
 		return 0;
 	}
 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
+
+	ast_reentrancy_init(t);
+	t->track = track;
 	pthread_rwlockattr_init(&attr);
 
 #ifdef HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NP
 	pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NP);
 #endif
 
-	res = pthread_rwlock_init(prwlock, &attr);
+	res = pthread_rwlock_init(&t->rwlock, &attr);
 	pthread_rwlockattr_destroy(&attr);
 	return res;
 }
 
+#define ast_rwlock_destroy(rwlock) __ast_rwlock_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, #rwlock, rwlock)
 
-static inline int __ast_rwlock_destroy(const char *filename, int lineno, const char *func, const char *rwlock_name, ast_rwlock_t *prwlock)
+static inline int __ast_rwlock_destroy(const char *filename, int lineno, const char *func, const char *rwlock_name, ast_rwlock_t *t)
 {
 	int res;
 	int canlog = strcmp(filename, "logger.c");
 
 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
-	if (*prwlock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
+	if (t->rwlock == ((pthread_rwlock_t) _RWLOCK_INIT_VALUE)) {
 		__ast_mutex_logger("%s line %d (%s): Warning: rwlock '%s' is uninitialized.\n",
 				   filename, lineno, func, rwlock_name);
 		return 0;
 	}
 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
 	
-	if ((res = pthread_rwlock_destroy(prwlock)))
+	if ((res = pthread_rwlock_destroy(&t->rwlock)))
 		__ast_mutex_logger("%s line %d (%s): Error destroying rwlock %s: %s\n",
 				filename, lineno, func, rwlock_name, strerror(res));
 
+	ast_reentrancy_lock(t);
+	t->file[0] = filename;
+	t->lineno[0] = lineno;
+	t->func[0] = func;
+	t->reentrancy = 0;
+	t->thread[0] = 0;
+	ast_reentrancy_unlock(t);
+	delete_reentrancy_cs(t);
+
 	return res;
 }
 
+#define ast_rwlock_unlock(a) \
+	_ast_rwlock_unlock(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
-static inline int _ast_rwlock_unlock(ast_rwlock_t *lock, const char *name,
+static inline int _ast_rwlock_unlock(ast_rwlock_t *t, const char *name,
 	const char *file, int line, const char *func)
 {
 	int res;
 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
 	int canlog = strcmp(file, "logger.c");
 
-	if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
+	if ((t->rwlock) == ((pthread_rwlock_t) _RWLOCK_INIT_VALUE)) {
 		__ast_mutex_logger("%s line %d (%s): Warning: rwlock '%s' is uninitialized.\n",
 				   file, line, func, name);
-		res = __ast_rwlock_init(file, line, func, name, lock);
-		if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
+		res = __ast_rwlock_init(t->track, file, line, func, name, t);
+		if ((t->rwlock) == ((pthread_rwlock_t) _RWLOCK_INIT_VALUE)) {
 			__ast_mutex_logger("%s line %d (%s): Error: rwlock '%s' is uninitialized and unable to initialize.\n",
 					file, line, func, name);
 		}
@@ -887,88 +900,211 @@
 	}
 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
 	
-	res = pthread_rwlock_unlock(lock);
-	ast_remove_lock_info(lock);
+	ast_reentrancy_lock(t);
+	if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
+		__ast_mutex_logger("%s line %d (%s): attempted unlock rwlock '%s' without owning it!\n",
+					file, line, func, name);
+		__ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
+				t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], name);
+		DO_THREAD_CRASH;
+	}
+
+	if (--t->reentrancy < 0) {
+		__ast_mutex_logger("%s line %d (%s): rwlock '%s' freed more times than we've locked!\n",
+				file, line, func, name);
+		t->reentrancy = 0;
+	}
+
+	if (t->reentrancy < AST_MAX_REENTRANCY) {
+		t->file[t->reentrancy] = NULL;
+		t->lineno[t->reentrancy] = 0;
+		t->func[t->reentrancy] = NULL;
+		t->thread[t->reentrancy] = 0;
+	}
+	ast_reentrancy_unlock(t);
+
+	if (t->track)
+		ast_remove_lock_info(&t->rwlock);
+
+	if ((res = pthread_rwlock_unlock(&t->rwlock))) {
+		__ast_mutex_logger("%s line %d (%s): Error releasing rwlock: %s\n",
+				file, line, func, strerror(res));
+		DO_THREAD_CRASH;
+	}
+
 	return res;
 }
 
+#define ast_rwlock_rdlock(a) \
+	_ast_rwlock_rdlock(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
-static inline int _ast_rwlock_rdlock(ast_rwlock_t *lock, const char *name,
+static inline int _ast_rwlock_rdlock(ast_rwlock_t *t, const char *name,
 	const char *file, int line, const char *func)
 {
 	int res;
 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
 	int canlog = strcmp(file, "logger.c");
 	
-	if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
+	if ((t->rwlock) == ((pthread_rwlock_t) _RWLOCK_INIT_VALUE)) {
 		 /* Don't warn abount uninitialized lock.
 		  * Simple try to initialize it.
 		  * May be not needed in linux system.
 		  */
-		res = __ast_rwlock_init(file, line, func, name, lock);
-		if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
+		res = __ast_rwlock_init(t->track, file, line, func, name, t);
+		if ((t->rwlock) == ((pthread_rwlock_t) _RWLOCK_INIT_VALUE)) {
 			__ast_mutex_logger("%s line %d (%s): Error: rwlock '%s' is uninitialized and unable to initialize.\n",
 					file, line, func, name);
 			return res;
 		}
 	}
 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
+	if (t->track)
+		ast_store_lock_info(AST_RDLOCK, file, line, func, name, &t->rwlock);
+#ifdef DETECT_DEADLOCKS
+	{
+		time_t seconds = time(NULL);
+		time_t wait_time, reported_wait = 0;
+		do {
+			res = pthread_rwlock_tryrdlock(&t->rwlock);
+			if (res == EBUSY) {
+				wait_time = time(NULL) - seconds;
+				if (wait_time > reported_wait && (wait_time % 5) == 0) {
+					__ast_mutex_logger("%s line %d (%s): Deadlock? waited %d sec for readlock '%s'?\n",
+						file, line, func, (int)wait_time, name);
+					ast_reentrancy_lock(t);
+					__ast_mutex_logger("%s line %d (%s): '%s' was locked  here.\n",
+							t->file[t->reentrancy-1], t->lineno[t->reentrancy-1],
+							t->func[t->reentrancy-1], name);
+					ast_reentrancy_unlock(t);
+					reported_wait = wait_time;
+				}
+				usleep(200);
+			}
+		} while (res == EBUSY);
+	}
+#else /* !DETECT_DEADLOCKS */
+	res = pthread_rwlock_rdlock(&t->rwlock);
+#endif /* !DETECT_DEADLOCKS */
 	
-	ast_store_lock_info(AST_RDLOCK, file, line, func, name, lock);
-	res = pthread_rwlock_rdlock(lock);
-	if (!res)
-		ast_mark_lock_acquired(lock);
-	else
-		ast_remove_lock_info(lock);
+	if (!res) {
+		ast_reentrancy_lock(t);
+		if (t->reentrancy < AST_MAX_REENTRANCY) {
+			t->file[t->reentrancy] = file;
+			t->lineno[t->reentrancy] = line;
+			t->func[t->reentrancy] = func;
+			t->thread[t->reentrancy] = pthread_self();
+			t->reentrancy++;
+		} else {
+			__ast_mutex_logger("%s line %d (%s): read lock '%s' really deep reentrancy!\n",
+					file, line, func, name);
+		}
+		ast_reentrancy_unlock(t);
+		if (t->track)
+			ast_mark_lock_acquired(&t->rwlock);
+	} else {
+		if (t->track)
+			ast_remove_lock_info(&t->rwlock);
+		__ast_mutex_logger("%s line %d (%s): Error obtaining read lock: %s\n",
+				file, line, func, strerror(res));
+		DO_THREAD_CRASH;
+	}
+
 	return res;
 }
 
+#define ast_rwlock_wrlock(a) \
+	_ast_rwlock_wrlock(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
-static inline int _ast_rwlock_wrlock(ast_rwlock_t *lock, const char *name,
+static inline int _ast_rwlock_wrlock(ast_rwlock_t *t, const char *name,
 	const char *file, int line, const char *func)
 {
 	int res;
 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
 	int canlog = strcmp(file, "logger.c");
 	
-	if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
+	if ((t->rwlock) == ((pthread_rwlock_t) _RWLOCK_INIT_VALUE)) {
 		 /* Don't warn abount uninitialized lock.
 		  * Simple try to initialize it.
 		  * May be not needed in linux system.
 		  */
-		res = __ast_rwlock_init(file, line, func, name, lock);
-		if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
+		res = __ast_rwlock_init(t->track, file, line, func, name, t);
+		if ((t->rwlock) == ((pthread_rwlock_t) _RWLOCK_INIT_VALUE)) {
 			__ast_mutex_logger("%s line %d (%s): Error: rwlock '%s' is uninitialized and unable to initialize.\n",
 					file, line, func, name);
 			return res;
 		}
 	}
 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
+	if (t->track)
+		ast_store_lock_info(AST_WRLOCK, file, line, func, name, &t->rwlock);
+#ifdef DETECT_DEADLOCKS
+	{
+		time_t seconds = time(NULL);
+		time_t wait_time, reported_wait = 0;
+		do {
+			res = pthread_rwlock_trywrlock(&t->rwlock);
+			if (res == EBUSY) {
+				wait_time = time(NULL) - seconds;
+				if (wait_time > reported_wait && (wait_time % 5) == 0) {
+					__ast_mutex_logger("%s line %d (%s): Deadlock? waited %d sec for writelock '%s'?\n",
+						file, line, func, (int)wait_time, name);
+					ast_reentrancy_lock(t);
+					__ast_mutex_logger("%s line %d (%s): '%s' was locked  here.\n",
+							t->file[t->reentrancy-1], t->lineno[t->reentrancy-1],
+							t->func[t->reentrancy-1], name);
+					ast_reentrancy_unlock(t);
+					reported_wait = wait_time;
+				}
+				usleep(200);
+			}
+		} while (res == EBUSY);
+	}
+#else /* !DETECT_DEADLOCKS */
+	res = pthread_rwlock_wrlock(&t->rwlock);
+#endif /* !DETECT_DEADLOCKS */
 
-	ast_store_lock_info(AST_WRLOCK, file, line, func, name, lock);
-	res = pthread_rwlock_wrlock(lock);
-	if (!res)
-		ast_mark_lock_acquired(lock);
-	else
-		ast_remove_lock_info(lock);
+	if (!res) {
+		ast_reentrancy_lock(t);
+		if (t->reentrancy < AST_MAX_REENTRANCY) {
+			t->file[t->reentrancy] = file;
+			t->lineno[t->reentrancy] = line;
+			t->func[t->reentrancy] = func;
+			t->thread[t->reentrancy] = pthread_self();
+			t->reentrancy++;
+		} else {
+			__ast_mutex_logger("%s line %d (%s): write lock '%s' really deep reentrancy!\n",
+					file, line, func, name);
+		}
+		ast_reentrancy_unlock(t);
+		if (t->track)
+			ast_mark_lock_acquired(&t->rwlock);
+	} else {
+		if (t->track)
+			ast_remove_lock_info(&t->rwlock);
+		__ast_mutex_logger("%s line %d (%s): Error obtaining write lock: %s\n",
+				file, line, func, strerror(res));
+		DO_THREAD_CRASH;
+	}
 	return res;
 }
 
+#define ast_rwlock_tryrdlock(a) \
+	_ast_rwlock_tryrdlock(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
-static inline int _ast_rwlock_tryrdlock(ast_rwlock_t *lock, const char *name,
+static inline int _ast_rwlock_tryrdlock(ast_rwlock_t *t, const char *name,
 	const char *file, int line, const char *func)
 {
 	int res;
 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
 	int canlog = strcmp(file, "logger.c");
 	
-	if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
+	if ((t->rwlock) == ((pthread_rwlock_t) _RWLOCK_INIT_VALUE)) {
 		 /* Don't warn abount uninitialized lock.
 		  * Simple try to initialize it.
 		  * May be not needed in linux system.
 		  */
-		res = __ast_rwlock_init(file, line, func, name, lock);
-		if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
+		res = __ast_rwlock_init(t->track, file, line, func, name, t);
+		if ((t->rwlock) == ((pthread_rwlock_t) _RWLOCK_INIT_VALUE)) {
 			__ast_mutex_logger("%s line %d (%s): Error: rwlock '%s' is uninitialized and unable to initialize.\n",
 					file, line, func, name);
 			return res;
@@ -976,30 +1112,47 @@
 	}
 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
 
-	ast_store_lock_info(AST_RDLOCK, file, line, func, name, lock);
-	res = pthread_rwlock_tryrdlock(lock);
-	if (!res)
-		ast_mark_lock_acquired(lock);
-	else
-		ast_remove_lock_info(lock);
+	if (t->track)
+		ast_store_lock_info(AST_RDLOCK, file, line, func, name, &t->rwlock);
+	
+	if (!(res = pthread_rwlock_tryrdlock(&t->rwlock))) {
+		ast_reentrancy_lock(t);
+		if (t->reentrancy < AST_MAX_REENTRANCY) {
+			t->file[t->reentrancy] = file;
+			t->lineno[t->reentrancy] = line;
+			t->func[t->reentrancy] = func;
+			t->thread[t->reentrancy] = pthread_self();
+			t->reentrancy++;
+		} else {
+			__ast_mutex_logger("%s line %d (%s): read lock '%s' really deep reentrancy!\n",
+					file, line, func, name);
+		}
+		ast_reentrancy_unlock(t);
+		if (t->track)
+			ast_mark_lock_acquired(&t->rwlock);
+	} else if (t->track) {
+		ast_mark_lock_failed(&t->rwlock);
+	}
 	return res;
 }
 
+#define ast_rwlock_trywrlock(a) \
+	_ast_rwlock_trywrlock(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
-static inline int _ast_rwlock_trywrlock(ast_rwlock_t *lock, const char *name,
+static inline int _ast_rwlock_trywrlock(ast_rwlock_t *t, const char *name,
 	const char *file, int line, const char *func)
 {
 	int res;
 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
 	int canlog = strcmp(file, "logger.c");
 	
-	if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
+	if ((t->rwlock) == ((pthread_rwlock_t) _RWLOCK_INIT_VALUE)) {
 		 /* Don't warn abount uninitialized lock.
 		  * Simple try to initialize it.
 		  * May be not needed in linux system.
 		  */
-		res = __ast_rwlock_init(file, line, func, name, lock);
-		if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
+		res = __ast_rwlock_init(t->track, file, line, func, name, t);
+		if ((t->rwlock) == ((pthread_rwlock_t) _RWLOCK_INIT_VALUE)) {
 			__ast_mutex_logger("%s line %d (%s): Error: rwlock '%s' is uninitialized and unable to initialize.\n",
 					file, line, func, name);
 			return res;
@@ -1007,17 +1160,42 @@
 	}
 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
 
-	ast_store_lock_info(AST_WRLOCK, file, line, func, name, lock);
-	res = pthread_rwlock_trywrlock(lock);
-	if (!res)
-		ast_mark_lock_acquired(lock);
-	else
-		ast_remove_lock_info(lock);
+	if (t->track)
+		ast_store_lock_info(AST_WRLOCK, file, line, func, name, &t->rwlock);
+	
+	if (!(res = pthread_rwlock_trywrlock(&t->rwlock))) {
+		ast_reentrancy_lock(t);
+		if (t->reentrancy < AST_MAX_REENTRANCY) {
+			t->file[t->reentrancy] = file;
+			t->lineno[t->reentrancy] = line;
+			t->func[t->reentrancy] = func;
+			t->thread[t->reentrancy] = pthread_self();
+			t->reentrancy++;
+		} else {
+			__ast_mutex_logger("%s line %d (%s): write lock '%s' really deep reentrancy!\n",
+					file, line, func, name);
+		}
+		ast_reentrancy_unlock(t);
+		if (t->track)
+			ast_mark_lock_acquired(&t->rwlock);
+	} else if (t->track) {
+		ast_mark_lock_failed(&t->rwlock);
+	}
 	return res;
 }
 
 #else /* !DEBUG_THREADS */
 
+#ifdef HAVE_PTHREAD_RWLOCK_INITIALIZER
+#define AST_RWLOCK_INIT_VALUE PTHREAD_RWLOCK_INITIALIZER
+#else
+#define AST_RWLOCK_INIT_VALUE { 0 }
+#endif
+
+typedef pthread_rwlock_t ast_rwlock_t;
+
+#define ast_rwlock_init_notracking(rwl) ast_rwlock_init(rwl)
+	
 static inline int ast_rwlock_init(ast_rwlock_t *prwlock)
 {
 	int res;
@@ -1067,23 +1245,27 @@
 
 /* Statically declared read/write locks */
 
-#ifndef HAVE_PTHREAD_RWLOCK_INITIALIZER
-#define __AST_RWLOCK_DEFINE(scope, rwlock)			\
-        scope ast_rwlock_t rwlock;				\
-static void  __attribute__ ((constructor)) init_##rwlock(void)	\
-{								\
-        ast_rwlock_init(&rwlock);				\
-}								\
-								\
-static void  __attribute__ ((destructor)) fini_##rwlock(void)	\
-{								\
-        ast_rwlock_destroy(&rwlock);				\
+#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
+#define __AST_RWLOCK_DEFINE(scope, rwlock, init_val, track) \
+        scope ast_rwlock_t rwlock = init_val; \
+static void  __attribute__ ((constructor)) init_##rwlock(void) \
+{ \
+	if (track) \
+        	ast_rwlock_init(&rwlock); \
+	else \
+		ast_rwlock_init_notracking(&rwlock); \
+} \
+static void  __attribute__ ((destructor)) fini_##rwlock(void) \
+{ \
+        ast_rwlock_destroy(&rwlock); \
 }
 #else
-#define __AST_RWLOCK_DEFINE(scope, rwlock)	scope ast_rwlock_t rwlock = AST_RWLOCK_INIT_VALUE
+#define __AST_RWLOCK_DEFINE(scope, rwlock, init_val, track) \
+        scope ast_rwlock_t rwlock = init_val
 #endif
 
-#define AST_RWLOCK_DEFINE_STATIC(rwlock) __AST_RWLOCK_DEFINE(static, rwlock)
+#define AST_RWLOCK_DEFINE_STATIC(rwlock) __AST_RWLOCK_DEFINE(static, rwlock, AST_RWLOCK_INIT_VALUE, 1)
+#define AST_RWLOCK_DEFINE_STATIC_NOTRACKING(rwlock) __AST_RWLOCK_DEFINE(static, rwlock, AST_RWLOCK_INIT_VALUE_NOTRACKING, 0)
 
 /*
  * Support for atomic instructions.
