##// END OF EJS Templates
fixed: the error handler should not handle handlers errors
cin -
r197:86187b01c4e0 default
parent child
Show More
@@ -1,142 +1,140
1 1 using System;
2 2 using Implab.Parallels;
3 3
4 4 namespace Implab {
5 5 public abstract class AbstractPromise : AbstractEvent<AbstractPromise.HandlerDescriptor>, IPromise {
6 6 public struct HandlerDescriptor {
7 7 readonly Action m_handler;
8 8 readonly Action<Exception> m_error;
9 9 readonly Action<Exception> m_cancel;
10 10 readonly PromiseEventType m_mask;
11 11
12 12 public HandlerDescriptor(Action success, Action<Exception> error, Action<Exception> cancel) {
13 13 m_handler = success;
14 14 m_error = error;
15 15 m_cancel = cancel;
16 16 m_mask = PromiseEventType.Success;
17 17 }
18 18
19 19 public HandlerDescriptor(Action handler, PromiseEventType mask) {
20 20 m_handler = handler;
21 21 m_error = null;
22 22 m_cancel = null;
23 23 m_mask = mask;
24 24 }
25 25
26 26 public void SignalSuccess() {
27 27 if ((m_mask & PromiseEventType.Success) != 0 && m_handler != null) {
28 28 try {
29 29 m_handler();
30 } catch (Exception err) {
31 // avoid calling handler twice in case of error
32 if (m_error != null)
33 SignalError(err);
30 // Analysis disable once EmptyGeneralCatchClause
31 } catch {
34 32 }
35 33 }
36 34 }
37 35
38 36 public void SignalError(Exception err) {
39 37 if (m_error != null) {
40 38 try {
41 39 m_error(err);
42 40 // Analysis disable once EmptyGeneralCatchClause
43 41 } catch {
44 42 }
45 43 } else if ((m_mask & PromiseEventType.Error ) != 0 && m_handler != null) {
46 44 try {
47 45 m_handler();
48 46 // Analysis disable once EmptyGeneralCatchClause
49 47 } catch {
50 48 }
51 49 }
52 50 }
53 51
54 52 public void SignalCancel(Exception reason) {
55 53 if (m_cancel != null) {
56 54 try {
57 55 m_cancel(reason);
58 } catch (Exception err) {
59 SignalError(err);
56 // Analysis disable once EmptyGeneralCatchClause
57 } catch {
60 58 }
61 59 } else if ( (m_mask & PromiseEventType.Cancelled) != 0 && m_handler != null) {
62 60 try {
63 61 m_handler();
64 62 // Analysis disable once EmptyGeneralCatchClause
65 63 } catch {
66 64 }
67 65 }
68 66 }
69 67 }
70 68
71 69
72 70 #region implemented abstract members of AbstractPromise
73 71
74 72 protected override void SignalHandler(HandlerDescriptor handler, int signal) {
75 73 switch (signal) {
76 74 case SUCCEEDED_STATE:
77 75 handler.SignalSuccess();
78 76 break;
79 77 case REJECTED_STATE:
80 78 handler.SignalError(Error);
81 79 break;
82 80 case CANCELLED_STATE:
83 81 handler.SignalCancel(CancellationReason);
84 82 break;
85 83 default:
86 84 throw new InvalidOperationException(String.Format("Invalid promise signal: {0}", signal));
87 85 }
88 86 }
89 87
90 88 protected override Signal GetResolveSignal() {
91 89 var signal = new Signal();
92 90 On(signal.Set, PromiseEventType.All);
93 91 return signal;
94 92 }
95 93
96 94 #endregion
97 95
98 96 public Type PromiseType {
99 97 get {
100 98 return typeof(void);
101 99 }
102 100 }
103 101
104 102 public IPromise On(Action success, Action<Exception> error, Action<Exception> cancel) {
105 103 AddHandler(new HandlerDescriptor(success, error, cancel));
106 104 return this;
107 105 }
108 106
109 107 public IPromise On(Action success, Action<Exception> error) {
110 108 AddHandler(new HandlerDescriptor(success, error, null));
111 109 return this;
112 110 }
113 111
114 112 public IPromise On(Action success) {
115 113 AddHandler(new HandlerDescriptor(success, null, null));
116 114 return this;
117 115 }
118 116
119 117 public IPromise On(Action handler, PromiseEventType events) {
120 118 AddHandler(new HandlerDescriptor(handler,events));
121 119 return this;
122 120 }
123 121
124 122 public IPromise<T> Cast<T>() {
125 123 throw new InvalidCastException();
126 124 }
127 125
128 126 public void Join() {
129 127 WaitResult(-1);
130 128 }
131 129
132 130 public void Join(int timeout) {
133 131 WaitResult(timeout);
134 132 }
135 133
136 134 protected void SetResult() {
137 135 if(BeginSetResult())
138 136 EndSetResult();
139 137 }
140 138 }
141 139 }
142 140
@@ -1,206 +1,204
1 1 using System;
2 2 using Implab.Parallels;
3 3
4 4 namespace Implab {
5 5 public abstract class AbstractPromise<T> : AbstractEvent<AbstractPromise<T>.HandlerDescriptor>, IPromise<T> {
6 6 public struct HandlerDescriptor {
7 7 readonly Action m_handler;
8 8 readonly Action<T> m_success;
9 9 readonly Action<Exception> m_error;
10 10 readonly Action<Exception> m_cancel;
11 11 readonly PromiseEventType m_mask;
12 12
13 13 public HandlerDescriptor(Action<T> success, Action<Exception> error, Action<Exception> cancel) {
14 14 m_success = success;
15 15 m_error = error;
16 16 m_cancel = cancel;
17 17
18 18 m_handler = null;
19 19 m_mask = 0;
20 20 }
21 21
22 22 public HandlerDescriptor(Action success, Action<Exception> error, Action<Exception> cancel) {
23 23 m_handler = success;
24 24 m_success = null;
25 25 m_error = error;
26 26 m_cancel = cancel;
27 27 m_mask = PromiseEventType.Success;
28 28 }
29 29
30 30 public HandlerDescriptor(Action handler, PromiseEventType mask) {
31 31 m_handler = handler;
32 32 m_mask = mask;
33 33 m_success = null;
34 34 m_error = null;
35 35 m_cancel = null;
36 36 }
37 37
38 38 public void SignalSuccess(T result) {
39 39 if (m_success != null) {
40 40 try {
41 41 m_success(result);
42 } catch(Exception err) {
43 SignalError(err);
42 // Analysis disable once EmptyGeneralCatchClause
43 } catch {
44 44 }
45 45 } else if ((m_mask & PromiseEventType.Success) != 0 && m_handler != null) {
46 46 try {
47 47 m_handler();
48 } catch(Exception err) {
49 // avoid calling handler twice in case of error
50 if (m_error != null)
51 SignalError(err);
48 // Analysis disable once EmptyGeneralCatchClause
49 } catch {
52 50 }
53 51 }
54 52 }
55 53
56 54 public void SignalError(Exception err) {
57 55 if (m_error != null) {
58 56 try {
59 57 m_error(err);
60 58 // Analysis disable once EmptyGeneralCatchClause
61 59 } catch {
62 60 }
63 61 } else if ((m_mask & PromiseEventType.Error) != 0 && m_handler != null) {
64 62 try {
65 63 m_handler();
66 64 // Analysis disable once EmptyGeneralCatchClause
67 65 } catch {
68 66 }
69 67 }
70 68 }
71 69
72 70 public void SignalCancel(Exception reason) {
73 71 if (m_cancel != null) {
74 72 try {
75 73 m_cancel(reason);
76 } catch (Exception err) {
77 SignalError(err);
74 // Analysis disable once EmptyGeneralCatchClause
75 } catch {
78 76 }
79 77 } else if ((m_mask & PromiseEventType.Cancelled) != 0 && m_handler != null) {
80 78 try {
81 79 m_handler();
82 80 // Analysis disable once EmptyGeneralCatchClause
83 81 } catch {
84 82 }
85 83 }
86 84 }
87 85 }
88 86
89 87 public Type PromiseType {
90 88 get {
91 89 return typeof(T);
92 90 }
93 91 }
94 92
95 93 public T Join() {
96 94 WaitResult(-1);
97 95 return m_result;
98 96 }
99 97 public T Join(int timeout) {
100 98 WaitResult(timeout);
101 99 return m_result;
102 100 }
103 101
104 102 void IPromise.Join() {
105 103 WaitResult(-1);
106 104 }
107 105 void IPromise.Join(int timeout) {
108 106 WaitResult(timeout);
109 107 }
110 108
111 109 public IPromise<T> On(Action<T> success, Action<Exception> error, Action<Exception> cancel) {
112 110 AddHandler(new HandlerDescriptor(success, error, cancel));
113 111 return this;
114 112 }
115 113
116 114 public IPromise<T> On(Action<T> success, Action<Exception> error) {
117 115 AddHandler(new HandlerDescriptor(success, error, null));
118 116 return this;
119 117 }
120 118
121 119 public IPromise<T> On(Action<T> success) {
122 120 AddHandler(new HandlerDescriptor(success, null, null));
123 121 return this;
124 122 }
125 123
126 124 public IPromise<T> On(Action handler, PromiseEventType events) {
127 125 AddHandler(new HandlerDescriptor(handler, events));
128 126 return this;
129 127 }
130 128
131 129 public IPromise<T> On(Action success, Action<Exception> error, Action<Exception> cancel) {
132 130 AddHandler(new HandlerDescriptor(success, error, cancel));
133 131 return this;
134 132 }
135 133
136 134 public IPromise<T> On(Action success, Action<Exception> error) {
137 135 AddHandler(new HandlerDescriptor(success, error, null));
138 136 return this;
139 137 }
140 138
141 139 public IPromise<T> On(Action success) {
142 140 AddHandler(new HandlerDescriptor(success, null, null));
143 141 return this;
144 142 }
145 143
146 144 IPromise IPromise.On(Action success, Action<Exception> error, Action<Exception> cancel) {
147 145 AddHandler(new HandlerDescriptor(success, error, cancel));
148 146 return this;
149 147 }
150 148
151 149 IPromise IPromise.On(Action success, Action<Exception> error) {
152 150 AddHandler(new HandlerDescriptor(success, error, null));
153 151 return this;
154 152 }
155 153
156 154 IPromise IPromise.On(Action success) {
157 155 AddHandler(new HandlerDescriptor(success, null, null));
158 156 return this;
159 157 }
160 158
161 159 IPromise IPromise.On(Action handler, PromiseEventType events) {
162 160 AddHandler(new HandlerDescriptor(handler, events));
163 161 return this;
164 162 }
165 163
166 164 public IPromise<T2> Cast<T2>() {
167 165 return (IPromise<T2>)this;
168 166 }
169 167
170 168 #region implemented abstract members of AbstractPromise
171 169
172 170 protected override Signal GetResolveSignal() {
173 171 var signal = new Signal();
174 172 AddHandler(new HandlerDescriptor(signal.Set, PromiseEventType.All));
175 173 return signal;
176 174 }
177 175
178 176 protected override void SignalHandler(HandlerDescriptor handler, int signal) {
179 177 switch (signal) {
180 178 case SUCCEEDED_STATE:
181 179 handler.SignalSuccess(m_result);
182 180 break;
183 181 case REJECTED_STATE:
184 182 handler.SignalError(Error);
185 183 break;
186 184 case CANCELLED_STATE:
187 185 handler.SignalCancel(CancellationReason);
188 186 break;
189 187 default:
190 188 throw new InvalidOperationException(String.Format("Invalid promise signal: {0}", signal));
191 189 }
192 190 }
193 191
194 192 #endregion
195 193
196 194 T m_result;
197 195
198 196 protected void SetResult(T value) {
199 197 if (BeginSetResult()) {
200 198 m_result = value;
201 199 EndSetResult();
202 200 }
203 201 }
204 202 }
205 203 }
206 204
General Comments 0
You need to be logged in to leave comments. Login now