[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 <thiago.macieira@intel.com>
(cherry picked from commit f5b874fd2d393b783dad85c95a158383420e481a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Sze Howe Koh 2025-02-26 15:59:52 +08:00 committed by Qt Cherry-pick Bot
parent 54ef8bf929
commit 206a8fec2c

View File

@ -2732,10 +2732,16 @@ int QObject::senderSignalIndex() const
\snippet code/src_corelib_kernel_qobject.cpp 21 \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 \warning This function violates the object-oriented principle of
modularity. However, it might be useful when you need to perform modularity. In particular, this function must not be called from an
expensive initialization only if something is connected to a override of connectNotify() or disconnectNotify(), as those might get
signal. called from any thread.
\sa isSignalConnected() \sa isSignalConnected()
*/ */
@ -2792,14 +2798,17 @@ int QObject::receivers(const char *signal) const
\snippet code/src_corelib_kernel_qobject.cpp 49 \snippet code/src_corelib_kernel_qobject.cpp 49
As the code snippet above illustrates, you can use this function to avoid As the code snippet above illustrates, you can use this function to avoid
expensive initialization or emitting a signal that nobody listens to. expensive operations 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. \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 \warning This function violates the object-oriented principle of
modularity. In particular, this function must not be called from an modularity. In particular, this function must not be called from an
override of connectNotify() or disconnectNotify(), as those might get override of connectNotify() or disconnectNotify(), as those might get
called from any thread. called from any thread.
\sa receivers()
*/ */
bool QObject::isSignalConnected(const QMetaMethod &signal) const 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 \warning This function violates the object-oriented principle of
modularity. However, it might be useful when you need to perform modularity. However, it might be useful when you need to perform
expensive initialization only if something is connected to a an expensive operation only if something is connected to a signal.
signal.
\warning This function is called from the thread which performs the \warning This function is called from the thread which performs the
connection, which may be a different thread from the thread in which connection, which may be a different thread from the thread in which