Skip to content

Commit

Permalink
Merge pull request #291 from manuguerra/cpu-usage-drop-when-connectio…
Browse files Browse the repository at this point in the history
…n-closes

Drop CPU usage as soon as connection is closed
  • Loading branch information
markandrus committed Dec 27, 2016
2 parents f5d13d1 + 5d22cd8 commit 987b25a
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 29 deletions.
8 changes: 6 additions & 2 deletions lib/peerconnection.js
Expand Up @@ -370,8 +370,12 @@ function RTCPeerConnection(configuration, constraints) {
args: [label, dataChannelDict]
});

dataChannels[label] = channel;
return new RTCDataChannel(channel);
// channel will be undefined if dataChannel was closed before calling this function
// (see peerconnection.cc)
if (channel) {
dataChannels[label] = channel;
return new RTCDataChannel(channel);
}
};

this.getStats = function getStats(onSuccess, onFailure) {
Expand Down
105 changes: 79 additions & 26 deletions src/peerconnection.cc
Expand Up @@ -340,7 +340,9 @@ NAN_METHOD(PeerConnection::CreateOffer) {

PeerConnection* self = Nan::ObjectWrap::Unwrap<PeerConnection>(info.This());

self->_jinglePeerConnection->CreateOffer(self->_createOfferObserver, nullptr);
if (self->_jinglePeerConnection != nullptr) {
self->_jinglePeerConnection->CreateOffer(self->_createOfferObserver, nullptr);
}

TRACE_END;
info.GetReturnValue().Set(Nan::Undefined());
Expand All @@ -351,7 +353,9 @@ NAN_METHOD(PeerConnection::CreateAnswer) {

PeerConnection* self = Nan::ObjectWrap::Unwrap<PeerConnection>(info.This());

self->_jinglePeerConnection->CreateAnswer(self->_createAnswerObserver, nullptr);
if (self->_jinglePeerConnection != nullptr) {
self->_jinglePeerConnection->CreateAnswer(self->_createAnswerObserver, nullptr);
}

TRACE_END;
info.GetReturnValue().Set(Nan::Undefined());
Expand All @@ -361,16 +365,19 @@ NAN_METHOD(PeerConnection::SetLocalDescription) {
TRACE_CALL;

PeerConnection* self = Nan::ObjectWrap::Unwrap<PeerConnection>(info.This());
Local<Object> desc = Local<Object>::Cast(info[0]);
String::Utf8Value _type(desc->Get(Nan::New("type").ToLocalChecked())->ToString());
String::Utf8Value _sdp(desc->Get(Nan::New("sdp").ToLocalChecked())->ToString());

std::string type = *_type;
std::string sdp = *_sdp;
webrtc::SdpParseError error;
webrtc::SessionDescriptionInterface* sdi = webrtc::CreateSessionDescription(type, sdp, &error);
if (self->_jinglePeerConnection != nullptr) {
Local<Object> desc = Local<Object>::Cast(info[0]);
String::Utf8Value _type(desc->Get(Nan::New("type").ToLocalChecked())->ToString());
String::Utf8Value _sdp(desc->Get(Nan::New("sdp").ToLocalChecked())->ToString());

self->_jinglePeerConnection->SetLocalDescription(self->_setLocalDescriptionObserver, sdi);
std::string type = *_type;
std::string sdp = *_sdp;
webrtc::SdpParseError error;
webrtc::SessionDescriptionInterface* sdi = webrtc::CreateSessionDescription(type, sdp, &error);

self->_jinglePeerConnection->SetLocalDescription(self->_setLocalDescriptionObserver, sdi);
}

TRACE_END;
info.GetReturnValue().Set(Nan::Undefined());
Expand All @@ -380,16 +387,19 @@ NAN_METHOD(PeerConnection::SetRemoteDescription) {
TRACE_CALL;

PeerConnection* self = Nan::ObjectWrap::Unwrap<PeerConnection>(info.This());
Local<Object> desc = Local<Object>::Cast(info[0]);
String::Utf8Value _type(desc->Get(Nan::New("type").ToLocalChecked())->ToString());
String::Utf8Value _sdp(desc->Get(Nan::New("sdp").ToLocalChecked())->ToString());

std::string type = *_type;
std::string sdp = *_sdp;
webrtc::SdpParseError error;
webrtc::SessionDescriptionInterface* sdi = webrtc::CreateSessionDescription(type, sdp, &error);
if (self->_jinglePeerConnection != nullptr) {
Local<Object> desc = Local<Object>::Cast(info[0]);
String::Utf8Value _type(desc->Get(Nan::New("type").ToLocalChecked())->ToString());
String::Utf8Value _sdp(desc->Get(Nan::New("sdp").ToLocalChecked())->ToString());

self->_jinglePeerConnection->SetRemoteDescription(self->_setRemoteDescriptionObserver, sdi);
std::string type = *_type;
std::string sdp = *_sdp;
webrtc::SdpParseError error;
webrtc::SessionDescriptionInterface* sdi = webrtc::CreateSessionDescription(type, sdp, &error);

self->_jinglePeerConnection->SetRemoteDescription(self->_setRemoteDescriptionObserver, sdi);
}

TRACE_END;
info.GetReturnValue().Set(Nan::Undefined());
Expand All @@ -410,7 +420,7 @@ NAN_METHOD(PeerConnection::AddIceCandidate) {
webrtc::SdpParseError sdpParseError;
webrtc::IceCandidateInterface* ci = webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, candidate, &sdpParseError);

if (self->_jinglePeerConnection->AddIceCandidate(ci)) {
if (self->_jinglePeerConnection != nullptr && self->_jinglePeerConnection->AddIceCandidate(ci)) {
self->QueueEvent(PeerConnection::ADD_ICE_CANDIDATE_SUCCESS, static_cast<void*>(nullptr));
} else {
PeerConnection::ErrorEvent* data = new PeerConnection::ErrorEvent(std::string("Failed to set ICE candidate."));
Expand All @@ -425,6 +435,12 @@ NAN_METHOD(PeerConnection::CreateDataChannel) {
TRACE_CALL;

PeerConnection* self = Nan::ObjectWrap::Unwrap<PeerConnection>(info.This());

if (self->_jinglePeerConnection == nullptr) {
info.GetReturnValue().Set(Nan::Undefined());
return;
}

String::Utf8Value label(info[0]->ToString());
Handle<Object> dataChannelDict = Handle<Object>::Cast(info[1]);

Expand Down Expand Up @@ -487,7 +503,12 @@ NAN_METHOD(PeerConnection::GetStats) {
rtc::scoped_refptr<StatsObserver> statsObserver =
new rtc::RefCountedObject<StatsObserver>(self, onSuccess);

if (!self->_jinglePeerConnection->GetStats(statsObserver, nullptr,
if (self->_jinglePeerConnection == nullptr) {
Local<Value> argv[] = {
Nan::New("data channel is closed").ToLocalChecked()
};
onFailure->Call(1, argv);
} else if (!self->_jinglePeerConnection->GetStats(statsObserver, nullptr,
webrtc::PeerConnectionInterface::kStatsOutputLevelStandard)) {
// TODO: Include error?
Local<Value> argv[] = {
Expand All @@ -510,7 +531,13 @@ NAN_METHOD(PeerConnection::Close) {
TRACE_CALL;

PeerConnection* self = Nan::ObjectWrap::Unwrap<PeerConnection>(info.This());
self->_jinglePeerConnection->Close();

if (self->_jinglePeerConnection != nullptr) {
self->_jinglePeerConnection->Close();
}

self->_jinglePeerConnection = nullptr;
self->_jinglePeerConnectionFactory = nullptr;

TRACE_END;
info.GetReturnValue().Set(Nan::Undefined());
Expand All @@ -520,7 +547,11 @@ NAN_GETTER(PeerConnection::GetLocalDescription) {
TRACE_CALL;

PeerConnection* self = Nan::ObjectWrap::Unwrap<PeerConnection>(info.Holder());
const webrtc::SessionDescriptionInterface* sdi = self->_jinglePeerConnection->local_description();
const webrtc::SessionDescriptionInterface* sdi = nullptr;

if ( self->_jinglePeerConnection != nullptr) {
sdi = self->_jinglePeerConnection->local_description();
}

Handle<Value> value;
if (nullptr == sdi) {
Expand All @@ -543,7 +574,11 @@ NAN_GETTER(PeerConnection::GetRemoteDescription) {
TRACE_CALL;

PeerConnection* self = Nan::ObjectWrap::Unwrap<PeerConnection>(info.Holder());
const webrtc::SessionDescriptionInterface* sdi = self->_jinglePeerConnection->remote_description();
const webrtc::SessionDescriptionInterface* sdi = nullptr;

if ( self->_jinglePeerConnection != nullptr) {
sdi = self->_jinglePeerConnection->remote_description();
}

Handle<Value> value;
if (nullptr == sdi) {
Expand All @@ -567,7 +602,13 @@ NAN_GETTER(PeerConnection::GetSignalingState) {

PeerConnection* self = Nan::ObjectWrap::Unwrap<PeerConnection>(info.Holder());

webrtc::PeerConnectionInterface::SignalingState state = self->_jinglePeerConnection->signaling_state();
webrtc::PeerConnectionInterface::SignalingState state;

if (self->_jinglePeerConnection != nullptr) {
state = self->_jinglePeerConnection->signaling_state();
} else {
state = webrtc::PeerConnectionInterface::kClosed;
}

TRACE_END;
info.GetReturnValue().Set(Nan::New<Number>(state));
Expand All @@ -578,7 +619,13 @@ NAN_GETTER(PeerConnection::GetIceConnectionState) {

PeerConnection* self = Nan::ObjectWrap::Unwrap<PeerConnection>(info.Holder());

webrtc::PeerConnectionInterface::IceConnectionState state = self->_jinglePeerConnection->ice_connection_state();
webrtc::PeerConnectionInterface::IceConnectionState state;

if (self->_jinglePeerConnection != nullptr) {
state = self->_jinglePeerConnection->ice_connection_state();
} else {
state = webrtc::PeerConnectionInterface::kIceConnectionClosed;
}

TRACE_END;
info.GetReturnValue().Set(Nan::New<Number>(state));
Expand All @@ -589,7 +636,13 @@ NAN_GETTER(PeerConnection::GetIceGatheringState) {

PeerConnection* self = Nan::ObjectWrap::Unwrap<PeerConnection>(info.Holder());

webrtc::PeerConnectionInterface::IceGatheringState state = self->_jinglePeerConnection->ice_gathering_state();
webrtc::PeerConnectionInterface::IceGatheringState state;

if (self->_jinglePeerConnection != nullptr) {
state = self->_jinglePeerConnection->ice_gathering_state();
} else {
state = webrtc::PeerConnectionInterface::kIceGatheringComplete;
}

TRACE_END;
info.GetReturnValue().Set(Nan::New<Number>(static_cast<uint32_t>(state)));
Expand Down
18 changes: 17 additions & 1 deletion test/connect.js
Expand Up @@ -244,9 +244,25 @@ test('getStats', function(t) {
});

test('close the connections', function(t) {
t.plan(1);
t.plan(3);

peers[0].close();
peers[1].close();

// make sure nothing crashes after connection is closed and _jinglePeerConnection is null
for (var i = 0; i < 2; i++) {
peers[i].createOffer();
peers[i].createAnswer();
peers[i].setLocalDescription({}, function() {}, function(){});
peers[i].setRemoteDescription({}, function() {}, function(){});
peers[i].addIceCandidate({}, function() {}, function(){});
peers[i].createDataChannel('test');
peers[i].getStats(function(){}, function(err){
t.ok(err);
});
peers[i].close();
}

t.pass('closed connections');

peers = [];
Expand Down

0 comments on commit 987b25a

Please sign in to comment.