summaryrefslogtreecommitdiff
path: root/include/asterisk
diff options
context:
space:
mode:
authorSean Bright <sean.bright@gmail.com>2017-03-29 11:11:51 -0400
committerSean Bright <sean.bright@gmail.com>2017-03-30 13:49:49 -0400
commitc9648f4690df2e8e23e60ffa70d4e9813246b62b (patch)
tree861db9e7e85430a117949e6a9275078b7e12dafe /include/asterisk
parent1d1309b1ed0da8e862e55d2fb0f021043d722ecd (diff)
astobj2: Prevent potential deadlocks with ao2_global_obj_release
The ao2_global_obj_release() function holds an exclusive lock on the global object while it is being dereferenced. Any destructors that run during this time that call ao2_global_obj_ref() will deadlock because a read lock is required. Instead, we make the global object inaccessible inside of the write lock and only dereference it once we have released the lock. This allows the affected destructors to fail gracefully. While this doesn't completely solve the referenced issue (the error message about not being able to create an IQ continues to be shown) it does solve the backtrace spew that accompanied it. ASTERISK-21009 #close Reported by: Marcello Ceschia Change-Id: Idf40ae136b5070dba22cb576ea8414fbc9939385
Diffstat (limited to 'include/asterisk')
-rw-r--r--include/asterisk/astobj2.h8
1 files changed, 4 insertions, 4 deletions
diff --git a/include/asterisk/astobj2.h b/include/asterisk/astobj2.h
index 4bd44db76..390e0ea1b 100644
--- a/include/asterisk/astobj2.h
+++ b/include/asterisk/astobj2.h
@@ -741,16 +741,16 @@ struct ao2_global_obj {
*/
#ifdef REF_DEBUG
#define ao2_t_global_obj_release(holder, tag) \
- __ao2_global_obj_release(&holder, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
+ __ao2_global_obj_replace_unref(&holder, NULL, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
#define ao2_global_obj_release(holder) \
- __ao2_global_obj_release(&holder, "", __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
+ __ao2_global_obj_replace_unref(&holder, NULL, "", __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
#else
#define ao2_t_global_obj_release(holder, tag) \
- __ao2_global_obj_release(&holder, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
+ __ao2_global_obj_replace_unref(&holder, NULL, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
#define ao2_global_obj_release(holder) \
- __ao2_global_obj_release(&holder, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
+ __ao2_global_obj_replace_unref(&holder, NULL, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
#endif
void __ao2_global_obj_release(struct ao2_global_obj *holder, const char *tag, const char *file, int line, const char *func, const char *name);