Remove the DBusMessage* members from QDBusMessagePrivate
We don't need to keep the entire original message in QDBusMessagePrivate after we've demarshalled it, nor do we need to keep a link to the message we're replying to. In order to reply properly to a message, we only need two pieces of information: the serial of the method call being replied to and the service that originated the call. Fixes: QTBUG-69919 Change-Id: Ic5d393bfd36e48a193fcffff13b7375db459e619 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Ievgenii Meshcheriakov <ievgenii.meshcheriakov@qt.io>
This commit is contained in:
parent
24627d9bce
commit
7bf1989e62
@ -36,22 +36,37 @@ static inline const char *data(const QByteArray &arr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QDBusMessagePrivate::QDBusMessagePrivate()
|
QDBusMessagePrivate::QDBusMessagePrivate()
|
||||||
: msg(nullptr), reply(nullptr), localReply(nullptr), ref(1), type(QDBusMessage::InvalidMessage),
|
: localReply(nullptr), ref(1), type(QDBusMessage::InvalidMessage),
|
||||||
delayedReply(false), localMessage(false),
|
delayedReply(false), parametersValidated(false),
|
||||||
parametersValidated(false), autoStartService(true),
|
localMessage(false), autoStartService(true),
|
||||||
interactiveAuthorizationAllowed(false)
|
interactiveAuthorizationAllowed(false), isReplyRequired(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QDBusMessagePrivate::~QDBusMessagePrivate()
|
QDBusMessagePrivate::~QDBusMessagePrivate()
|
||||||
{
|
{
|
||||||
if (msg)
|
|
||||||
q_dbus_message_unref(msg);
|
|
||||||
if (reply)
|
|
||||||
q_dbus_message_unref(reply);
|
|
||||||
delete localReply;
|
delete localReply;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QDBusMessagePrivate::createResponseLink(const QDBusMessagePrivate *call)
|
||||||
|
{
|
||||||
|
if (Q_UNLIKELY(call->type != QDBusMessage::MethodCallMessage)) {
|
||||||
|
qWarning("QDBusMessage: replying to a message that isn't a method call");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (call->localMessage) {
|
||||||
|
localMessage = true;
|
||||||
|
call->localReply = new QDBusMessage(*this); // keep an internal copy
|
||||||
|
} else {
|
||||||
|
serial = call->serial;
|
||||||
|
service = call->service;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the reply must have a serial or be a local-loop optimization
|
||||||
|
Q_ASSERT(serial || localMessage);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\since 4.3
|
\since 4.3
|
||||||
Returns the human-readable message associated with the error that was received.
|
Returns the human-readable message associated with the error that was received.
|
||||||
@ -113,8 +128,8 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDB
|
|||||||
case QDBusMessage::ReplyMessage:
|
case QDBusMessage::ReplyMessage:
|
||||||
msg = q_dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
|
msg = q_dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
|
||||||
if (!d_ptr->localMessage) {
|
if (!d_ptr->localMessage) {
|
||||||
q_dbus_message_set_destination(msg, q_dbus_message_get_sender(d_ptr->reply));
|
q_dbus_message_set_destination(msg, data(d_ptr->service.toUtf8()));
|
||||||
q_dbus_message_set_reply_serial(msg, q_dbus_message_get_serial(d_ptr->reply));
|
q_dbus_message_set_reply_serial(msg, d_ptr->serial);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case QDBusMessage::ErrorMessage:
|
case QDBusMessage::ErrorMessage:
|
||||||
@ -126,8 +141,8 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDB
|
|||||||
msg = q_dbus_message_new(DBUS_MESSAGE_TYPE_ERROR);
|
msg = q_dbus_message_new(DBUS_MESSAGE_TYPE_ERROR);
|
||||||
q_dbus_message_set_error_name(msg, d_ptr->name.toUtf8());
|
q_dbus_message_set_error_name(msg, d_ptr->name.toUtf8());
|
||||||
if (!d_ptr->localMessage) {
|
if (!d_ptr->localMessage) {
|
||||||
q_dbus_message_set_destination(msg, q_dbus_message_get_sender(d_ptr->reply));
|
q_dbus_message_set_destination(msg, data(d_ptr->service.toUtf8()));
|
||||||
q_dbus_message_set_reply_serial(msg, q_dbus_message_get_serial(d_ptr->reply));
|
q_dbus_message_set_reply_serial(msg, d_ptr->serial);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case QDBusMessage::SignalMessage:
|
case QDBusMessage::SignalMessage:
|
||||||
@ -204,6 +219,7 @@ QDBusMessage QDBusMessagePrivate::fromDBusMessage(DBusMessage *dmsg, QDBusConnec
|
|||||||
return message;
|
return message;
|
||||||
|
|
||||||
message.d_ptr->type = QDBusMessage::MessageType(q_dbus_message_get_type(dmsg));
|
message.d_ptr->type = QDBusMessage::MessageType(q_dbus_message_get_type(dmsg));
|
||||||
|
message.d_ptr->serial = q_dbus_message_get_serial(dmsg);
|
||||||
message.d_ptr->path = QString::fromUtf8(q_dbus_message_get_path(dmsg));
|
message.d_ptr->path = QString::fromUtf8(q_dbus_message_get_path(dmsg));
|
||||||
message.d_ptr->interface = QString::fromUtf8(q_dbus_message_get_interface(dmsg));
|
message.d_ptr->interface = QString::fromUtf8(q_dbus_message_get_interface(dmsg));
|
||||||
message.d_ptr->name = message.d_ptr->type == DBUS_MESSAGE_TYPE_ERROR ?
|
message.d_ptr->name = message.d_ptr->type == DBUS_MESSAGE_TYPE_ERROR ?
|
||||||
@ -212,7 +228,7 @@ QDBusMessage QDBusMessagePrivate::fromDBusMessage(DBusMessage *dmsg, QDBusConnec
|
|||||||
message.d_ptr->service = QString::fromUtf8(q_dbus_message_get_sender(dmsg));
|
message.d_ptr->service = QString::fromUtf8(q_dbus_message_get_sender(dmsg));
|
||||||
message.d_ptr->signature = QString::fromUtf8(q_dbus_message_get_signature(dmsg));
|
message.d_ptr->signature = QString::fromUtf8(q_dbus_message_get_signature(dmsg));
|
||||||
message.d_ptr->interactiveAuthorizationAllowed = q_dbus_message_get_allow_interactive_authorization(dmsg);
|
message.d_ptr->interactiveAuthorizationAllowed = q_dbus_message_get_allow_interactive_authorization(dmsg);
|
||||||
message.d_ptr->msg = q_dbus_message_ref(dmsg);
|
message.d_ptr->isReplyRequired = !q_dbus_message_get_no_reply(dmsg);
|
||||||
|
|
||||||
QDBusDemarshaller demarshaller(capabilities);
|
QDBusDemarshaller demarshaller(capabilities);
|
||||||
demarshaller.message = q_dbus_message_ref(dmsg);
|
demarshaller.message = q_dbus_message_ref(dmsg);
|
||||||
@ -402,6 +418,7 @@ QDBusMessage QDBusMessage::createMethodCall(const QString &service, const QStrin
|
|||||||
message.d_ptr->path = path;
|
message.d_ptr->path = path;
|
||||||
message.d_ptr->interface = interface;
|
message.d_ptr->interface = interface;
|
||||||
message.d_ptr->name = method;
|
message.d_ptr->name = method;
|
||||||
|
message.d_ptr->isReplyRequired = true;
|
||||||
|
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
@ -444,15 +461,7 @@ QDBusMessage QDBusMessage::createReply(const QVariantList &arguments) const
|
|||||||
QDBusMessage reply;
|
QDBusMessage reply;
|
||||||
reply.setArguments(arguments);
|
reply.setArguments(arguments);
|
||||||
reply.d_ptr->type = ReplyMessage;
|
reply.d_ptr->type = ReplyMessage;
|
||||||
if (d_ptr->msg)
|
reply.d_ptr->createResponseLink(d_ptr);
|
||||||
reply.d_ptr->reply = q_dbus_message_ref(d_ptr->msg);
|
|
||||||
if (d_ptr->localMessage) {
|
|
||||||
reply.d_ptr->localMessage = true;
|
|
||||||
d_ptr->localReply = new QDBusMessage(reply); // keep an internal copy
|
|
||||||
}
|
|
||||||
|
|
||||||
// the reply must have a msg or be a local-loop optimization
|
|
||||||
Q_ASSERT(reply.d_ptr->reply || reply.d_ptr->localMessage);
|
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -463,15 +472,7 @@ QDBusMessage QDBusMessage::createReply(const QVariantList &arguments) const
|
|||||||
QDBusMessage QDBusMessage::createErrorReply(const QString &name, const QString &msg) const
|
QDBusMessage QDBusMessage::createErrorReply(const QString &name, const QString &msg) const
|
||||||
{
|
{
|
||||||
QDBusMessage reply = QDBusMessage::createError(name, msg);
|
QDBusMessage reply = QDBusMessage::createError(name, msg);
|
||||||
if (d_ptr->msg)
|
reply.d_ptr->createResponseLink(d_ptr);
|
||||||
reply.d_ptr->reply = q_dbus_message_ref(d_ptr->msg);
|
|
||||||
if (d_ptr->localMessage) {
|
|
||||||
reply.d_ptr->localMessage = true;
|
|
||||||
d_ptr->localReply = new QDBusMessage(reply); // keep an internal copy
|
|
||||||
}
|
|
||||||
|
|
||||||
// the reply must have a msg or be a local-loop optimization
|
|
||||||
Q_ASSERT(reply.d_ptr->reply || reply.d_ptr->localMessage);
|
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -555,6 +556,8 @@ QDBusMessage &QDBusMessage::operator=(const QDBusMessage &other)
|
|||||||
*/
|
*/
|
||||||
QString QDBusMessage::service() const
|
QString QDBusMessage::service() const
|
||||||
{
|
{
|
||||||
|
if (d_ptr->type == ErrorMessage || d_ptr->type == ReplyMessage)
|
||||||
|
return QString(); // d_ptr->service holds the destination
|
||||||
return d_ptr->service;
|
return d_ptr->service;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -617,9 +620,9 @@ bool QDBusMessage::isReplyRequired() const
|
|||||||
if (d_ptr->type != QDBusMessage::MethodCallMessage)
|
if (d_ptr->type != QDBusMessage::MethodCallMessage)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!d_ptr->msg)
|
if (d_ptr->localMessage) // if it's a local message, reply is required
|
||||||
return d_ptr->localMessage; // if it's a local message, reply is required
|
return true;
|
||||||
return !q_dbus_message_get_no_reply(d_ptr->msg);
|
return d_ptr->isReplyRequired;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -759,6 +762,12 @@ QDBusMessage &QDBusMessage::operator<<(const QVariant &arg)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QDBusMessage::QDBusMessage(QDBusMessagePrivate &dd)
|
||||||
|
: d_ptr(&dd)
|
||||||
|
{
|
||||||
|
d_ptr->ref.ref();
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the message type.
|
Returns the message type.
|
||||||
*/
|
*/
|
||||||
|
@ -84,6 +84,7 @@ public:
|
|||||||
QDBusMessage &operator<<(const QVariant &arg);
|
QDBusMessage &operator<<(const QVariant &arg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QDBusMessage(QDBusMessagePrivate &dd);
|
||||||
friend class QDBusMessagePrivate;
|
friend class QDBusMessagePrivate;
|
||||||
QDBusMessagePrivate *d_ptr;
|
QDBusMessagePrivate *d_ptr;
|
||||||
};
|
};
|
||||||
|
@ -39,20 +39,22 @@ public:
|
|||||||
|
|
||||||
// the following parameters are "const": they are not changed after the constructors
|
// the following parameters are "const": they are not changed after the constructors
|
||||||
// the parametersValidated member below controls whether they've been validated already
|
// the parametersValidated member below controls whether they've been validated already
|
||||||
|
// (service is also used to store the destination of reply-type messages)
|
||||||
QString service, path, interface, name, message, signature;
|
QString service, path, interface, name, message, signature;
|
||||||
|
|
||||||
DBusMessage *msg;
|
|
||||||
DBusMessage *reply;
|
|
||||||
mutable QDBusMessage *localReply;
|
mutable QDBusMessage *localReply;
|
||||||
QAtomicInt ref;
|
QAtomicInt ref;
|
||||||
QDBusMessage::MessageType type;
|
QDBusMessage::MessageType type;
|
||||||
|
uint32_t serial; // if type == MethodCall; the incoming serial; if type == Reply or Error, the serial we're replying to
|
||||||
|
|
||||||
mutable uint delayedReply : 1;
|
mutable uint delayedReply : 1;
|
||||||
uint localMessage : 1;
|
|
||||||
mutable uint parametersValidated : 1;
|
mutable uint parametersValidated : 1;
|
||||||
|
uint localMessage : 1;
|
||||||
uint autoStartService : 1;
|
uint autoStartService : 1;
|
||||||
uint interactiveAuthorizationAllowed : 1;
|
uint interactiveAuthorizationAllowed : 1;
|
||||||
|
uint isReplyRequired : 1;
|
||||||
|
|
||||||
|
void createResponseLink(const QDBusMessagePrivate *call);
|
||||||
static void setParametersValidated(QDBusMessage &msg, bool enable)
|
static void setParametersValidated(QDBusMessage &msg, bool enable)
|
||||||
{ msg.d_ptr->parametersValidated = enable; }
|
{ msg.d_ptr->parametersValidated = enable; }
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user