summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/webchannel/shared/qwebchannel.js12
-rw-r--r--tests/auto/qml/tst_webchannel.qml61
2 files changed, 66 insertions, 7 deletions
diff --git a/examples/webchannel/shared/qwebchannel.js b/examples/webchannel/shared/qwebchannel.js
index a57a740..3cfcd62 100644
--- a/examples/webchannel/shared/qwebchannel.js
+++ b/examples/webchannel/shared/qwebchannel.js
@@ -273,13 +273,11 @@ function QObject(name, data, webChannel)
console.error("Bad callback given to disconnect from signal " + signalName);
return;
}
- object.__objectSignals__[signalIndex] = object.__objectSignals__[signalIndex] || [];
- var idx = object.__objectSignals__[signalIndex].indexOf(callback);
- if (idx === -1) {
- console.error("Cannot find connection of signal " + signalName + " to " + callback.name);
- return;
- }
- object.__objectSignals__[signalIndex].splice(idx, 1);
+ // This makes a new list. This is important because it won't interfere with
+ // signal processing if a disconnection happens while emittig a signal
+ object.__objectSignals__[signalIndex] = (object.__objectSignals__[signalIndex] || []).filter(function(c) {
+ return c != callback;
+ });
if (!isPropertyNotifySignal && object.__objectSignals__[signalIndex].length === 0) {
// only required for "pure" signals, handled separately for properties in propertyUpdate
webChannel.exec({
diff --git a/tests/auto/qml/tst_webchannel.qml b/tests/auto/qml/tst_webchannel.qml
index 9c9b6d0..671c314 100644
--- a/tests/auto/qml/tst_webchannel.qml
+++ b/tests/auto/qml/tst_webchannel.qml
@@ -497,6 +497,67 @@ TestCase {
compare(signalArgs, [42, 42, 1, 1, 0, 0]);
}
+ function test_connectDuringEmit()
+ {
+ var cb1 = 0;
+ var cb2 = 0;
+ var channel = client.createChannel(function(channel) {
+ var myObj = channel.objects.myObj;
+ myObj.mySignal.connect(function() {
+ cb1++;
+ myObj.mySignal.connect(function() {
+ cb2++;
+ });
+ });
+ });
+ client.awaitInit();
+
+ var msg = client.awaitMessage();
+ compare(msg.type, JSClient.QWebChannelMessageTypes.connectToSignal);
+ compare(msg.object, "myObj");
+
+ client.awaitIdle();
+
+ myObj.mySignal(42, myObj);
+
+ compare(cb1, 1);
+ compare(cb2, 0);
+ }
+
+ function test_disconnectDuringEmit()
+ {
+ var cb1 = 0;
+ var cb2 = 0;
+ var cb3 = 0;
+ var channel = client.createChannel(function(channel) {
+ var myObj = channel.objects.myObj;
+ var cb1impl = function() {
+ cb1++;
+ };
+ myObj.mySignal.connect(cb1impl);
+ myObj.mySignal.connect(function() {
+ cb2++;
+ myObj.mySignal.disconnect(cb1impl);
+ });
+ myObj.mySignal.connect(function() {
+ cb3++;
+ });
+ });
+ client.awaitInit();
+
+ var msg = client.awaitMessage();
+ compare(msg.type, JSClient.QWebChannelMessageTypes.connectToSignal);
+ compare(msg.object, "myObj");
+
+ client.awaitIdle();
+
+ myObj.mySignal(42, myObj);
+
+ compare(cb1, 1);
+ compare(cb2, 1);
+ compare(cb3, 1);
+ }
+
function test_overloading()
{
var signalArgs_implicit = [];