Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix deadlock on mountpoint destroy during RTSP reconnect #2700

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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