diff --git a/daemon/janus.c b/daemon/janus.c index 6ebe520b3..3982c5a71 100644 --- a/daemon/janus.c +++ b/daemon/janus.c @@ -1418,6 +1418,22 @@ static const char *janus_detach(struct websocket_message *wm, JsonReader *reader } +// janus_lock must be held +static void janus_session_cleanup(struct janus_session *session) { + GHashTableIter iter; + g_hash_table_iter_init(&iter, session->handles); + gpointer key; + while (g_hash_table_iter_next(&iter, &key, NULL)) { + uint64_t *handle_id = key; + struct janus_handle *handle = NULL; + g_hash_table_steal_extended(janus_handles, handle_id, NULL, (void **) &handle); + if (!handle) // bug? + continue; + janus_destroy_handle(handle); + } +} + + static const char *janus_destroy(struct websocket_message *wm, JsonReader *reader, JsonBuilder *builder, struct janus_session *session, int *retcode) @@ -1433,6 +1449,7 @@ static const char *janus_destroy(struct websocket_message *wm, JsonReader *reade if (ht_session != session) return "Sesssion ID not found"; // already removed/destroyed + janus_session_cleanup(session); obj_put(session); return NULL; diff --git a/t/auto-daemon-tests-websocket.py b/t/auto-daemon-tests-websocket.py index 4449b5099..0c49a2187 100644 --- a/t/auto-daemon-tests-websocket.py +++ b/t/auto-daemon-tests-websocket.py @@ -2860,10 +2860,55 @@ class TestVideoroom(unittest.TestCase): }, ) + # destroy session #2 + self.destroySession(token, session_2) + # success is received first + self.assertEqual(self._res, {"janus": "success", "session_id": session_2}) + + # followed by events in the other session + eventloop.run_until_complete(testIJson(self, 2)) + + self.assertEqual( + self._res, + { + "janus": "event", + "session_id": session_3, + "sender": pub_handle_2, + "plugindata": { + "plugin": "janus.plugin.videoroom", + "data": { + "videoroom": "event", + "room": room, + "unpublished": feed_1, + }, + }, + }, + ) + + eventloop.run_until_complete(testIJson(self, 2)) + + self.assertEqual( + self._res, + { + "janus": "event", + "session_id": session_3, + "sender": pub_handle_2, + "plugindata": { + "plugin": "janus.plugin.videoroom", + "data": { + "videoroom": "event", + "room": room, + "leaving": feed_1, + }, + }, + }, + ) + pub_sock_1.close() pub_sock_2.close() self.destroyVideoroom(token, session_1, control_handle, room) self.destroySession(token, session_1) + self.destroySession(token, session_3) def testVideoroomMute(self): (token, session, control_handle, room) = self.startVideoroom()