internal override void Execute() { TaskMetadata taskMetadata; Task task; lock (scheduler.resourcesLock) { if (!scheduler.tokenToTask.ContainsKey(taskToken)) { return; } task = scheduler.tokenToTask[taskToken]; taskMetadata = scheduler.taskToMetadata[task]; } if (!scheduler.resourceToTask.ContainsKey(resource)) { return; } //In case task is not locking the resource, do nothing if (scheduler.resourceToTask[resource] != task) { return; } else if (scheduler.resourceToTask[resource] == task) { //Change state of task taskMetadata.taskState = TaskMetadata.TaskState.Executing; //In case task is locking the resource, unlock it and notify the caller scheduler.resourceToTask.Remove(resource); //Give resource to first task waiting for it if (scheduler.tasksWaitingOnResources.ContainsKey(resource) && scheduler.tasksWaitingOnResources[resource].Count > 0) { (Task taskWaitingOnResource, EventWaitHandle taskWaitingOnResourceNotifier) = scheduler.FindLowestPriorityTaskWaitingOnResource(resource); scheduler.tasksWaitingOnResources[resource].Remove((taskWaitingOnResource, taskWaitingOnResourceNotifier)); lock (scheduler.resourcesLock) { if (scheduler.taskToToken.ContainsKey(taskWaitingOnResource)) { scheduler.eventQueue.Add(new TaskWantsToLockResourceEvent(scheduler, scheduler.taskToToken[taskWaitingOnResource], taskWaitingOnResourceNotifier, resource)); } } } //Set priority back to normal taskMetadata.VirtualPriority = taskMetadata.InitialPriority; taskMetadata.waitingOnResource = null; scheduler.Graph.RemoveEdge(resource, task); scheduler.taskHoldingResources[task].Remove(resource); //Notify our caller that he has released the resource successfully taskNotifier.Set(); //Queue new event for scheduling, because the virtual priority is dropping scheduler.eventQueue.Add(new ScheduleTasksEvent(scheduler)); } }