/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/


#include <QtCore>
#include <QtTest/QtTest>

#include "emulationdetector.h"

enum { OneMinute = 60 * 1000,
       TwoMinutes = OneMinute * 2 };


struct Functor
{
    void operator()() const {};
};

class tst_QObjectRace: public QObject
{
    Q_OBJECT
private slots:
    void moveToThreadRace();
    void destroyRace();
    void disconnectRace();
};

class RaceObject : public QObject
{
    Q_OBJECT
    QList<QThread *> threads;
    int count;

public:
    RaceObject()
        : count(0)
    { }

    void addThread(QThread *thread)
    { threads.append(thread); }

public slots:
    void theSlot()
    {
        enum { step = 35 };
        if ((++count % step) == 0) {
            QThread *nextThread = threads.at((count / step) % threads.size());
            moveToThread(nextThread);
        }
    }

    void destroSlot() {
        emit theSignal();
    }
signals:
    void theSignal();
};

class RaceThread : public QThread
{
    Q_OBJECT
    RaceObject *object;
    QElapsedTimer stopWatch;

public:
    RaceThread()
        : object(0)
    { }

    void setObject(RaceObject *o)
    {
        object = o;
        object->addThread(this);
    }

    void start() {
        stopWatch.start();
        QThread::start();
    }

    void run() {
        QTimer zeroTimer;
        connect(&zeroTimer, SIGNAL(timeout()), object, SLOT(theSlot()));
        connect(&zeroTimer, SIGNAL(timeout()), this, SLOT(checkStopWatch()), Qt::DirectConnection);
        zeroTimer.start(0);
        (void) exec();
    }

signals:
    void theSignal();

private slots:
    void checkStopWatch()
    {
        if (stopWatch.elapsed() >= 5000)
            quit();

        QObject o;
        connect(&o, SIGNAL(destroyed()) , object, SLOT(destroSlot()));
        connect(object, SIGNAL(destroyed()) , &o, SLOT(deleteLater()));
    }
};

void tst_QObjectRace::moveToThreadRace()
{
    RaceObject *object = new RaceObject;

    enum { ThreadCount = 6 };
    RaceThread *threads[ThreadCount];
    for (int i = 0; i < ThreadCount; ++i) {
        threads[i] = new RaceThread;
        threads[i]->setObject(object);
    }

    object->moveToThread(threads[0]);

    for (int i = 0; i < ThreadCount; ++i)
        threads[i]->start();

    while(!threads[0]->isFinished()) {
        QPointer<RaceObject> foo (object);
        QObject o;
        connect(&o, SIGNAL(destroyed()) , object, SLOT(destroSlot()));
        connect(object, SIGNAL(destroyed()) , &o, SLOT(deleteLater()));
        QTest::qWait(10);
    }
    // the other threads should finish pretty quickly now
    for (int i = 1; i < ThreadCount; ++i)
        QVERIFY(threads[i]->wait(300));

    for (int i = 0; i < ThreadCount; ++i)
        delete threads[i];
    delete object;
}


class MyObject : public QObject
{   Q_OBJECT
        bool ok;
    public:
        MyObject() : ok(true) {}
        ~MyObject() { Q_ASSERT(ok); ok = false; }
    public slots:
        void slot1() { Q_ASSERT(ok); }
        void slot2() { Q_ASSERT(ok); }
        void slot3() { Q_ASSERT(ok); }
        void slot4() { Q_ASSERT(ok); }
        void slot5() { Q_ASSERT(ok); }
        void slot6() { Q_ASSERT(ok); }
        void slot7() { Q_ASSERT(ok); }
    signals:
        void signal1();
        void signal2();
        void signal3();
        void signal4();
        void signal5();
        void signal6();
        void signal7();
};

namespace {
const char *_slots[] = { SLOT(slot1()) , SLOT(slot2()) , SLOT(slot3()),
                         SLOT(slot4()) , SLOT(slot5()) , SLOT(slot6()),
                         SLOT(slot7()) };

const char *_signals[] = { SIGNAL(signal1()), SIGNAL(signal2()), SIGNAL(signal3()),
                           SIGNAL(signal4()), SIGNAL(signal5()), SIGNAL(signal6()),
                           SIGNAL(signal7()) };

typedef void (MyObject::*PMFType)();
const PMFType _slotsPMF[] = { &MyObject::slot1, &MyObject::slot2, &MyObject::slot3,
                              &MyObject::slot4, &MyObject::slot5, &MyObject::slot6,
                              &MyObject::slot7 };

const PMFType _signalsPMF[] = { &MyObject::signal1, &MyObject::signal2, &MyObject::signal3,
                                &MyObject::signal4, &MyObject::signal5, &MyObject::signal6,
                                &MyObject::signal7 };

}

class DestroyThread : public QThread
{
    Q_OBJECT
    MyObject **objects;
    int number;

public:
    void setObjects(MyObject **o, int n)
    {
        objects = o;
        number = n;
        for(int i = 0; i < number; i++)
            objects[i]->moveToThread(this);
    }

    void run() {
        for (int i = number-1; i >= 0; --i) {
            /* Do some more connection and disconnection between object in this thread that have not been destroyed yet */

            const int nAlive = i+1;
            connect   (objects[((i+1)*31) % nAlive], _signals[(12*i)%7], objects[((i+2)*37) % nAlive],  _slots[(15*i+2)%7] );
            disconnect(objects[((i+1)*31) % nAlive], _signals[(12*i)%7], objects[((i+2)*37) % nAlive],  _slots[(15*i+2)%7] );

            connect   (objects[((i+4)*41) % nAlive], _signalsPMF[(18*i)%7], objects[((i+5)*43) % nAlive],  _slotsPMF[(19*i+2)%7] );
            disconnect(objects[((i+4)*41) % nAlive], _signalsPMF[(18*i)%7], objects[((i+5)*43) % nAlive],  _slotsPMF[(19*i+2)%7] );

            QMetaObject::Connection c = connect(objects[((i+5)*43) % nAlive], _signalsPMF[(9*i+1)%7], Functor());

            for (int f = 0; f < 7; ++f)
                emit (objects[i]->*_signalsPMF[f])();

            disconnect(c);

            disconnect(objects[i], _signalsPMF[(10*i+5)%7], 0, 0);
            disconnect(objects[i], _signals[(11*i+6)%7], 0, 0);

            disconnect(objects[i], 0, objects[(i*17+6) % nAlive], 0);
            if (i%4 == 1) {
                disconnect(objects[i], 0, 0, 0);
            }

            delete objects[i];
        }

        //run the possible queued slots
        qApp->processEvents();
    }
};

#define EXTRA_THREAD_WAIT 3000
#define MAIN_THREAD_WAIT TwoMinutes

void tst_QObjectRace::destroyRace()
{
    if (EmulationDetector::isRunningArmOnX86())
        QSKIP("Test is too slow to run on emulator");

    enum { ThreadCount = 10, ObjectCountPerThread = 2777,
           ObjectCount = ThreadCount * ObjectCountPerThread };

    MyObject *objects[ObjectCount];
    for (int i = 0; i < ObjectCount; ++i)
        objects[i] = new MyObject;


    for (int i = 0; i < ObjectCount * 17; ++i) {
        connect(objects[(i*13) % ObjectCount], _signals[(2*i)%7],
                objects[((i+2)*17) % ObjectCount],  _slots[(3*i+2)%7] );
        connect(objects[((i+6)*23) % ObjectCount], _signals[(5*i+4)%7],
                objects[((i+8)*41) % ObjectCount],  _slots[(i+6)%7] );

        connect(objects[(i*67) % ObjectCount], _signalsPMF[(2*i)%7],
                objects[((i+1)*71) % ObjectCount],  _slotsPMF[(3*i+2)%7] );
        connect(objects[((i+3)*73) % ObjectCount], _signalsPMF[(5*i+4)%7],
                objects[((i+5)*79) % ObjectCount],  Functor() );
    }

    DestroyThread *threads[ThreadCount];
    for (int i = 0; i < ThreadCount; ++i) {
        threads[i] = new DestroyThread;
        threads[i]->setObjects(objects + i*ObjectCountPerThread, ObjectCountPerThread);
    }

    for (int i = 0; i < ThreadCount; ++i)
        threads[i]->start();

    QVERIFY(threads[0]->wait(MAIN_THREAD_WAIT));
    // the other threads should finish pretty quickly now
    for (int i = 1; i < ThreadCount; ++i)
        QVERIFY(threads[i]->wait(EXTRA_THREAD_WAIT));

    for (int i = 0; i < ThreadCount; ++i)
        delete threads[i];
}

static QAtomicInteger<unsigned> countedStructObjectsCount;
struct CountedFunctor
{
    CountedFunctor() : destroyed(false) { countedStructObjectsCount.fetchAndAddRelaxed(1); }
    CountedFunctor(const CountedFunctor &) : destroyed(false) { countedStructObjectsCount.fetchAndAddRelaxed(1); }
    CountedFunctor &operator=(const CountedFunctor &) { return *this; }
    ~CountedFunctor() { destroyed = true; countedStructObjectsCount.fetchAndAddRelaxed(-1);}
    void operator()() const {QCOMPARE(destroyed, false);}

private:
    bool destroyed;
};

class DisconnectRaceSenderObject : public QObject
{
    Q_OBJECT
signals:
    void theSignal();
};

class DisconnectRaceThread : public QThread
{
    Q_OBJECT

    DisconnectRaceSenderObject *sender;
    bool emitSignal;
public:
    DisconnectRaceThread(DisconnectRaceSenderObject *s, bool emitIt)
        : QThread(), sender(s), emitSignal(emitIt)
    {
    }

    void run()
    {
        while (!isInterruptionRequested()) {
            QMetaObject::Connection conn = connect(sender, &DisconnectRaceSenderObject::theSignal,
                                                   sender, CountedFunctor(), Qt::BlockingQueuedConnection);
            if (emitSignal)
                emit sender->theSignal();
            disconnect(conn);
            yieldCurrentThread();
        }
    }
};

class DeleteReceiverRaceSenderThread : public QThread
{
    Q_OBJECT

    DisconnectRaceSenderObject *sender;
public:
    DeleteReceiverRaceSenderThread(DisconnectRaceSenderObject *s)
        : QThread(), sender(s)
    {
    }

    void run()
    {
        while (!isInterruptionRequested()) {
            emit sender->theSignal();
            yieldCurrentThread();
        }
    }
};

class DeleteReceiverRaceReceiver : public QObject
{
    Q_OBJECT

    DisconnectRaceSenderObject *sender;
    QObject *receiver;
    QTimer *timer;
public:
    DeleteReceiverRaceReceiver(DisconnectRaceSenderObject *s)
        : QObject(), sender(s), receiver(0)
    {
        timer = new QTimer(this);
        connect(timer, &QTimer::timeout, this, &DeleteReceiverRaceReceiver::onTimeout);
        timer->start(1);
    }
    ~DeleteReceiverRaceReceiver()
    {
        delete receiver;
    }

    void onTimeout()
    {
        if (receiver)
            delete receiver;
        receiver = new QObject;
        connect(sender, &DisconnectRaceSenderObject::theSignal, receiver, CountedFunctor(), Qt::BlockingQueuedConnection);
    }
};

class DeleteReceiverRaceReceiverThread : public QThread
{
    Q_OBJECT

    DisconnectRaceSenderObject *sender;
public:
    DeleteReceiverRaceReceiverThread(DisconnectRaceSenderObject *s)
        : QThread(), sender(s)
    {
    }

    void run()
    {
        QScopedPointer<DeleteReceiverRaceReceiver> receiver(new DeleteReceiverRaceReceiver(sender));
        exec();
    }
};

void tst_QObjectRace::disconnectRace()
{
    enum { ThreadCount = 20, TimeLimit = 3000 };

    QCOMPARE(countedStructObjectsCount.loadRelaxed(), 0u);

    {
        QScopedPointer<DisconnectRaceSenderObject> sender(new DisconnectRaceSenderObject());
        QScopedPointer<QThread> senderThread(new QThread());
        senderThread->start();
        sender->moveToThread(senderThread.data());

        DisconnectRaceThread *threads[ThreadCount];
        for (int i = 0; i < ThreadCount; ++i) {
            threads[i] = new DisconnectRaceThread(sender.data(), !(i % 10));
            threads[i]->start();
        }

        QTest::qWait(TimeLimit);

        for (int i = 0; i < ThreadCount; ++i) {
            threads[i]->requestInterruption();
            QVERIFY(threads[i]->wait());
            delete threads[i];
        }

        senderThread->quit();
        QVERIFY(senderThread->wait());
    }

    QCOMPARE(countedStructObjectsCount.loadRelaxed(), 0u);

    {
        QScopedPointer<DisconnectRaceSenderObject> sender(new DisconnectRaceSenderObject());
        QScopedPointer<DeleteReceiverRaceSenderThread> senderThread(new DeleteReceiverRaceSenderThread(sender.data()));
        senderThread->start();
        sender->moveToThread(senderThread.data());

        DeleteReceiverRaceReceiverThread *threads[ThreadCount];
        for (int i = 0; i < ThreadCount; ++i) {
            threads[i] = new DeleteReceiverRaceReceiverThread(sender.data());
            threads[i]->start();
        }

        QTest::qWait(TimeLimit);

        senderThread->requestInterruption();
        QVERIFY(senderThread->wait());

        for (int i = 0; i < ThreadCount; ++i) {
            threads[i]->quit();
            QVERIFY(threads[i]->wait());
            delete threads[i];
        }
    }

    QCOMPARE(countedStructObjectsCount.loadRelaxed(), 0u);
}

QTEST_MAIN(tst_QObjectRace)
#include "tst_qobjectrace.moc"
