Ejemplo n.º 1
0
            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));
                }
            }