File indexing completed on 2024-04-28 04:01:24

0001 /* -*- C++ -*-
0002     This file is part of ThreadWeaver.
0003 
0004     SPDX-FileCopyrightText: 2004-2013 Mirko Boehm <mirko@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #include "sequence_p.h"
0010 #include "debuggingaids.h"
0011 
0012 namespace ThreadWeaver
0013 {
0014 namespace Private
0015 {
0016 Sequence_Private::Sequence_Private()
0017 {
0018 }
0019 
0020 BlockerPolicy *Sequence_Private::blocker()
0021 {
0022     return &blocker_;
0023 }
0024 
0025 void Sequence_Private::prepareToEnqueueElements()
0026 {
0027     Q_ASSERT(!mutex.tryLock());
0028     const int jobs = elements.count();
0029     // probably incorrect:
0030     completed_.storeRelease(0);
0031     // block the execution of the later jobs:
0032     for (int i = 0; i < jobs; ++i) {
0033         TWDEBUG(4, "Sequence_Private::prepareToEnqueueElements: blocking %p\n", elements.at(i).data());
0034         JobPointer nextJob = elements.at(i);
0035         QMutexLocker l(nextJob->mutex());
0036         nextJob->assignQueuePolicy(blocker());
0037     }
0038 }
0039 
0040 void Sequence_Private::processCompletedElement(Collection *collection, JobPointer job, Thread *)
0041 {
0042     Q_ASSERT(!mutex.tryLock());
0043     Q_ASSERT(job != nullptr);
0044     Q_ASSERT(!self.isNull());
0045 
0046     auto updatedStatus = updateStatus(collection, job);
0047     if (updatedStatus != JobInterface::Status_Running) {
0048         // We need to unlock mutex so that `stop` can
0049         // properly stop us
0050         mutex.unlock();
0051         stop(collection);
0052         mutex.lock();
0053         // stop might have changed our status
0054         // so lets restore back to original
0055         collection->setStatus(updatedStatus);
0056     }
0057     const int next = completed_.fetchAndAddAcquire(1);
0058     const int count = elements.count();
0059     if (count > 0) {
0060         if (next < count) {
0061             TWDEBUG(4, "Sequence_Private::processCompletedElement: unblocking %p\n", elements.at(next).data());
0062             JobPointer nextJob = elements.at(next);
0063             QMutexLocker l(nextJob->mutex());
0064             nextJob->removeQueuePolicy(blocker());
0065         }
0066     }
0067 }
0068 
0069 void Sequence_Private::elementDequeued(const JobPointer &job)
0070 {
0071     Q_ASSERT(!mutex.tryLock());
0072     QMutexLocker l(job->mutex());
0073     job->removeQueuePolicy(blocker());
0074 }
0075 
0076 void BlockerPolicy::destructed(JobInterface *)
0077 {
0078 }
0079 
0080 bool BlockerPolicy::canRun(JobPointer)
0081 {
0082     return false;
0083 }
0084 
0085 void BlockerPolicy::free(JobPointer)
0086 {
0087 }
0088 
0089 void BlockerPolicy::release(JobPointer)
0090 {
0091 }
0092 
0093 }
0094 
0095 }