diff --git a/src/ice.c b/src/ice.c index 09cdcfd242..2c1bb9c32b 100644 --- a/src/ice.c +++ b/src/ice.c @@ -396,6 +396,12 @@ gboolean janus_ice_event_get_combine_media_stats(void) { return janus_ice_event_combine_media_stats; } +/* Number of active PeerConnection (for stats) */ +static volatile gint pc_num = 0; +int janus_ice_get_peerconnection_num(void) { + return g_atomic_int_get(&pc_num); +} + /* RTP/RTCP port range */ static uint16_t rtp_range_min = 0; static uint16_t rtp_range_max = 0; @@ -1617,6 +1623,8 @@ void janus_ice_webrtc_hangup(janus_ice_handle *handle, const char *reason) { #endif g_main_context_wakeup(handle->mainctx); } + if(g_atomic_int_dec_and_test(&handle->has_pc)) + g_atomic_int_dec_and_test(&pc_num); } static void janus_ice_webrtc_free(janus_ice_handle *handle) { @@ -5186,4 +5194,6 @@ void janus_ice_dtls_handshake_done(janus_ice_handle *handle) { janus_events_notify_handlers(JANUS_EVENT_TYPE_WEBRTC, JANUS_EVENT_SUBTYPE_WEBRTC_STATE, session->session_id, handle->handle_id, handle->opaque_id, info); } + g_atomic_int_set(&handle->has_pc, 1); + g_atomic_int_inc(&pc_num); } diff --git a/src/ice.h b/src/ice.h index 36509770cd..c65eb1a486 100644 --- a/src/ice.h +++ b/src/ice.h @@ -205,6 +205,9 @@ void janus_ice_set_event_stats_period(int period); /*! \brief Method to get the current event handler statistics period (see above) * @returns The current event handler stats period */ int janus_ice_get_event_stats_period(void); +/*! \brief Method to get the number of active PeerConnection (for stats) + * @returns The current number of active PeerConnections */ +int janus_ice_get_peerconnection_num(void); /*! \brief Method to define wether the media stats shall be dispatched in one event (true) or in dedicated single events (false - default) * @param[in] combine_media_stats_to_one_event true to combine media statistics in on event or false to send dedicated events */ @@ -402,6 +405,8 @@ struct janus_ice_handle { janus_text2pcap *text2pcap; /*! \brief Mutex to lock/unlock the ICE session */ janus_mutex mutex; + /*! \brief Atomic flag to check whether a PeerConnection was established */ + volatile gint has_pc; /*! \brief Whether a close_pc was requested recently on the PeerConnection */ volatile gint closepc; /*! \brief Atomic flag to check if this instance has been destroyed */ diff --git a/src/janus.c b/src/janus.c index fc8d705f52..9e993fa48e 100644 --- a/src/janus.c +++ b/src/janus.c @@ -641,6 +641,9 @@ static janus_mutex sessions_mutex; static GHashTable *sessions = NULL; static GMainContext *sessions_watchdog_context = NULL; +/* Counters */ +static volatile gint sessions_num = 0; +static volatile gint handles_num = 0; static void janus_ice_handle_dereference(janus_ice_handle *handle) { if(handle) @@ -744,6 +747,20 @@ static gpointer janus_sessions_watchdog(gpointer user_data) { return NULL; } +static gboolean janus_status_sessions(gpointer user_data) { + if(janus_events_is_enabled()) { + json_t *info = json_object(); + json_object_set_new(info, "status", json_string("update")); + json_t *details = json_object(); + json_object_set_new(details, "sessions", json_integer(g_atomic_int_get(&sessions_num))); + json_object_set_new(details, "handles", json_integer(g_atomic_int_get(&handles_num))); + json_object_set_new(details, "peerconnections", json_integer(janus_ice_get_peerconnection_num())); + json_object_set_new(details, "stats-period", json_integer(janus_ice_get_event_stats_period())); + json_object_set_new(info, "info", details); + janus_events_notify_handlers(JANUS_EVENT_TYPE_CORE, JANUS_EVENT_SUBTYPE_CORE_STARTUP, 0, info); + } + return TRUE; +} janus_session *janus_session_create(guint64 session_id) { janus_session *session = NULL; @@ -772,6 +789,7 @@ janus_session *janus_session_create(guint64 session_id) { janus_mutex_init(&session->mutex); janus_mutex_lock(&sessions_mutex); g_hash_table_insert(sessions, janus_uint64_dup(session->session_id), session); + g_atomic_int_inc(&sessions_num); janus_mutex_unlock(&sessions_mutex); return session; } @@ -840,13 +858,15 @@ void janus_session_handles_insert(janus_session *session, janus_ice_handle *hand session->ice_handles = g_hash_table_new_full(g_int64_hash, g_int64_equal, (GDestroyNotify)g_free, (GDestroyNotify)janus_ice_handle_dereference); janus_refcount_increase(&handle->ref); g_hash_table_insert(session->ice_handles, janus_uint64_dup(handle->handle_id), handle); + g_atomic_int_inc(&handles_num); janus_mutex_unlock(&session->mutex); } gint janus_session_handles_remove(janus_session *session, janus_ice_handle *handle) { janus_mutex_lock(&session->mutex); gint error = janus_ice_handle_destroy(session, handle); - g_hash_table_remove(session->ice_handles, &handle->handle_id); + if(g_hash_table_remove(session->ice_handles, &handle->handle_id)) + g_atomic_int_dec_and_test(&handles_num); janus_mutex_unlock(&session->mutex); return error; } @@ -864,6 +884,7 @@ void janus_session_handles_clear(janus_session *session) { continue; janus_ice_handle_destroy(session, handle); g_hash_table_iter_remove(&iter); + g_atomic_int_dec_and_test(&handles_num); } } janus_mutex_unlock(&session->mutex); @@ -1260,7 +1281,8 @@ int janus_process_incoming_request(janus_request *request) { goto jsondone; } janus_mutex_lock(&sessions_mutex); - g_hash_table_remove(sessions, &session->session_id); + if(g_hash_table_remove(sessions, &session->session_id)) + g_atomic_int_dec_and_test(&sessions_num); janus_mutex_unlock(&sessions_mutex); /* Notify the source that the session has been destroyed */ janus_request *source = janus_session_get_request(session); @@ -2826,7 +2848,8 @@ int janus_process_incoming_admin_request(janus_request *request) { /* Session-related */ if(!strcasecmp(message_text, "destroy_session")) { janus_mutex_lock(&sessions_mutex); - g_hash_table_remove(sessions, &session->session_id); + if(g_hash_table_remove(sessions, &session->session_id)) + g_atomic_int_dec_and_test(&sessions_num); janus_mutex_unlock(&sessions_mutex); /* Notify the source that the session has been destroyed */ janus_request *source = janus_session_get_request(session); @@ -5587,6 +5610,11 @@ gint main(int argc, char *argv[]) { janus_options_destroy(); exit(1); } + /* Send a status event every once in a while */ + GSource *timeout_source = g_timeout_source_new_seconds(15); + g_source_set_callback(timeout_source, janus_status_sessions, sessions_watchdog_context, NULL); + g_source_attach(timeout_source, sessions_watchdog_context); + g_source_unref(timeout_source); } /* Load plugins */