@@ -37,9 +37,17 @@ public abstract class CompletionSource
3737
3838 public sealed class CompletionSource < T > : CompletionSource
3939 {
40- AsyncValueTaskMethodBuilder < T > _amb = AsyncValueTaskMethodBuilder < T > . Create ( ) ;
40+ AsyncValueTaskMethodBuilder < T > _amb ;
4141
42- public ValueTask < T > Task => _amb . Task ;
42+ public ValueTask < T > Task { get ; }
43+
44+ public CompletionSource ( )
45+ {
46+ _amb = AsyncValueTaskMethodBuilder < T > . Create ( ) ;
47+ // AsyncValueTaskMethodBuilder's Task and SetResult aren't thread safe in regard to each other
48+ // Which is why we access it prematurely
49+ Task = _amb . Task ;
50+ }
4351
4452 public void SetResult ( T value )
4553 => _amb . SetResult ( value ) ;
@@ -50,9 +58,17 @@ public override void SetException(Exception exception)
5058
5159 public sealed class PoolingCompletionSource < T > : CompletionSource
5260 {
53- PoolingAsyncValueTaskMethodBuilder < T > _amb = PoolingAsyncValueTaskMethodBuilder < T > . Create ( ) ;
61+ PoolingAsyncValueTaskMethodBuilder < T > _amb ;
5462
55- public ValueTask < T > Task => _amb . Task ;
63+ public ValueTask < T > Task { get ; }
64+
65+ public PoolingCompletionSource ( )
66+ {
67+ _amb = PoolingAsyncValueTaskMethodBuilder < T > . Create ( ) ;
68+ // PoolingAsyncValueTaskMethodBuilder's Task and SetResult aren't thread safe in regard to each other
69+ // Which is why we access it prematurely
70+ Task = _amb . Task ;
71+ }
5672
5773 public void SetResult ( T value )
5874 => _amb . SetResult ( value ) ;
@@ -90,7 +106,7 @@ public CompletionSourceContinuation(object handle, delegate*<Task, CompletionSou
90106 if ( task . IsCompletedSuccessfully )
91107 return new ( new T ? ( task . Result ) ) ;
92108
93- // Otherwise we do one additional allocation, this allow us to share state machine codegen for all Ts.
109+ // Otherwise we do one additional allocation, this allows us to share state machine codegen for all Ts.
94110 var source = new PoolingCompletionSource < T ? > ( ) ;
95111 OnCompletedWithSource ( task . AsTask ( ) , source , new ( instance , & UnboxAndComplete ) ) ;
96112 return source . Task ;
@@ -111,7 +127,7 @@ public static unsafe ValueTask<T> ReadAsObjectAsyncAsT<T>(this PgConverter<T> in
111127 if ( task . IsCompletedSuccessfully )
112128 return new ( ( T ) task . Result ) ;
113129
114- // Otherwise we do one additional allocation, this allow us to share state machine codegen for all Ts.
130+ // Otherwise we do one additional allocation, this allows us to share state machine codegen for all Ts.
115131 var source = new PoolingCompletionSource < T > ( ) ;
116132 OnCompletedWithSource ( task . AsTask ( ) , source , new ( instance , & UnboxAndComplete ) ) ;
117133 return source . Task ;
0 commit comments