Skip to content

Commit 45ef556

Browse files
committed
cold tasks only
1 parent 5af1568 commit 45ef556

11 files changed

+738
-214
lines changed

src/IcedTasks/CancellablePoolingValueTask.fs

Lines changed: 83 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -54,35 +54,59 @@ module CancellablePoolingValueTasks =
5454
let initialResumptionFunc =
5555
CancellableTaskBaseResumptionFunc<'T, _>(fun sm -> code.Invoke(&sm))
5656

57-
let resumptionInfo =
57+
let resumptionInfo () =
58+
let mutable state = InitialYield
59+
5860
{ new CancellableTaskBaseResumptionDynamicInfo<'T, _>(initialResumptionFunc) with
5961
member info.MoveNext(sm) =
60-
let mutable savedExn = null
61-
62-
try
63-
sm.ResumptionDynamicInfo.ResumptionData <- null
64-
let step = info.ResumptionFunc.Invoke(&sm)
65-
66-
if step then
67-
MethodBuilder.SetResult(&sm.Data.MethodBuilder, sm.Data.Result)
68-
else
69-
match sm.ResumptionDynamicInfo.ResumptionData with
70-
| :? ICriticalNotifyCompletion as awaiter ->
71-
let mutable awaiter = awaiter
72-
// assert not (isNull awaiter)
73-
MethodBuilder.AwaitOnCompleted(
74-
&sm.Data.MethodBuilder,
75-
&awaiter,
76-
&sm
77-
)
78-
| awaiter -> assert not (isNull awaiter)
79-
80-
with exn ->
81-
savedExn <- exn
82-
// Run SetException outside the stack unwind, see https://github.com/dotnet/roslyn/issues/26567
83-
match savedExn with
84-
| null -> ()
85-
| exn -> MethodBuilder.SetException(&sm.Data.MethodBuilder, exn)
62+
let current = state
63+
let mutable continuation = Stop
64+
65+
match current with
66+
| InitialYield ->
67+
state <- Running
68+
69+
continuation <-
70+
if BindContext.CheckWhenIsBind() then Bounce else Immediate
71+
| Running ->
72+
try
73+
let step = info.ResumptionFunc.Invoke(&sm)
74+
75+
if step then
76+
state <- SetResult
77+
78+
continuation <-
79+
if BindContext.Check() then Bounce else Immediate
80+
else
81+
continuation <-
82+
Await(downcast sm.ResumptionDynamicInfo.ResumptionData)
83+
with exn ->
84+
state <- SetException(ExceptionCache.CaptureOrRetrieve exn)
85+
continuation <- if BindContext.Check() then Bounce else Immediate
86+
| SetResult ->
87+
MethodBuilder.SetResult(&sm.Data.MethodBuilder, sm.Data.Result)
88+
| SetException edi ->
89+
MethodBuilder.SetException(&sm.Data.MethodBuilder, edi.SourceException)
90+
91+
let continuation = continuation
92+
93+
match continuation with
94+
| Stop -> ()
95+
| Immediate -> info.MoveNext(&sm)
96+
| Bounce ->
97+
MethodBuilder.AwaitOnCompleted(
98+
&sm.Data.MethodBuilder,
99+
Trampoline.AwaiterRef,
100+
&sm
101+
)
102+
| Await awaiter ->
103+
let mutable awaiter = awaiter
104+
105+
MethodBuilder.AwaitUnsafeOnCompleted(
106+
&sm.Data.MethodBuilder,
107+
&awaiter,
108+
&sm
109+
)
86110

87111
member _.SetStateMachine(sm, state) =
88112
MethodBuilder.SetStateMachine(&sm.Data.MethodBuilder, state)
@@ -93,7 +117,7 @@ module CancellablePoolingValueTasks =
93117
ValueTask.FromCanceled<_>(ct)
94118
else
95119
sm.Data.CancellationToken <- ct
96-
sm.ResumptionDynamicInfo <- resumptionInfo
120+
sm.ResumptionDynamicInfo <- resumptionInfo ()
97121
sm.Data.MethodBuilder <- PoolingAsyncValueTaskMethodBuilder<'T>.Create()
98122
sm.Data.MethodBuilder.Start(&sm)
99123
sm.Data.MethodBuilder.Task
@@ -103,22 +127,36 @@ module CancellablePoolingValueTasks =
103127
if __useResumableCode then
104128
__stateMachine<CancellableTaskBaseStateMachineData<'T, _>, CancellableValueTask<'T>>
105129
(MoveNextMethodImpl<_>(fun sm ->
106-
//-- RESUMABLE CODE START
107130
__resumeAt sm.ResumptionPoint
108-
let mutable __stack_exn = null
109-
110-
try
111-
let __stack_code_fin = code.Invoke(&sm)
112-
113-
if __stack_code_fin then
114-
MethodBuilder.SetResult(&sm.Data.MethodBuilder, sm.Data.Result)
115-
with exn ->
116-
__stack_exn <- exn
117-
// Run SetException outside the stack unwind, see https://github.com/dotnet/roslyn/issues/26567
118-
match __stack_exn with
119-
| null -> ()
120-
| exn -> MethodBuilder.SetException(&sm.Data.MethodBuilder, exn)
121-
//-- RESUMABLE CODE END
131+
let mutable error = ValueNone
132+
133+
let __stack_go1 = yieldOnBindLimitWhenIsBind().Invoke(&sm)
134+
135+
if __stack_go1 then
136+
try
137+
let __stack_code_fin = code.Invoke(&sm)
138+
139+
if __stack_code_fin then
140+
let __stack_go2 = yieldOnBindLimit().Invoke(&sm)
141+
142+
if __stack_go2 then
143+
MethodBuilder.SetResult(
144+
&sm.Data.MethodBuilder,
145+
sm.Data.Result
146+
)
147+
with exn ->
148+
error <-
149+
ValueSome
150+
<| ExceptionCache.CaptureOrRetrieve exn
151+
152+
if error.IsSome then
153+
let __stack_go2 = yieldOnBindLimit().Invoke(&sm)
154+
155+
if __stack_go2 then
156+
MethodBuilder.SetException(
157+
&sm.Data.MethodBuilder,
158+
error.Value.SourceException
159+
)
122160
))
123161
(SetStateMachineMethodImpl<_>(fun sm state ->
124162
MethodBuilder.SetStateMachine(&sm.Data.MethodBuilder, state)
@@ -148,6 +186,8 @@ module CancellablePoolingValueTasks =
148186
([<InlineIfLambda>] x: CancellationToken -> ValueTask<_>)
149187
: CancellationToken -> Awaiter<ValueTaskAwaiter<_>, _> =
150188
fun ct ->
189+
BindContext.SetIsBind()
190+
151191
(x ct)
152192
|> Awaitable.GetAwaiter
153193

0 commit comments

Comments
 (0)