Add a QAbstractMetaCallEvent

And use it to clean up the reimplementations in Qt DBus.

Change-Id: I8e3fe35e8db6405cbcbfb45b42a8f2efecc1cef0
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
This commit is contained in:
Lars Knoll 2019-02-01 12:49:16 +01:00
parent 6e0b5dadc7
commit 999c26dd83
4 changed files with 50 additions and 29 deletions

View File

@ -420,6 +420,16 @@ bool QObjectPrivate::maybeSignalConnected(uint signalIndex) const
return false; return false;
} }
/*!
\internal
*/
QAbstractMetaCallEvent::~QAbstractMetaCallEvent()
{
#if QT_CONFIG(thread)
if (semaphore_)
semaphore_->release();
#endif
}
/*! /*!
\internal \internal
@ -427,8 +437,8 @@ bool QObjectPrivate::maybeSignalConnected(uint signalIndex) const
QMetaCallEvent::QMetaCallEvent(ushort method_offset, ushort method_relative, QObjectPrivate::StaticMetaCallFunction callFunction, QMetaCallEvent::QMetaCallEvent(ushort method_offset, ushort method_relative, QObjectPrivate::StaticMetaCallFunction callFunction,
const QObject *sender, int signalId, const QObject *sender, int signalId,
int nargs, int *types, void **args, QSemaphore *semaphore) int nargs, int *types, void **args, QSemaphore *semaphore)
: QEvent(MetaCall), slotObj_(0), sender_(sender), signalId_(signalId), : QAbstractMetaCallEvent(sender, signalId, semaphore),
nargs_(nargs), types_(types), args_(args), semaphore_(semaphore), slotObj_(nullptr), nargs_(nargs), types_(types), args_(args),
callFunction_(callFunction), method_offset_(method_offset), method_relative_(method_relative) callFunction_(callFunction), method_offset_(method_offset), method_relative_(method_relative)
{ } { }
@ -437,9 +447,9 @@ QMetaCallEvent::QMetaCallEvent(ushort method_offset, ushort method_relative, QOb
*/ */
QMetaCallEvent::QMetaCallEvent(QtPrivate::QSlotObjectBase *slotO, const QObject *sender, int signalId, QMetaCallEvent::QMetaCallEvent(QtPrivate::QSlotObjectBase *slotO, const QObject *sender, int signalId,
int nargs, int *types, void **args, QSemaphore *semaphore) int nargs, int *types, void **args, QSemaphore *semaphore)
: QEvent(MetaCall), slotObj_(slotO), sender_(sender), signalId_(signalId), : QAbstractMetaCallEvent(sender, signalId, semaphore),
nargs_(nargs), types_(types), args_(args), semaphore_(semaphore), slotObj_(slotO), nargs_(nargs), types_(types), args_(args),
callFunction_(0), method_offset_(0), method_relative_(ushort(-1)) callFunction_(nullptr), method_offset_(0), method_relative_(ushort(-1))
{ {
if (slotObj_) if (slotObj_)
slotObj_->ref(); slotObj_->ref();
@ -458,10 +468,6 @@ QMetaCallEvent::~QMetaCallEvent()
free(types_); free(types_);
free(args_); free(args_);
} }
#if QT_CONFIG(thread)
if (semaphore_)
semaphore_->release();
#endif
if (slotObj_) if (slotObj_)
slotObj_->destroyIfLastRef(); slotObj_->destroyIfLastRef();
} }
@ -1179,7 +1185,7 @@ bool QObject::event(QEvent *e)
case QEvent::MetaCall: case QEvent::MetaCall:
{ {
QMetaCallEvent *mce = static_cast<QMetaCallEvent*>(e); QAbstractMetaCallEvent *mce = static_cast<QAbstractMetaCallEvent*>(e);
if (!d_func()->connections.load()) { if (!d_func()->connections.load()) {
QBasicMutexLocker locker(signalSlotLock(this)); QBasicMutexLocker locker(signalSlotLock(this));

View File

@ -485,7 +485,26 @@ Q_DECLARE_TYPEINFO(QObjectPrivate::Connection, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(QObjectPrivate::Sender, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(QObjectPrivate::Sender, Q_MOVABLE_TYPE);
class QSemaphore; class QSemaphore;
class Q_CORE_EXPORT QMetaCallEvent : public QEvent class Q_CORE_EXPORT QAbstractMetaCallEvent : public QEvent
{
public:
QAbstractMetaCallEvent(const QObject *sender, int signalId, QSemaphore *semaphore = nullptr)
: QEvent(MetaCall), signalId_(signalId), sender_(sender), semaphore_(semaphore)
{}
~QAbstractMetaCallEvent();
virtual void placeMetaCall(QObject *object) = 0;
inline const QObject *sender() const { return sender_; }
inline int signalId() const { return signalId_; }
private:
int signalId_;
const QObject *sender_;
QSemaphore *semaphore_;
};
class Q_CORE_EXPORT QMetaCallEvent : public QAbstractMetaCallEvent
{ {
public: public:
QMetaCallEvent(ushort method_offset, ushort method_relative, QObjectPrivate::StaticMetaCallFunction callFunction , const QObject *sender, int signalId, QMetaCallEvent(ushort method_offset, ushort method_relative, QObjectPrivate::StaticMetaCallFunction callFunction , const QObject *sender, int signalId,
@ -496,23 +515,18 @@ public:
QMetaCallEvent(QtPrivate::QSlotObjectBase *slotObj, const QObject *sender, int signalId, QMetaCallEvent(QtPrivate::QSlotObjectBase *slotObj, const QObject *sender, int signalId,
int nargs = 0, int *types = nullptr, void **args = nullptr, QSemaphore *semaphore = nullptr); int nargs = 0, int *types = nullptr, void **args = nullptr, QSemaphore *semaphore = nullptr);
~QMetaCallEvent(); ~QMetaCallEvent() override;
inline int id() const { return method_offset_ + method_relative_; } inline int id() const { return method_offset_ + method_relative_; }
inline const QObject *sender() const { return sender_; }
inline int signalId() const { return signalId_; }
inline void **args() const { return args_; } inline void **args() const { return args_; }
virtual void placeMetaCall(QObject *object); virtual void placeMetaCall(QObject *object) override;
private: private:
QtPrivate::QSlotObjectBase *slotObj_; QtPrivate::QSlotObjectBase *slotObj_;
const QObject *sender_;
int signalId_;
int nargs_; int nargs_;
int *types_; int *types_;
void **args_; void **args_;
QSemaphore *semaphore_;
QObjectPrivate::StaticMetaCallFunction callFunction_; QObjectPrivate::StaticMetaCallFunction callFunction_;
ushort method_offset_; ushort method_offset_;
ushort method_relative_; ushort method_relative_;

View File

@ -66,11 +66,11 @@ namespace {
// of to QDBusAbstractInterface::customEvent. // of to QDBusAbstractInterface::customEvent.
// See solution in Patch Set 1 of this change in the Qt Gerrit servers. // See solution in Patch Set 1 of this change in the Qt Gerrit servers.
// (https://codereview.qt-project.org/#/c/126384/1) // (https://codereview.qt-project.org/#/c/126384/1)
class DisconnectRelayEvent : public QMetaCallEvent class DisconnectRelayEvent : public QAbstractMetaCallEvent
{ {
public: public:
DisconnectRelayEvent(QObject *sender, const QMetaMethod &m) DisconnectRelayEvent(QObject *sender, const QMetaMethod &m)
: QMetaCallEvent(0, 0, nullptr, sender, m.methodIndex()) : QAbstractMetaCallEvent(sender, m.methodIndex())
{} {}
void placeMetaCall(QObject *object) override void placeMetaCall(QObject *object) override

View File

@ -101,36 +101,37 @@ struct QDBusSlotCache
Q_DECLARE_SHARED(QDBusSlotCache::Data) Q_DECLARE_SHARED(QDBusSlotCache::Data)
Q_DECLARE_SHARED(QDBusSlotCache) Q_DECLARE_SHARED(QDBusSlotCache)
class QDBusCallDeliveryEvent: public QMetaCallEvent class QDBusCallDeliveryEvent: public QAbstractMetaCallEvent
{ {
public: public:
QDBusCallDeliveryEvent(const QDBusConnection &c, int id, QObject *sender, QDBusCallDeliveryEvent(const QDBusConnection &c, int id, QObject *sender,
const QDBusMessage &msg, const QVector<int> &types, int f = 0) const QDBusMessage &msg, const QVector<int> &types, int f = 0)
: QMetaCallEvent(0, id, nullptr, sender, -1), connection(c), message(msg), metaTypes(types), flags(f) : QAbstractMetaCallEvent(sender, -1), connection(c), message(msg), metaTypes(types), id(id), flags(f)
{ } { }
void placeMetaCall(QObject *object) override void placeMetaCall(QObject *object) override
{ {
QDBusConnectionPrivate::d(connection)->deliverCall(object, flags, message, metaTypes, id()); QDBusConnectionPrivate::d(connection)->deliverCall(object, flags, message, metaTypes, id);
} }
private: private:
QDBusConnection connection; // just for refcounting QDBusConnection connection; // just for refcounting
QDBusMessage message; QDBusMessage message;
QVector<int> metaTypes; QVector<int> metaTypes;
int id;
int flags; int flags;
}; };
class QDBusActivateObjectEvent: public QMetaCallEvent class QDBusActivateObjectEvent: public QAbstractMetaCallEvent
{ {
public: public:
QDBusActivateObjectEvent(const QDBusConnection &c, QObject *sender, QDBusActivateObjectEvent(const QDBusConnection &c, QObject *sender,
const QDBusConnectionPrivate::ObjectTreeNode &n, const QDBusConnectionPrivate::ObjectTreeNode &n,
int p, const QDBusMessage &m, QSemaphore *s = nullptr) int p, const QDBusMessage &m, QSemaphore *s = nullptr)
: QMetaCallEvent(0, ushort(-1), nullptr, sender, -1, 0, nullptr, nullptr, s), connection(c), node(n), : QAbstractMetaCallEvent(sender, -1, s), connection(c), node(n),
pathStartPos(p), message(m), handled(false) pathStartPos(p), message(m), handled(false)
{ } { }
~QDBusActivateObjectEvent(); ~QDBusActivateObjectEvent() override;
void placeMetaCall(QObject *) override; void placeMetaCall(QObject *) override;
@ -142,15 +143,15 @@ private:
bool handled; bool handled;
}; };
class QDBusSpyCallEvent : public QMetaCallEvent class QDBusSpyCallEvent : public QAbstractMetaCallEvent
{ {
public: public:
typedef void (*Hook)(const QDBusMessage&); typedef void (*Hook)(const QDBusMessage&);
QDBusSpyCallEvent(QDBusConnectionPrivate *cp, const QDBusConnection &c, const QDBusMessage &msg, QDBusSpyCallEvent(QDBusConnectionPrivate *cp, const QDBusConnection &c, const QDBusMessage &msg,
const Hook *hooks, int count) const Hook *hooks, int count)
: QMetaCallEvent(0, 0, nullptr, cp, 0), conn(c), msg(msg), hooks(hooks), hookCount(count) : QAbstractMetaCallEvent(cp, 0), conn(c), msg(msg), hooks(hooks), hookCount(count)
{} {}
~QDBusSpyCallEvent(); ~QDBusSpyCallEvent() override;
void placeMetaCall(QObject *) override; void placeMetaCall(QObject *) override;
static inline void invokeSpyHooks(const QDBusMessage &msg, const Hook *hooks, int hookCount); static inline void invokeSpyHooks(const QDBusMessage &msg, const Hook *hooks, int hookCount);