JobQueue: fixed incorrect requeuing.
* A dependent job was requeued even if it wasn't part of the queue before. The code relied on dependent jobs being already enqueued; but that cannot be guaranteed. * If a job failed, its dependent jobs are now also set to failed, so that they won't be requeued at a later point. * This caused some of the "Launching xxx failed: Operation not allowed" messages in the boot process. Those actually weren't harmless, and could mess up the natural job order.
This commit is contained in:
@@ -30,6 +30,16 @@ public:
|
|||||||
fJob._ClearTicketNumber();
|
fJob._ClearTicketNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetState(BJobState state)
|
||||||
|
{
|
||||||
|
fJob.SetState(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotifyStateListeners()
|
||||||
|
{
|
||||||
|
fJob.NotifyStateListeners();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BJob& fJob;
|
BJob& fJob;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -243,11 +243,18 @@ void
|
|||||||
JobQueue::_RequeueDependantJobsOf(BJob* job)
|
JobQueue::_RequeueDependantJobsOf(BJob* job)
|
||||||
{
|
{
|
||||||
while (BJob* dependantJob = job->DependantJobAt(0)) {
|
while (BJob* dependantJob = job->DependantJobAt(0)) {
|
||||||
|
JobPriorityQueue::iterator found = fQueuedJobs->find(dependantJob);
|
||||||
|
bool removed = false;
|
||||||
|
if (found != fQueuedJobs->end()) {
|
||||||
try {
|
try {
|
||||||
fQueuedJobs->erase(dependantJob);
|
fQueuedJobs->erase(dependantJob);
|
||||||
|
removed = true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
}
|
}
|
||||||
|
}
|
||||||
dependantJob->RemoveDependency(job);
|
dependantJob->RemoveDependency(job);
|
||||||
|
if (removed) {
|
||||||
|
// Only insert a job if it was in our queue before
|
||||||
try {
|
try {
|
||||||
fQueuedJobs->insert(dependantJob);
|
fQueuedJobs->insert(dependantJob);
|
||||||
if (dependantJob->IsRunnable())
|
if (dependantJob->IsRunnable())
|
||||||
@@ -256,6 +263,7 @@ JobQueue::_RequeueDependantJobsOf(BJob* job)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -266,8 +274,15 @@ JobQueue::_RemoveDependantJobsOf(BJob* job)
|
|||||||
fQueuedJobs->erase(dependantJob);
|
fQueuedJobs->erase(dependantJob);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dependantJob->State() != B_JOB_STATE_ABORTED) {
|
||||||
|
BJob::Private(*dependantJob).SetState(B_JOB_STATE_ABORTED);
|
||||||
|
BJob::Private(*dependantJob).NotifyStateListeners();
|
||||||
|
}
|
||||||
|
|
||||||
_RemoveDependantJobsOf(dependantJob);
|
_RemoveDependantJobsOf(dependantJob);
|
||||||
dependantJob->RemoveDependency(job);
|
dependantJob->RemoveDependency(job);
|
||||||
|
// TODO: we need some sort of ownership management
|
||||||
delete dependantJob;
|
delete dependantJob;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user