| 217 | } |
| 218 | |
| 219 | ACTOR static Future<Void> runner(PriorityMultiLock* self) { |
| 220 | state int sinceYield = 0; |
| 221 | state Future<Void> error = self->brokenOnDestruct.getFuture(); |
| 222 | state int maxPriority = self->waiters.size() - 1; |
| 223 | |
| 224 | // Priority to try to run tasks from next |
| 225 | state int priority = maxPriority; |
| 226 | state Queue* pQueue = &self->waiters[maxPriority]; |
| 227 | |
| 228 | // Track the number of waiters unlocked at the same priority in a row |
| 229 | state int lastPriorityCount = 0; |
| 230 | |
| 231 | loop { |
| 232 | // Cleanup finished runner futures at the front of the runner queue. |
| 233 | while (!self->runners.empty() && self->runners.front().isReady()) { |
| 234 | self->runners.pop_front(); |
| 235 | } |
| 236 | |
| 237 | // Wait for a runner to release its lock |
| 238 | wait(self->release.onTrigger()); |
| 239 | prioritylock_printf("runner wakeup %s\n", self->toString().c_str()); |
| 240 | |
| 241 | if (++sinceYield == 1000) { |
| 242 | sinceYield = 0; |
| 243 | wait(delay(0)); |
| 244 | } |
| 245 | |
| 246 | // While there are available slots and there are waiters, launch tasks |
| 247 | while (self->available > 0 && self->waiting > 0) { |
| 248 | prioritylock_printf("Checking priority=%d lastPriorityCount=%d %s\n", |
| 249 | priority, |
| 250 | lastPriorityCount, |
| 251 | self->toString().c_str()); |
| 252 | |
| 253 | while (!pQueue->empty() && ++lastPriorityCount < self->launchLimit) { |
| 254 | Waiter w = pQueue->front(); |
| 255 | pQueue->pop_front(); |
| 256 | --self->waiting; |
| 257 | Lock lock; |
| 258 | prioritylock_printf(" Running waiter priority=%d wait=%f %s\n", |
| 259 | priority, |
| 260 | now() - w.queuedTime, |
| 261 | self->toString().c_str()); |
| 262 | w.lockPromise.send(lock); |
| 263 | |
| 264 | // Self may have been destructed during the lock callback |
| 265 | if (error.isReady()) { |
| 266 | throw error.getError(); |
| 267 | } |
| 268 | |
| 269 | // If the lock was not already released, add it to the runners future queue |
| 270 | if (lock.promise.canBeSet()) { |
| 271 | self->addRunner(lock); |
| 272 | |
| 273 | // A slot has been consumed, so stop reading from this queue if there aren't any more |
| 274 | if (--self->available == 0) { |
| 275 | break; |
| 276 | } |
nothing calls this directly
no test coverage detected