Skip to content

Commit

Permalink
Fix deadlock on mountpoint destroy during RTSP reconnect (#2700)
Browse files Browse the repository at this point in the history
  • Loading branch information
lionelnicolas committed Jun 15, 2021
1 parent a467088 commit 1d50e06
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 18 deletions.
36 changes: 24 additions & 12 deletions mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,23 @@ 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 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);
#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;
Expand Down Expand Up @@ -72,17 +78,23 @@ 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 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);
#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;
Expand Down
16 changes: 10 additions & 6 deletions plugins/janus_streaming.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit 1d50e06

Please sign in to comment.