diff options
-rw-r--r-- | examples/webchannel/shared/qwebchannel.js | 12 | ||||
-rw-r--r-- | tests/auto/qml/tst_webchannel.qml | 61 |
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 = []; |