Fix the WorkUnit race condition properly.

Also fixes a few other subtle issues.

Basically, async workunits are now closed when they're actually done,
or on error, and not after the work has been submitted. Not only
does this address the race condition where a parent workunit might
access a child before that child had been initialized, but it also
allows child outcomes to properly propagate to the parent.