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