Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
LazyAsyncResult.cs
Go to the documentation of this file.
3
4namespace System.Net;
5
6internal class LazyAsyncResult : IAsyncResult
7{
8 private class ThreadContext
9 {
10 internal int _nestedIOCount;
11 }
12
13 [ThreadStatic]
14 private static ThreadContext t_threadContext;
15
16 private readonly object _asyncObject;
17
18 private readonly object _asyncState;
19
20 private AsyncCallback _asyncCallback;
21
22 private object _result;
23
24 private int _intCompleted;
25
26 private bool _endCalled;
27
28 private bool _userEvent;
29
30 private object _event;
31
32 private static ThreadContext CurrentThreadContext
33 {
34 get
35 {
36 ThreadContext threadContext = t_threadContext;
37 if (threadContext == null)
38 {
39 threadContext = (t_threadContext = new ThreadContext());
40 }
41 return threadContext;
42 }
43 }
44
45 internal object AsyncObject => _asyncObject;
46
47 public object AsyncState => _asyncState;
48
49 protected AsyncCallback AsyncCallback => _asyncCallback;
50
52 {
53 get
54 {
55 _userEvent = true;
56 if (_intCompleted == 0)
57 {
58 Interlocked.CompareExchange(ref _intCompleted, int.MinValue, 0);
59 }
61 while (waitHandle == null)
62 {
63 LazilyCreateEvent(out waitHandle);
64 }
65 return waitHandle;
66 }
67 }
68
69 public bool CompletedSynchronously
70 {
71 get
72 {
73 int num = _intCompleted;
74 if (num == 0)
75 {
76 num = Interlocked.CompareExchange(ref _intCompleted, int.MinValue, 0);
77 }
78 return num > 0;
79 }
80 }
81
82 public bool IsCompleted
83 {
84 get
85 {
86 int num = _intCompleted;
87 if (num == 0)
88 {
89 num = Interlocked.CompareExchange(ref _intCompleted, int.MinValue, 0);
90 }
91 return (num & 0x7FFFFFFF) != 0;
92 }
93 }
94
95 internal bool InternalPeekCompleted => (_intCompleted & 0x7FFFFFFF) != 0;
96
97 internal object Result
98 {
99 get
100 {
101 if (_result != DBNull.Value)
102 {
103 return _result;
104 }
105 return null;
106 }
107 set
108 {
109 _result = value;
110 }
111 }
112
113 internal bool EndCalled
114 {
115 get
116 {
117 return _endCalled;
118 }
119 set
120 {
122 }
123 }
124
125 internal LazyAsyncResult(object myObject, object myState, AsyncCallback myCallBack)
126 {
127 _asyncObject = myObject;
128 _asyncState = myState;
129 _asyncCallback = myCallBack;
131 if (System.Net.NetEventSource.Log.IsEnabled())
132 {
133 System.Net.NetEventSource.Info(this, null, ".ctor");
134 }
135 }
136
137 private bool LazilyCreateEvent(out ManualResetEvent waitHandle)
138 {
139 waitHandle = new ManualResetEvent(initialState: false);
140 try
141 {
142 if (Interlocked.CompareExchange(ref _event, waitHandle, null) == null)
143 {
145 {
146 waitHandle.Set();
147 }
148 return true;
149 }
150 waitHandle.Dispose();
151 waitHandle = (ManualResetEvent)_event;
152 return false;
153 }
154 catch
155 {
156 _event = null;
157 waitHandle?.Dispose();
158 throw;
159 }
160 }
161
162 protected void ProtectedInvokeCallback(object result, IntPtr userToken)
163 {
164 if (result == DBNull.Value)
165 {
166 throw new ArgumentNullException("result");
167 }
168 if (((uint)_intCompleted & 0x7FFFFFFFu) != 0 || (Interlocked.Increment(ref _intCompleted) & 0x7FFFFFFF) != 1)
169 {
170 return;
171 }
172 if (_result == DBNull.Value)
173 {
174 _result = result;
175 }
176 ManualResetEvent manualResetEvent = (ManualResetEvent)_event;
177 if (manualResetEvent != null)
178 {
179 try
180 {
181 manualResetEvent.Set();
182 }
184 {
185 }
186 }
187 Complete(userToken);
188 }
189
190 internal void InvokeCallback(object result)
191 {
193 }
194
195 internal void InvokeCallback()
196 {
198 }
199
200 protected virtual void Complete(IntPtr userToken)
201 {
202 bool flag = false;
203 ThreadContext currentThreadContext = CurrentThreadContext;
204 try
205 {
206 currentThreadContext._nestedIOCount++;
207 if (_asyncCallback != null)
208 {
209 if (System.Net.NetEventSource.Log.IsEnabled())
210 {
211 System.Net.NetEventSource.Info(this, "Invoking callback", "Complete");
212 }
213 if (currentThreadContext._nestedIOCount >= 50)
214 {
215 if (System.Net.NetEventSource.Log.IsEnabled())
216 {
217 System.Net.NetEventSource.Info(this, "*** OFFLOADED the user callback ****", "Complete");
218 }
219 Task.Factory.StartNew(delegate(object s)
220 {
223 flag = true;
224 }
225 else
226 {
227 _asyncCallback(this);
228 }
229 }
230 else if (System.Net.NetEventSource.Log.IsEnabled())
231 {
232 System.Net.NetEventSource.Info(this, "No callback to invoke", "Complete");
233 }
234 }
235 finally
236 {
237 currentThreadContext._nestedIOCount--;
238 if (!flag)
239 {
240 Cleanup();
241 }
242 }
243 }
244
245 private static void WorkerThreadComplete(object state)
246 {
248 try
249 {
250 lazyAsyncResult._asyncCallback(lazyAsyncResult);
251 }
252 finally
253 {
254 lazyAsyncResult.Cleanup();
255 }
256 }
257
258 protected virtual void Cleanup()
259 {
260 }
261
263 {
264 return WaitForCompletion(snap: true);
265 }
266
267 private object WaitForCompletion(bool snap)
268 {
269 ManualResetEvent waitHandle = null;
270 bool flag = false;
271 if (!(snap ? IsCompleted : InternalPeekCompleted))
272 {
273 waitHandle = (ManualResetEvent)_event;
274 if (waitHandle == null)
275 {
276 flag = LazilyCreateEvent(out waitHandle);
277 }
278 }
279 if (waitHandle != null)
280 {
281 try
282 {
283 if (System.Net.NetEventSource.Log.IsEnabled())
284 {
285 System.Net.NetEventSource.Info(this, $"Waiting for completion event {waitHandle}", "WaitForCompletion");
286 }
287 waitHandle.WaitOne(-1);
288 }
290 {
291 }
292 finally
293 {
294 if (flag && !_userEvent)
295 {
296 ManualResetEvent manualResetEvent = (ManualResetEvent)_event;
297 _event = null;
298 if (!_userEvent)
299 {
300 manualResetEvent?.Dispose();
301 }
302 }
303 }
304 }
305 SpinWait spinWait = default(SpinWait);
306 while (_result == DBNull.Value)
307 {
308 spinWait.SpinOnce();
309 }
310 return _result;
311 }
312}
static readonly DBNull Value
Definition DBNull.cs:8
virtual void Complete(IntPtr userToken)
static ThreadContext CurrentThreadContext
bool LazilyCreateEvent(out ManualResetEvent waitHandle)
object WaitForCompletion(bool snap)
void ProtectedInvokeCallback(object result, IntPtr userToken)
LazyAsyncResult(object myObject, object myState, AsyncCallback myCallBack)
static ThreadContext t_threadContext
void InvokeCallback(object result)
static void WorkerThreadComplete(object state)
static readonly System.Net.NetEventSource Log
static void Info(object thisOrContextObject, FormattableString formattableString=null, [CallerMemberName] string memberName=null)
static int CompareExchange(ref int location1, int value, int comparand)
static int Increment(ref int location)
static new TaskFactory< TResult > Factory
Definition Task.cs:56
virtual void Dispose(bool explicitDisposing)
virtual bool WaitOne(int millisecondsTimeout)
static readonly IntPtr Zero
Definition IntPtr.cs:18