From 206a8fec2cb2aeb964282ba0a370f675d69c1f91 Mon Sep 17 00:00:00 2001 From: Sze Howe Koh Date: Wed, 26 Feb 2025 15:59:52 +0800 Subject: [PATCH] [Doc] QObject: Sync warnings of isSignalConnected() and receivers() Extends e75c1a00e31723f1c9deb8427725fa0a58fae2a8 because calling receivers() in disconnectNotify() can deadlock too. As a drive-by, some statements are generalized further: * "expensive initialization" -> "expensive operations" since that is what the relevant snippets actually show. * The potential race condition is not limited to "after this function returns and before the signal gets emitted" Task-number: QTBUG-106025 Change-Id: Iff014706b9e8d8147e3bbb9ac51542197eec5db3 Pick-to: 6.8 6.5 Reviewed-by: Thiago Macieira (cherry picked from commit f5b874fd2d393b783dad85c95a158383420e481a) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/kernel/qobject.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index b0f2b9cd205..938afc7d021 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -2732,10 +2732,16 @@ int QObject::senderSignalIndex() const \snippet code/src_corelib_kernel_qobject.cpp 21 + As the code snippet above illustrates, you can use this function to avoid + expensive operations or emitting a signal that nobody listens to. + + \warning In a multithreaded application, consecutive calls to this + function are not guaranteed to yield the same results. + \warning This function violates the object-oriented principle of - modularity. However, it might be useful when you need to perform - expensive initialization only if something is connected to a - signal. + modularity. In particular, this function must not be called from an + override of connectNotify() or disconnectNotify(), as those might get + called from any thread. \sa isSignalConnected() */ @@ -2792,14 +2798,17 @@ int QObject::receivers(const char *signal) const \snippet code/src_corelib_kernel_qobject.cpp 49 As the code snippet above illustrates, you can use this function to avoid - expensive initialization or emitting a signal that nobody listens to. - However, in a multithreaded application, connections might change after - this function returns and before the signal gets emitted. + expensive operations or emitting a signal that nobody listens to. + + \warning In a multithreaded application, consecutive calls to this + function are not guaranteed to yield the same results. \warning This function violates the object-oriented principle of modularity. In particular, this function must not be called from an override of connectNotify() or disconnectNotify(), as those might get called from any thread. + + \sa receivers() */ bool QObject::isSignalConnected(const QMetaMethod &signal) const { @@ -3483,8 +3492,7 @@ bool QObject::disconnect(const QObject *sender, const QMetaMethod &signal, \warning This function violates the object-oriented principle of modularity. However, it might be useful when you need to perform - expensive initialization only if something is connected to a - signal. + an expensive operation only if something is connected to a signal. \warning This function is called from the thread which performs the connection, which may be a different thread from the thread in which