diff options
author | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2016-10-07 16:20:20 +0900 |
---|---|---|
committer | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2016-10-07 16:20:20 +0900 |
commit | 14302ddbac1e6d9c95de15c97362c3de09f545eb (patch) | |
tree | ce55d67815b1081a8c942fb6432134e056c4dd6c | |
parent | ab45e1aee912cf242caea2d762b2b27c83a0e972 (diff) | |
download | libquotient-14302ddbac1e6d9c95de15c97362c3de09f545eb.tar.gz libquotient-14302ddbac1e6d9c95de15c97362c3de09f545eb.zip |
Fixed massive leaks of Event objects
-rw-r--r-- | connection.cpp | 3 | ||||
-rw-r--r-- | jobs/syncjob.cpp | 2 | ||||
-rw-r--r-- | jobs/syncjob.h | 37 | ||||
-rw-r--r-- | room.cpp | 6 | ||||
-rw-r--r-- | room.h | 6 |
5 files changed, 41 insertions, 13 deletions
diff --git a/connection.cpp b/connection.cpp index 9f56ec96..bc6d1f26 100644 --- a/connection.cpp +++ b/connection.cpp @@ -18,7 +18,6 @@ #include "connection.h" #include "connectiondata.h" -//#include "connectionprivate.h" #include "user.h" #include "events/event.h" #include "room.h" @@ -172,7 +171,7 @@ void Connection::sync(int timeout) auto job = d->startSyncJob(filter, timeout); connect( job, &SyncJob::success, [=] () { d->data->setLastEvent(job->nextBatch()); - for( const auto& roomData: job->roomData() ) + for( auto& roomData: job->roomData() ) { if ( Room* r = provideRoom(roomData.roomId) ) r->updateData(roomData); diff --git a/jobs/syncjob.cpp b/jobs/syncjob.cpp index 2b2705b1..59c40785 100644 --- a/jobs/syncjob.cpp +++ b/jobs/syncjob.cpp @@ -83,7 +83,7 @@ QString SyncJob::nextBatch() const return d->nextBatch; } -const SyncData& SyncJob::roomData() const +SyncData& SyncJob::roomData() { return d->roomData; } diff --git a/jobs/syncjob.h b/jobs/syncjob.h index ed99b38b..55d7458c 100644 --- a/jobs/syncjob.h +++ b/jobs/syncjob.h @@ -26,10 +26,34 @@ namespace QMatrixClient { + /** + * @brief A crude wrapper around a container of pointers that owns pointers + * to contained objects + * + * Similar to vector<unique_ptr<>>, upon deletion, EventsHolder + * will delete all events contained in it. + */ + template <typename ContainerT> + class Owning : public ContainerT + { + public: + Owning() = default; + Owning(Owning&) = delete; + Owning(Owning&& other) : ContainerT(std::move(other)) { } + ~Owning() { for (auto e: *this) delete e; } + + /** + * @brief returns the underlying events and releases the ownership + * + * Acts similar to unique_ptr::release. + */ + ContainerT release() { return std::move(*this); } + }; + class SyncRoomData { public: - class EventList : public Events + class EventList : public Owning<Events> { private: QString jsonKey; @@ -55,7 +79,13 @@ namespace QMatrixClient JoinState joinState_ = JoinState::Join, const QJsonObject& room_ = QJsonObject()); }; - using SyncData = QVector<SyncRoomData>; +} +Q_DECLARE_TYPEINFO(QMatrixClient::SyncRoomData, Q_MOVABLE_TYPE); + +namespace QMatrixClient +{ + // QVector cannot work with non-copiable objects, std::vector can. + using SyncData = std::vector<SyncRoomData>; class ConnectionData; class SyncJob: public BaseJob @@ -69,7 +99,7 @@ namespace QMatrixClient void setPresence(QString presence); void setTimeout(int timeout); - const SyncData& roomData() const; + SyncData& roomData(); QString nextBatch() const; protected: @@ -82,6 +112,5 @@ namespace QMatrixClient Private* d; }; } -Q_DECLARE_TYPEINFO(QMatrixClient::SyncRoomData, Q_MOVABLE_TYPE); #endif // QMATRIXCLIENT_SYNCJOB_H @@ -119,7 +119,7 @@ QString Room::id() const return d->id; } -Room::Timeline Room::messageEvents() const +const Room::Timeline& Room::messageEvents() const { return d->messageEvents; } @@ -329,7 +329,7 @@ QString Room::roomMembername(QString userId) const return roomMembername(connection()->user(userId)); } -void Room::updateData(const SyncRoomData& data) +void Room::updateData(SyncRoomData& data) { if( d->prevBatch.isEmpty() ) d->prevBatch = data.timelinePrevBatch; @@ -339,7 +339,7 @@ void Room::updateData(const SyncRoomData& data) // State changes can arrive in a timeline event; so check those. processStateEvents(data.timeline); - addNewMessageEvents(data.timeline); + addNewMessageEvents(data.timeline.release()); for( Event* ephemeralEvent: data.ephemeral ) { @@ -37,13 +37,13 @@ namespace QMatrixClient { Q_OBJECT public: - using Timeline = Events; + using Timeline = Owning<Events>; Room(Connection* connection, QString id); virtual ~Room(); Q_INVOKABLE QString id() const; - Q_INVOKABLE Timeline messageEvents() const; + Q_INVOKABLE const Timeline& messageEvents() const; Q_INVOKABLE QString name() const; Q_INVOKABLE QStringList aliases() const; Q_INVOKABLE QString canonicalAlias() const; @@ -66,7 +66,7 @@ namespace QMatrixClient */ Q_INVOKABLE QString roomMembername(QString userId) const; - Q_INVOKABLE void updateData( const SyncRoomData& data ); + Q_INVOKABLE void updateData(SyncRoomData& data ); Q_INVOKABLE void setJoinState( JoinState state ); Q_INVOKABLE void markMessageAsRead( Event* event ); |