History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: PSL-108
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Jens Halm
Reporter: Staffan Eketorp
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
Parsley - Spicelib

ConcurrentTaskGroup issue when adding a Task while the doStart method is executing

Created: 02/Apr/08 05:25 PM   Updated: 20/Sep/09 10:39 PM
Component/s: Spicelib Task Framework
Affects Version/s: None
Fix Version/s: Spicelib 1.0.1


 Description  « Hide
Consider the following code. It will crash

public function test():void {
var group:ConcurrentTaskGroup = new ConcurrentTaskGroup();
group.addTask(new CommandTask(new Command(first, [group])));
group.start();

 }

public function first(group:TaskGroup):void {
group.addTask(new CommandTask(new Command(second)));
}

public function second():void {}

The error occurs since the loop in ConcurrentTaskGroup.doStart does not care if tasks have been created as a result of former tasks so that the allTasks collection changes. Thus, my recommended ConcurrentTask.doStart function looks like:

protected override function doStart () : void {
if (allTasks.isEmpty()) {
complete();
return;
}

var beginTasks:Array = new Array();
for (var i : Number = 0; i < allTasks.getSize(); i++)
beginTasks.push(allTasks.get(i));

for each(var t:Task in beginTasks)
startTask(t);
}

 All   Comments   Change History      Sort Order:
Staffan Eketorp - 04/Apr/08 11:10 AM - edited
Found an issue with my suggestion. Haven't checked but I suppose it should be an issue with the "old" code as well. Consider the following scenario

Add two tasks to a concurrent task group that completes immediatly (in their doStart). Then the handleTaskComplete function will check the condition
activeTasks.isEmpty() && state == TaskState.ACTIVE
when the first task completes, and the statement above will be true since the second task hasn't been added to the activeTasks collection yet and thus the task group will complete, which is erronous.

Thus my new ConcurrentTaskGroup.doStart looks like:

protected override function doStart () : void {
if (allTasks.isEmpty()) {
complete();
return;
}

var beginTasks:Array = new Array();
for (var i : Number = 0; i < allTasks.getSize(); i++)
{
activeTasks.append(allTasks.get(i));
beginTasks.push(allTasks.get(i));
}

for each(var t:Task in beginTasks)
startTask(t);
}

Jens Halm - 07/Apr/08 06:01 PM
I applied the fix with the suggested logic, just with a different syntax. Thanks for spotting this.
There is also a new UnitTest for this scenario: TaskTest.testAddTaskWhileDoStartExecutes