20
20
21
21
import rx .*;
22
22
import rx .Observable .OnSubscribe ;
23
+ import rx .exceptions .Exceptions ;
23
24
24
25
/**
25
26
* Converts an {@code Iterable} sequence into an {@code Observable}.
@@ -42,11 +43,25 @@ public OnSubscribeFromIterable(Iterable<? extends T> iterable) {
42
43
43
44
@ Override
44
45
public void call (final Subscriber <? super T > o ) {
45
- final Iterator <? extends T > it = is .iterator ();
46
- if (!it .hasNext () && !o .isUnsubscribed ())
47
- o .onCompleted ();
48
- else
49
- o .setProducer (new IterableProducer <T >(o , it ));
46
+ final Iterator <? extends T > it ;
47
+ boolean b ;
48
+
49
+ try {
50
+ it = is .iterator ();
51
+
52
+ b = it .hasNext ();
53
+ } catch (Throwable ex ) {
54
+ Exceptions .throwOrReport (ex , o );
55
+ return ;
56
+ }
57
+
58
+ if (!o .isUnsubscribed ()) {
59
+ if (!b ) {
60
+ o .onCompleted ();
61
+ } else {
62
+ o .setProducer (new IterableProducer <T >(o , it ));
63
+ }
64
+ }
50
65
}
51
66
52
67
private static final class IterableProducer <T > extends AtomicLong implements Producer {
@@ -81,55 +96,98 @@ void slowpath(long n) {
81
96
final Iterator <? extends T > it = this .it ;
82
97
83
98
long r = n ;
84
- while (true ) {
85
- /*
86
- * This complicated logic is done to avoid touching the
87
- * volatile `requested` value during the loop itself. If
88
- * it is touched during the loop the performance is
89
- * impacted significantly.
90
- */
91
- long numToEmit = r ;
92
- while (true ) {
99
+ long e = 0 ;
100
+
101
+ for (;;) {
102
+ while (e != r ) {
93
103
if (o .isUnsubscribed ()) {
94
104
return ;
95
- } else if (it .hasNext ()) {
96
- if (--numToEmit >= 0 ) {
97
- o .onNext (it .next ());
98
- } else
99
- break ;
100
- } else if (!o .isUnsubscribed ()) {
101
- o .onCompleted ();
105
+ }
106
+
107
+ T value ;
108
+
109
+ try {
110
+ value = it .next ();
111
+ } catch (Throwable ex ) {
112
+ Exceptions .throwOrReport (ex , o );
102
113
return ;
103
- } else {
104
- // is unsubscribed
114
+ }
115
+
116
+ o .onNext (value );
117
+
118
+ if (o .isUnsubscribed ()) {
105
119
return ;
106
120
}
121
+
122
+ boolean b ;
123
+
124
+ try {
125
+ b = it .hasNext ();
126
+ } catch (Throwable ex ) {
127
+ Exceptions .throwOrReport (ex , o );
128
+ return ;
129
+ }
130
+
131
+ if (!b ) {
132
+ if (!o .isUnsubscribed ()) {
133
+ o .onCompleted ();
134
+ }
135
+ return ;
136
+ }
137
+
138
+ e ++;
107
139
}
108
- r = addAndGet (-r );
109
- if (r == 0L ) {
110
- // we're done emitting the number requested so
111
- // return
112
- return ;
140
+
141
+ r = get ();
142
+ if (e == r ) {
143
+ r = BackpressureUtils .produced (this , e );
144
+ if (r == 0L ) {
145
+ break ;
146
+ }
147
+ e = 0L ;
113
148
}
114
-
115
149
}
150
+
116
151
}
117
152
118
153
void fastpath () {
119
154
// fast-path without backpressure
120
155
final Subscriber <? super T > o = this .o ;
121
156
final Iterator <? extends T > it = this .it ;
122
157
123
- while ( true ) {
158
+ for (;; ) {
124
159
if (o .isUnsubscribed ()) {
125
160
return ;
126
- } else if (it .hasNext ()) {
127
- o .onNext (it .next ());
128
- } else if (!o .isUnsubscribed ()) {
129
- o .onCompleted ();
161
+ }
162
+
163
+ T value ;
164
+
165
+ try {
166
+ value = it .next ();
167
+ } catch (Throwable ex ) {
168
+ Exceptions .throwOrReport (ex , o );
169
+ return ;
170
+ }
171
+
172
+ o .onNext (value );
173
+
174
+ if (o .isUnsubscribed ()) {
130
175
return ;
131
- } else {
132
- // is unsubscribed
176
+ }
177
+
178
+ boolean b ;
179
+
180
+ try {
181
+ b = it .hasNext ();
182
+ } catch (Throwable ex ) {
183
+ Exceptions .throwOrReport (ex , o );
184
+ return ;
185
+ }
186
+
187
+ if (!b ) {
188
+ if (!o .isUnsubscribed ()) {
189
+ o .onCompleted ();
190
+ }
133
191
return ;
134
192
}
135
193
}
0 commit comments