From ac170b682824bf58034b5a355960386d7c4126bf Mon Sep 17 00:00:00 2001 From: Lionel Nicolas Date: Sat, 12 Jun 2021 11:51:13 -0400 Subject: [PATCH 1/3] Remove unnecessary semicolon in janus mutex macros --- mutex.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/mutex.h b/mutex.h index d661628fda..fa2646a9d7 100644 --- a/mutex.h +++ b/mutex.h @@ -28,17 +28,17 @@ typedef pthread_mutex_t janus_mutex; /*! \brief Janus mutex destruction */ #define janus_mutex_destroy(a) pthread_mutex_destroy(a) /*! \brief Janus mutex lock without debug */ -#define janus_mutex_lock_nodebug(a) pthread_mutex_lock(a); +#define janus_mutex_lock_nodebug(a) pthread_mutex_lock(a) /*! \brief Janus mutex lock with debug (prints the line that locked a mutex) */ -#define janus_mutex_lock_debug(a) { JANUS_PRINT("[%s:%s:%d:lock] %p\n", __FILE__, __FUNCTION__, __LINE__, a); pthread_mutex_lock(a); }; +#define janus_mutex_lock_debug(a) { JANUS_PRINT("[%s:%s:%d:lock] %p\n", __FILE__, __FUNCTION__, __LINE__, a); pthread_mutex_lock(a); } /*! \brief Janus mutex lock wrapper (selective locking debug) */ -#define janus_mutex_lock(a) { if(!lock_debug) { janus_mutex_lock_nodebug(a); } else { janus_mutex_lock_debug(a); } }; +#define janus_mutex_lock(a) { if(!lock_debug) { janus_mutex_lock_nodebug(a); } else { janus_mutex_lock_debug(a); } } /*! \brief Janus mutex unlock without debug */ -#define janus_mutex_unlock_nodebug(a) pthread_mutex_unlock(a); +#define janus_mutex_unlock_nodebug(a) pthread_mutex_unlock(a) /*! \brief Janus mutex unlock with debug (prints the line that unlocked a mutex) */ -#define janus_mutex_unlock_debug(a) { JANUS_PRINT("[%s:%s:%d:unlock] %p\n", __FILE__, __FUNCTION__, __LINE__, a); pthread_mutex_unlock(a); }; +#define janus_mutex_unlock_debug(a) { JANUS_PRINT("[%s:%s:%d:unlock] %p\n", __FILE__, __FUNCTION__, __LINE__, a); pthread_mutex_unlock(a); } /*! \brief Janus mutex unlock wrapper (selective locking debug) */ -#define janus_mutex_unlock(a) { if(!lock_debug) { janus_mutex_unlock_nodebug(a); } else { janus_mutex_unlock_debug(a); } }; +#define janus_mutex_unlock(a) { if(!lock_debug) { janus_mutex_unlock_nodebug(a); } else { janus_mutex_unlock_debug(a); } } /*! \brief Janus condition implementation */ typedef pthread_cond_t janus_condition; @@ -72,17 +72,17 @@ typedef GMutex janus_mutex; /*! \brief Janus mutex destruction */ #define janus_mutex_destroy(a) g_mutex_clear(a) /*! \brief Janus mutex lock without debug */ -#define janus_mutex_lock_nodebug(a) g_mutex_lock(a); +#define janus_mutex_lock_nodebug(a) g_mutex_lock(a) /*! \brief Janus mutex lock with debug (prints the line that locked a mutex) */ -#define janus_mutex_lock_debug(a) { JANUS_PRINT("[%s:%s:%d:lock] %p\n", __FILE__, __FUNCTION__, __LINE__, a); g_mutex_lock(a); }; +#define janus_mutex_lock_debug(a) { JANUS_PRINT("[%s:%s:%d:lock] %p\n", __FILE__, __FUNCTION__, __LINE__, a); g_mutex_lock(a); } /*! \brief Janus mutex lock wrapper (selective locking debug) */ -#define janus_mutex_lock(a) { if(!lock_debug) { janus_mutex_lock_nodebug(a); } else { janus_mutex_lock_debug(a); } }; +#define janus_mutex_lock(a) { if(!lock_debug) { janus_mutex_lock_nodebug(a); } else { janus_mutex_lock_debug(a); } } /*! \brief Janus mutex unlock without debug */ -#define janus_mutex_unlock_nodebug(a) g_mutex_unlock(a); +#define janus_mutex_unlock_nodebug(a) g_mutex_unlock(a) /*! \brief Janus mutex unlock with debug (prints the line that unlocked a mutex) */ -#define janus_mutex_unlock_debug(a) { JANUS_PRINT("[%s:%s:%d:unlock] %p\n", __FILE__, __FUNCTION__, __LINE__, a); g_mutex_unlock(a); }; +#define janus_mutex_unlock_debug(a) { JANUS_PRINT("[%s:%s:%d:unlock] %p\n", __FILE__, __FUNCTION__, __LINE__, a); g_mutex_unlock(a); } /*! \brief Janus mutex unlock wrapper (selective locking debug) */ -#define janus_mutex_unlock(a) { if(!lock_debug) { janus_mutex_unlock_nodebug(a); } else { janus_mutex_unlock_debug(a); } }; +#define janus_mutex_unlock(a) { if(!lock_debug) { janus_mutex_unlock_nodebug(a); } else { janus_mutex_unlock_debug(a); } } /*! \brief Janus condition implementation */ typedef GCond janus_condition; From 1bfdc8f15843bb7d99681d101ba856617c07b537 Mon Sep 17 00:00:00 2001 From: Lionel Nicolas Date: Sat, 12 Jun 2021 11:51:49 -0400 Subject: [PATCH 2/3] Add janus_mutex_trylock macro --- mutex.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/mutex.h b/mutex.h index fa2646a9d7..269701fb72 100644 --- a/mutex.h +++ b/mutex.h @@ -33,6 +33,12 @@ typedef pthread_mutex_t janus_mutex; #define janus_mutex_lock_debug(a) { JANUS_PRINT("[%s:%s:%d:lock] %p\n", __FILE__, __FUNCTION__, __LINE__, a); pthread_mutex_lock(a); } /*! \brief Janus mutex lock wrapper (selective locking debug) */ #define janus_mutex_lock(a) { if(!lock_debug) { janus_mutex_lock_nodebug(a); } else { janus_mutex_lock_debug(a); } } +/*! \brief Janus mutex try lock without debug */ +#define janus_mutex_trylock_nodebug(a) { ret = pthread_mutex_trylock(a); } +/*! \brief Janus mutex try lock with debug (prints the line that tried to lock a mutex) */ +#define janus_mutex_trylock_debug(a) { JANUS_PRINT("[%s:%s:%d:trylock] %p\n", __FILE__, __FUNCTION__, __LINE__, a); ret = pthread_mutex_trylock(a); } +/*! \brief Janus mutex try lock wrapper (selective locking debug) */ +#define janus_mutex_trylock(a) ({ int ret; if(!lock_debug) { janus_mutex_trylock_nodebug(a); } else { janus_mutex_trylock_debug(a); } ret; }) /*! \brief Janus mutex unlock without debug */ #define janus_mutex_unlock_nodebug(a) pthread_mutex_unlock(a) /*! \brief Janus mutex unlock with debug (prints the line that unlocked a mutex) */ @@ -77,6 +83,12 @@ typedef GMutex janus_mutex; #define janus_mutex_lock_debug(a) { JANUS_PRINT("[%s:%s:%d:lock] %p\n", __FILE__, __FUNCTION__, __LINE__, a); g_mutex_lock(a); } /*! \brief Janus mutex lock wrapper (selective locking debug) */ #define janus_mutex_lock(a) { if(!lock_debug) { janus_mutex_lock_nodebug(a); } else { janus_mutex_lock_debug(a); } } +/*! \brief Janus mutex try lock without debug */ +#define janus_mutex_trylock_nodebug(a) { ret = g_mutex_trylock(a); } +/*! \brief Janus mutex try lock with debug (prints the line that tried to lock a mutex) */ +#define janus_mutex_trylock_debug(a) { JANUS_PRINT("[%s:%s:%d:trylock] %p\n", __FILE__, __FUNCTION__, __LINE__, a); ret = g_mutex_trylock(a); } +/*! \brief Janus mutex try lock wrapper (selective locking debug) */ +#define janus_mutex_trylock(a) ({ gboolean ret; if(!lock_debug) { janus_mutex_trylock_nodebug(a); } else { janus_mutex_trylock_debug(a); } ret; }) /*! \brief Janus mutex unlock without debug */ #define janus_mutex_unlock_nodebug(a) g_mutex_unlock(a) /*! \brief Janus mutex unlock with debug (prints the line that unlocked a mutex) */ From a049a23a8f1636a3d1ad4ba30c4a95f896bd89b1 Mon Sep 17 00:00:00 2001 From: Lionel Nicolas Date: Sat, 12 Jun 2021 12:02:53 -0400 Subject: [PATCH 3/3] Fix deadlock when destroying RTSP mountpoint while reconnecting --- plugins/janus_streaming.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/plugins/janus_streaming.c b/plugins/janus_streaming.c index 25c938c205..ceaa27f3aa 100644 --- a/plugins/janus_streaming.c +++ b/plugins/janus_streaming.c @@ -6489,14 +6489,18 @@ static int janus_streaming_rtsp_connect_to_server(janus_streaming_mountpoint *mp int asport = 0, asport_rtcp = 0; multiple_fds audio_fds = {-1, -1}; - if(g_atomic_int_get(&mp->destroyed)) { - curl_easy_cleanup(curl); - g_free(curldata->buffer); - g_free(curldata); - return -8; + while (!janus_mutex_trylock(&mountpoints_mutex)) { + if(g_atomic_int_get(&mp->destroyed)) { + JANUS_LOG(LOG_WARN, "[%s] Destroying mountpoint while trying to reconnect, aborting\n", mp->name); + curl_easy_cleanup(curl); + g_free(curldata->buffer); + g_free(curldata); + return -8; + } + + g_usleep(1000); } - janus_mutex_lock(&mountpoints_mutex); /* Parse both video and audio first before proceed to setup as curldata will be reused */ int vresult = -1; if(dovideo) {