Skip to content

Commit feb4255

Browse files
properly cleanup pointers on destrcution
1 parent 639823e commit feb4255

3 files changed

Lines changed: 22 additions & 5 deletions

File tree

include/livekit/room.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,13 +146,15 @@ class LIVEKIT_API Room {
146146
/// - published tracks (audio/video/screen)
147147
/// - identity, SID, metadata
148148
/// - publishing/unpublishing operations
149-
/// @return Non-null pointer after successful connect().
149+
/// @return Non-null pointer while connected; nullptr before connect, after
150+
/// room end-of-stream teardown, or when the room is destroyed.
150151
LocalParticipant* localParticipant() const;
151152

152153
/// Look up a remote participant by identity.
153154
///
154155
/// @param identity The participant’s identity string (not SID)
155-
/// @return Pointer to RemoteParticipant if present, otherwise nullptr.
156+
/// @return Pointer to RemoteParticipant if present, otherwise nullptr (also
157+
/// nullptr after room teardown or when the room is destroyed).
156158
/// RemoteParticipant contains:
157159
/// - identity/name/metadata
158160
/// - track publications
@@ -163,7 +165,7 @@ class LIVEKIT_API Room {
163165
///
164166
/// @return Vector of non-null pointers to the current remote participants.
165167
/// The pointers are owned by the Room and remain valid until the
166-
/// corresponding participant disconnects.
168+
/// corresponding participant disconnects or the room is torn down.
167169
std::vector<RemoteParticipant*> remoteParticipants() const;
168170

169171
/// Returns the current connection state of the room.

src/room.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,19 @@ Room::~Room() {
8282

8383
int listener_to_remove = 0;
8484
std::unique_ptr<LocalParticipant> local_participant_to_cleanup;
85+
std::unordered_map<std::string, std::shared_ptr<RemoteParticipant>> remote_participants_to_cleanup;
8586
{
8687
const std::scoped_lock<std::mutex> g(lock_);
8788
listener_to_remove = listener_id_;
8889
listener_id_ = 0;
89-
// Move local participant out for cleanup outside the lock
90+
connection_state_ = ConnectionState::Disconnected;
91+
// Move participant state out so accessors return nullptr during teardown.
9092
local_participant_to_cleanup = std::move(local_participant_);
93+
remote_participants_to_cleanup = std::move(remote_participants_);
94+
room_handle_.reset();
95+
e2ee_manager_.reset();
96+
text_stream_readers_.clear();
97+
byte_stream_readers_.clear();
9198
}
9299

93100
// Shutdown local participant (unregisters RPC handlers, etc.) before
@@ -1158,7 +1165,11 @@ void Room::onEvent(const FfiEvent& event) {
11581165
FfiClient::instance().removeListener(listener_to_remove);
11591166
}
11601167

1161-
// Old state will be destroyed here when going out of scope
1168+
if (old_local_participant) {
1169+
old_local_participant->shutdown();
1170+
}
1171+
1172+
// old_* state is destroyed here when going out of scope
11621173

11631174
const RoomEosEvent ev;
11641175
if (delegate_snapshot) {

src/tests/unit/test_room.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ TEST_F(RoomTest, ConnectWithoutInitialize) {
3333
Room room;
3434
bool result = room.connect("wss://localhost:7880", "test", livekit::RoomOptions());
3535
EXPECT_FALSE(result) << "Connecting without initializing should return false";
36+
EXPECT_EQ(room.localParticipant(), nullptr)
37+
<< "Local participant should be null after failed connect";
38+
EXPECT_TRUE(room.remoteParticipants().empty())
39+
<< "Remote participants should be empty after failed connect";
3640
}
3741

3842
TEST_F(RoomTest, CreateRoom) {

0 commit comments

Comments
 (0)