aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Communications/RestClient/GenericAsyncResult.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/Communications/RestClient/GenericAsyncResult.cs')
-rw-r--r--OpenSim/Framework/Communications/RestClient/GenericAsyncResult.cs163
1 files changed, 163 insertions, 0 deletions
diff --git a/OpenSim/Framework/Communications/RestClient/GenericAsyncResult.cs b/OpenSim/Framework/Communications/RestClient/GenericAsyncResult.cs
new file mode 100644
index 0000000..4be459d
--- /dev/null
+++ b/OpenSim/Framework/Communications/RestClient/GenericAsyncResult.cs
@@ -0,0 +1,163 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Threading;
5
6namespace OpenSim.Framework.RestClient
7{
8 internal class SimpleAsyncResult : IAsyncResult
9 {
10
11 private readonly AsyncCallback m_callback;
12
13 /// <summary>
14 /// Is process completed?
15 /// </summary>
16 /// <remarks>Should really be boolean, but VolatileRead has no boolean method</remarks>
17 private byte m_completed;
18
19 /// <summary>
20 /// Did process complete synchroneously?
21 /// </summary>
22 /// <remarks>I have a hard time imagining a scenario where this is the case, again, same issue about
23 /// booleans and VolatileRead as m_completed
24 /// </remarks>
25 private byte m_completedSynchronously;
26
27 private readonly object m_asyncState;
28 private ManualResetEvent m_waitHandle;
29 private Exception m_exception;
30
31 internal SimpleAsyncResult(AsyncCallback cb, object state)
32 {
33 m_callback = cb;
34 m_asyncState = state;
35 m_completed = 0;
36 m_completedSynchronously = 1;
37 }
38
39
40 #region IAsyncResult Members
41
42 public object AsyncState
43 {
44 get { return m_asyncState; }
45 }
46
47
48
49 public WaitHandle AsyncWaitHandle
50 {
51 get
52 {
53 if (m_waitHandle == null)
54 {
55 bool done = IsCompleted;
56 ManualResetEvent mre = new ManualResetEvent(done);
57 if (Interlocked.CompareExchange(ref m_waitHandle, mre, null) != null)
58 {
59 mre.Close();
60 }
61 else
62 {
63 if (!done && IsCompleted)
64 {
65 m_waitHandle.Set();
66 }
67 }
68 }
69 return m_waitHandle;
70 }
71 }
72
73
74 public bool CompletedSynchronously
75 {
76 get { return Thread.VolatileRead(ref m_completedSynchronously) == 1; }
77 }
78
79
80 public bool IsCompleted
81 {
82 get { return Thread.VolatileRead(ref m_completed) == 1; }
83 }
84
85
86 #endregion
87
88
89 #region class Methods
90 internal void SetAsCompleted(bool completedSynchronously)
91 {
92 m_completed = 1;
93 if(completedSynchronously)
94 m_completedSynchronously = 1;
95 else
96 m_completedSynchronously = 0;
97
98 SignalCompletion();
99 }
100
101 internal void HandleException(Exception e, bool completedSynchronously)
102 {
103 m_completed = 1;
104 if (completedSynchronously)
105 m_completedSynchronously = 1;
106 else
107 m_completedSynchronously = 0;
108 m_exception = e;
109
110 SignalCompletion();
111 }
112
113 private void SignalCompletion()
114 {
115 if(m_waitHandle != null) m_waitHandle.Set();
116
117 if(m_callback != null) m_callback(this);
118 }
119
120 public void EndInvoke()
121 {
122 // This method assumes that only 1 thread calls EndInvoke
123 if (!IsCompleted)
124 {
125 // If the operation isn't done, wait for it
126 AsyncWaitHandle.WaitOne();
127 AsyncWaitHandle.Close();
128 m_waitHandle = null; // Allow early GC
129 }
130
131 // Operation is done: if an exception occured, throw it
132 if (m_exception != null) throw m_exception;
133 }
134
135 #endregion
136 }
137
138 internal class AsyncResult<T> : SimpleAsyncResult
139 {
140 private T m_result = default(T);
141
142 public AsyncResult(AsyncCallback asyncCallback, Object state) :
143 base(asyncCallback, state) { }
144
145
146 public void SetAsCompleted(T result, bool completedSynchronously)
147 {
148 // Save the asynchronous operation's result
149 m_result = result;
150
151 // Tell the base class that the operation completed
152 // sucessfully (no exception)
153 base.SetAsCompleted(completedSynchronously);
154 }
155
156 new public T EndInvoke()
157 {
158 base.EndInvoke();
159 return m_result;
160 }
161
162 }
163}