aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKitsune Ral <Kitsune-Ral@users.sf.net>2016-10-07 16:20:20 +0900
committerKitsune Ral <Kitsune-Ral@users.sf.net>2016-10-07 16:20:20 +0900
commit14302ddbac1e6d9c95de15c97362c3de09f545eb (patch)
treece55d67815b1081a8c942fb6432134e056c4dd6c
parentab45e1aee912cf242caea2d762b2b27c83a0e972 (diff)
downloadlibquotient-14302ddbac1e6d9c95de15c97362c3de09f545eb.tar.gz
libquotient-14302ddbac1e6d9c95de15c97362c3de09f545eb.zip
Fixed massive leaks of Event objects
-rw-r--r--connection.cpp3
-rw-r--r--jobs/syncjob.cpp2
-rw-r--r--jobs/syncjob.h37
-rw-r--r--room.cpp6
-rw-r--r--room.h6
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
diff --git a/room.cpp b/room.cpp
index c693898f..e07426a7 100644
--- a/room.cpp
+++ b/room.cpp
@@ -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 )
{
diff --git a/room.h b/room.h
index 1c29aa01..7266ae70 100644
--- a/room.h
+++ b/room.h
@@ -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 );