1 | /* -*- C++ -*- |
---|---|
2 | This file is part of ThreadWeaver. |
3 | |
4 | SPDX-FileCopyrightText: 2004-2013 Mirko Boehm <mirko@kde.org> |
5 | |
6 | SPDX-License-Identifier: LGPL-2.0-or-later |
7 | */ |
8 | |
9 | #include "sequence_p.h" |
10 | #include "debuggingaids.h" |
11 | |
12 | namespace ThreadWeaver |
13 | { |
14 | namespace Private |
15 | { |
16 | Sequence_Private::Sequence_Private() |
17 | { |
18 | } |
19 | |
20 | BlockerPolicy *Sequence_Private::blocker() |
21 | { |
22 | return &blocker_; |
23 | } |
24 | |
25 | void Sequence_Private::prepareToEnqueueElements() |
26 | { |
27 | Q_ASSERT(!mutex.tryLock()); |
28 | const int jobs = elements.count(); |
29 | // probably incorrect: |
30 | completed_.storeRelease(newValue: 0); |
31 | // block the execution of the later jobs: |
32 | for (int i = 0; i < jobs; ++i) { |
33 | TWDEBUG(4, "Sequence_Private::prepareToEnqueueElements: blocking %p\n", elements.at(i).data()); |
34 | JobPointer nextJob = elements.at(i); |
35 | QMutexLocker l(nextJob->mutex()); |
36 | nextJob->assignQueuePolicy(blocker()); |
37 | } |
38 | } |
39 | |
40 | void Sequence_Private::processCompletedElement(Collection *collection, JobPointer job, Thread *) |
41 | { |
42 | Q_ASSERT(!mutex.tryLock()); |
43 | Q_ASSERT(job != nullptr); |
44 | Q_ASSERT(!self.isNull()); |
45 | |
46 | auto updatedStatus = updateStatus(collection, job); |
47 | if (updatedStatus != JobInterface::Status_Running) { |
48 | // We need to unlock mutex so that `stop` can |
49 | // properly stop us |
50 | mutex.unlock(); |
51 | stop(collection); |
52 | mutex.lock(); |
53 | // stop might have changed our status |
54 | // so lets restore back to original |
55 | collection->setStatus(updatedStatus); |
56 | } |
57 | const int next = completed_.fetchAndAddAcquire(valueToAdd: 1); |
58 | const int count = elements.count(); |
59 | if (count > 0) { |
60 | if (next < count) { |
61 | TWDEBUG(4, "Sequence_Private::processCompletedElement: unblocking %p\n", elements.at(next).data()); |
62 | JobPointer nextJob = elements.at(i: next); |
63 | QMutexLocker l(nextJob->mutex()); |
64 | nextJob->removeQueuePolicy(blocker()); |
65 | } |
66 | } |
67 | } |
68 | |
69 | void Sequence_Private::elementDequeued(const JobPointer &job) |
70 | { |
71 | Q_ASSERT(!mutex.tryLock()); |
72 | QMutexLocker l(job->mutex()); |
73 | job->removeQueuePolicy(blocker()); |
74 | } |
75 | |
76 | void BlockerPolicy::destructed(JobInterface *) |
77 | { |
78 | } |
79 | |
80 | bool BlockerPolicy::canRun(JobPointer) |
81 | { |
82 | return false; |
83 | } |
84 | |
85 | void BlockerPolicy::free(JobPointer) |
86 | { |
87 | } |
88 | |
89 | void BlockerPolicy::release(JobPointer) |
90 | { |
91 | } |
92 | |
93 | } |
94 | |
95 | } |
96 |