mirror of
https://github.com/simonbrunel/qtpromise.git
synced 2025-07-01 23:11:47 +08:00
Cleanup promise captured in resolve/reject
Make sure that QPromiseResolve and QPromiseReject release their associated promise as soon as one of them is resolved or rejected, ensuring that the promise data is cleaned up once resolved (that fixes cases where one or both of them are captured in a signal/slot connection lambda)
This commit is contained in:
@ -7,6 +7,9 @@
|
||||
// Qt
|
||||
#include <QtTest>
|
||||
|
||||
// STL
|
||||
#include <memory>
|
||||
|
||||
using namespace QtPromise;
|
||||
|
||||
class tst_qpromise_construct : public QObject
|
||||
@ -30,6 +33,8 @@ private Q_SLOTS:
|
||||
void rejectSync_void();
|
||||
void rejectAsync();
|
||||
void rejectAsync_void();
|
||||
void connectAndResolve();
|
||||
void connectAndReject();
|
||||
};
|
||||
|
||||
QTEST_MAIN(tst_qpromise_construct)
|
||||
@ -228,3 +233,77 @@ void tst_qpromise_construct::rejectThrowTwoArgs_void()
|
||||
QCOMPARE(waitForValue(p, -1, 42), -1);
|
||||
QCOMPARE(waitForError(p, QString()), QString("foo"));
|
||||
}
|
||||
|
||||
// https://github.com/simonbrunel/qtpromise/issues/6
|
||||
void tst_qpromise_construct::connectAndResolve()
|
||||
{
|
||||
QScopedPointer<QObject> object(new QObject());
|
||||
|
||||
std::weak_ptr<int> wptr;
|
||||
|
||||
{
|
||||
auto p = QPromise<std::shared_ptr<int>>([&](
|
||||
const QPromiseResolve<std::shared_ptr<int>>& resolve,
|
||||
const QPromiseReject<std::shared_ptr<int>>& reject) {
|
||||
|
||||
connect(object.data(), &QObject::objectNameChanged,
|
||||
[=, &wptr](const QString& name) {
|
||||
std::shared_ptr<int> sptr(new int(42));
|
||||
|
||||
wptr = sptr;
|
||||
|
||||
if (name == "foobar") {
|
||||
resolve(sptr);
|
||||
} else {
|
||||
reject(42);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
QCOMPARE(p.isPending(), true);
|
||||
|
||||
object->setObjectName("foobar");
|
||||
|
||||
QCOMPARE(waitForValue(p, std::shared_ptr<int>()), wptr.lock());
|
||||
QCOMPARE(wptr.use_count(), 1l); // "p" still holds a reference
|
||||
}
|
||||
|
||||
QCOMPARE(wptr.use_count(), 0l);
|
||||
}
|
||||
|
||||
// https://github.com/simonbrunel/qtpromise/issues/6
|
||||
void tst_qpromise_construct::connectAndReject()
|
||||
{
|
||||
QScopedPointer<QObject> object(new QObject());
|
||||
|
||||
std::weak_ptr<int> wptr;
|
||||
|
||||
{
|
||||
auto p = QPromise<int>([&](
|
||||
const QPromiseResolve<int>& resolve,
|
||||
const QPromiseReject<int>& reject) {
|
||||
|
||||
connect(object.data(), &QObject::objectNameChanged,
|
||||
[=, &wptr](const QString& name) {
|
||||
std::shared_ptr<int> sptr(new int(42));
|
||||
|
||||
wptr = sptr;
|
||||
|
||||
if (name == "foobar") {
|
||||
reject(sptr);
|
||||
} else {
|
||||
resolve(42);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
QCOMPARE(p.isPending(), true);
|
||||
|
||||
object->setObjectName("foobar");
|
||||
|
||||
QCOMPARE(waitForError(p, std::shared_ptr<int>()), wptr.lock());
|
||||
QCOMPARE(wptr.use_count(), 1l); // "p" still holds a reference
|
||||
}
|
||||
|
||||
QCOMPARE(wptr.use_count(), 0l);
|
||||
}
|
||||
|
Reference in New Issue
Block a user