@@ -101,8 +101,10 @@ static final class ParallelDispatcher<T>
101
101
this .subscribers = subscribers ;
102
102
this .prefetch = prefetch ;
103
103
this .limit = prefetch - (prefetch >> 2 );
104
- this .requests = new AtomicLongArray (subscribers .length );
105
- this .emissions = new long [subscribers .length ];
104
+ int m = subscribers .length ;
105
+ this .requests = new AtomicLongArray (m + m + 1 );
106
+ this .requests .lazySet (m + m , m );
107
+ this .emissions = new long [m ];
106
108
}
107
109
108
110
@ Override
@@ -145,42 +147,56 @@ public void onSubscribe(Subscription s) {
145
147
}
146
148
147
149
void setupSubscribers () {
148
- final int m = subscribers .length ;
150
+ Subscriber <? super T >[] subs = subscribers ;
151
+ final int m = subs .length ;
149
152
150
153
for (int i = 0 ; i < m ; i ++) {
151
154
if (cancelled ) {
152
155
return ;
153
156
}
154
- final int j = i ;
155
157
156
158
subscriberCount .lazySet (i + 1 );
157
159
158
- subscribers [i ].onSubscribe (new Subscription () {
159
- @ Override
160
- public void request (long n ) {
161
- if (SubscriptionHelper .validate (n )) {
162
- AtomicLongArray ra = requests ;
163
- for (;;) {
164
- long r = ra .get (j );
165
- if (r == Long .MAX_VALUE ) {
166
- return ;
167
- }
168
- long u = BackpressureHelper .addCap (r , n );
169
- if (ra .compareAndSet (j , r , u )) {
170
- break ;
171
- }
172
- }
173
- if (subscriberCount .get () == m ) {
174
- drain ();
175
- }
160
+ subs [i ].onSubscribe (new RailSubscription (i , m ));
161
+ }
162
+ }
163
+
164
+ final class RailSubscription implements Subscription {
165
+
166
+ final int j ;
167
+
168
+ final int m ;
169
+
170
+ RailSubscription (int j , int m ) {
171
+ this .j = j ;
172
+ this .m = m ;
173
+ }
174
+
175
+ @ Override
176
+ public void request (long n ) {
177
+ if (SubscriptionHelper .validate (n )) {
178
+ AtomicLongArray ra = requests ;
179
+ for (;;) {
180
+ long r = ra .get (j );
181
+ if (r == Long .MAX_VALUE ) {
182
+ return ;
183
+ }
184
+ long u = BackpressureHelper .addCap (r , n );
185
+ if (ra .compareAndSet (j , r , u )) {
186
+ break ;
176
187
}
177
188
}
178
-
179
- @ Override
180
- public void cancel () {
181
- ParallelDispatcher .this .cancel ();
189
+ if (subscriberCount .get () == m ) {
190
+ drain ();
182
191
}
183
- });
192
+ }
193
+ }
194
+
195
+ @ Override
196
+ public void cancel () {
197
+ if (requests .compareAndSet (m + j , 0L , 1L )) {
198
+ ParallelDispatcher .this .cancel (m + m );
199
+ }
184
200
}
185
201
}
186
202
@@ -209,8 +225,8 @@ public void onComplete() {
209
225
drain ();
210
226
}
211
227
212
- void cancel () {
213
- if (! cancelled ) {
228
+ void cancel (int m ) {
229
+ if (requests . decrementAndGet ( m ) == 0L ) {
214
230
cancelled = true ;
215
231
this .s .cancel ();
216
232
@@ -268,7 +284,7 @@ void drainAsync() {
268
284
269
285
long ridx = r .get (idx );
270
286
long eidx = e [idx ];
271
- if (ridx != eidx ) {
287
+ if (ridx != eidx && r . get ( n + idx ) == 0 ) {
272
288
273
289
T v ;
274
290
@@ -356,7 +372,7 @@ void drainSync() {
356
372
357
373
long ridx = r .get (idx );
358
374
long eidx = e [idx ];
359
- if (ridx != eidx ) {
375
+ if (ridx != eidx && r . get ( n + idx ) == 0 ) {
360
376
361
377
T v ;
362
378
0 commit comments