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 public object AsyncState => _asyncState;
46
47 protected AsyncCallback AsyncCallback => _asyncCallback;
48
50 {
51 get
52 {
53 _userEvent = true;
54 if (_intCompleted == 0)
55 {
56 Interlocked.CompareExchange(ref _intCompleted, int.MinValue, 0);
57 }
59 while (waitHandle == null)
60 {
61 LazilyCreateEvent(out waitHandle);
62 }
63 return waitHandle;
64 }
65 }
66
67 public bool CompletedSynchronously
68 {
69 get
70 {
71 int num = _intCompleted;
72 if (num == 0)
73 {
74 num = Interlocked.CompareExchange(ref _intCompleted, int.MinValue, 0);
75 }
76 return num > 0;
77 }
78 }
79
80 public bool IsCompleted
81 {
82 get
83 {
84 int num = _intCompleted;
85 if (num == 0)
86 {
87 num = Interlocked.CompareExchange(ref _intCompleted, int.MinValue, 0);
88 }
89 return (num & 0x7FFFFFFF) != 0;
90 }
91 }
92
93 internal bool InternalPeekCompleted => (_intCompleted & 0x7FFFFFFF) != 0;
94
95 internal bool EndCalled
96 {
97 get
98 {
99 return _endCalled;
100 }
101 set
102 {
104 }
105 }
106
107 internal LazyAsyncResult(object myObject, object myState, AsyncCallback myCallBack)
108 {
109 _asyncObject = myObject;
110 _asyncState = myState;
111 _asyncCallback = myCallBack;
113 if (System.Net.NetEventSource.Log.IsEnabled())
114 {
115 System.Net.NetEventSource.Info(this, null, ".ctor");
116 }
117 }
118
119 private bool LazilyCreateEvent(out ManualResetEvent waitHandle)
120 {
121 waitHandle = new ManualResetEvent(initialState: false);
122 try
123 {
124 if (Interlocked.CompareExchange(ref _event, waitHandle, null) == null)
125 {
127 {
128 waitHandle.Set();
129 }
130 return true;
131 }
132 waitHandle.Dispose();
133 waitHandle = (ManualResetEvent)_event;
134 return false;
135 }
136 catch
137 {
138 _event = null;
139 waitHandle?.Dispose();
140 throw;
141 }
142 }
143
144 protected void ProtectedInvokeCallback(object result, IntPtr userToken)
145 {
146 if (result == DBNull.Value)
147 {
148 throw new ArgumentNullException("result");
149 }
150 if (((uint)_intCompleted & 0x7FFFFFFFu) != 0 || (Interlocked.Increment(ref _intCompleted) & 0x7FFFFFFF) != 1)
151 {
152 return;
153 }
154 if (_result == DBNull.Value)
155 {
156 _result = result;
157 }
158 ManualResetEvent manualResetEvent = (ManualResetEvent)_event;
159 if (manualResetEvent != null)
160 {
161 try
162 {
163 manualResetEvent.Set();
164 }
166 {
167 }
168 }
169 Complete(userToken);
170 }
171
172 internal void InvokeCallback(object result)
173 {
175 }
176
177 internal void InvokeCallback()
178 {
180 }
181
182 protected virtual void Complete(IntPtr userToken)
183 {
184 bool flag = false;
185 ThreadContext currentThreadContext = CurrentThreadContext;
186 try
187 {
188 currentThreadContext._nestedIOCount++;
189 if (_asyncCallback != null)
190 {
191 if (System.Net.NetEventSource.Log.IsEnabled())
192 {
193 System.Net.NetEventSource.Info(this, "Invoking callback", "Complete");
194 }
195 if (currentThreadContext._nestedIOCount >= 50)
196 {
197 if (System.Net.NetEventSource.Log.IsEnabled())
198 {
199 System.Net.NetEventSource.Info(this, "*** OFFLOADED the user callback ****", "Complete");
200 }
201 Task.Factory.StartNew(delegate(object s)
202 {
205 flag = true;
206 }
207 else
208 {
209 _asyncCallback(this);
210 }
211 }
212 else if (System.Net.NetEventSource.Log.IsEnabled())
213 {
214 System.Net.NetEventSource.Info(this, "No callback to invoke", "Complete");
215 }
216 }
217 finally
218 {
219 currentThreadContext._nestedIOCount--;
220 if (!flag)
221 {
222 Cleanup();
223 }
224 }
225 }
226
227 private static void WorkerThreadComplete(object state)
228 {
229 LazyAsyncResult lazyAsyncResult = (LazyAsyncResult)state;
230 try
231 {
232 lazyAsyncResult._asyncCallback(lazyAsyncResult);
233 }
234 finally
235 {
236 lazyAsyncResult.Cleanup();
237 }
238 }
239
240 protected virtual void Cleanup()
241 {
242 }
243
245 {
246 return WaitForCompletion(snap: true);
247 }
248
249 private object WaitForCompletion(bool snap)
250 {
251 ManualResetEvent waitHandle = null;
252 bool flag = false;
253 if (!(snap ? IsCompleted : InternalPeekCompleted))
254 {
255 waitHandle = (ManualResetEvent)_event;
256 if (waitHandle == null)
257 {
258 flag = LazilyCreateEvent(out waitHandle);
259 }
260 }
261 if (waitHandle != null)
262 {
263 try
264 {
265 if (System.Net.NetEventSource.Log.IsEnabled())
266 {
267 System.Net.NetEventSource.Info(this, $"Waiting for completion event {waitHandle}", "WaitForCompletion");
268 }
269 waitHandle.WaitOne(-1);
270 }
272 {
273 }
274 finally
275 {
276 if (flag && !_userEvent)
277 {
278 ManualResetEvent manualResetEvent = (ManualResetEvent)_event;
279 _event = null;
280 if (!_userEvent)
281 {
282 manualResetEvent?.Dispose();
283 }
284 }
285 }
286 }
287 SpinWait spinWait = default(SpinWait);
288 while (_result == DBNull.Value)
289 {
290 spinWait.SpinOnce();
291 }
292 return _result;
293 }
294}
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