diff options
author | Andrew Webster <awebster@arcx.com> | 2020-02-06 09:25:00 -0500 |
---|---|---|
committer | Andrew Webster <awebster@arcx.com> | 2020-02-21 10:46:35 -0500 |
commit | b808e4f8ec42df64fee5f6f170c225b6fbd62070 (patch) | |
tree | 0bf4fca57f721ed4e70a2bf8bd64562d8112a93c /tests/auto | |
parent | 295b33d05396cad96bbed3094bf23d880fe58109 (diff) | |
download | qtwebchannel-b808e4f8ec42df64fee5f6f170c225b6fbd62070.tar.gz |
Skip changes made while iterating over connections for emit
If changes are made to the connections while iterating over them
during an emit, these new changes should be ignored until the next
emit. If not, the following things could happen:
* newly added connections could be called for the current emit
* an existing connection may not be called at all
New connections added to the list are already ignored because forEach
caches the length before processing an array.
However, if an item is removed during forEach, the current index is
not adjusted, which will result in next item being skipped if the
removed item is before the current index. This is dealt with by creating
a new list during disconnect with the diconnected item removed. This
way the list that forEach uses is not modified.
This logic is slightly different than QObject, which uses a linked list.
If handlers A and B have been attached to the same signal, and handler A
disconnects handler B, handler B would still be called, even if it was
connected after handler A, which is not the case for QObject. A more
complex solution may be required if this behavior needs to match
QObject.
This also removes an error message when disconnect fails to find any
matching connection. This more closely matches QObject.
Change-Id: Ief04426a962362055022f450d9767d4b5fe152a1
Reviewed-by: Milian Wolff <milian.wolff@kdab.com>
Diffstat (limited to 'tests/auto')
-rw-r--r-- | tests/auto/qml/tst_webchannel.qml | 61 |
1 files changed, 61 insertions, 0 deletions
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 = []; |