15
15
*/
16
16
package rx .operators ;
17
17
18
- import java .util .LinkedHashSet ;
19
- import java .util .Set ;
20
18
import java .util .concurrent .ConcurrentLinkedQueue ;
21
19
import java .util .concurrent .atomic .AtomicBoolean ;
22
20
import java .util .concurrent .atomic .AtomicReference ;
@@ -59,14 +57,8 @@ static final class State<T> {
59
57
final NotificationLite <T > nl = NotificationLite .instance ();
60
58
/** The first observer or the one which buffers until the first arrives. */
61
59
final AtomicReference <Observer <? super T >> observerRef = new AtomicReference <Observer <? super T >>(new BufferedObserver <T >());
62
- /** How many subscribers . */
60
+ /** Allow a single subscriber only . */
63
61
final AtomicBoolean first = new AtomicBoolean ();
64
- /** The rest of the subscribers without buffering. Guarded by this. */
65
- final Set <Subscriber <? super T >> subscribers = new LinkedHashSet <Subscriber <? super T >>();
66
- /** Guarded by this. */
67
- boolean done ;
68
- /** Guarded by this. */
69
- Throwable exception ;
70
62
}
71
63
72
64
static final class OnSubscribeAction <T > implements OnSubscribe <T > {
@@ -95,33 +87,7 @@ public void call() {
95
87
}
96
88
}));
97
89
} else {
98
- Throwable e = null ;
99
- boolean done ;
100
- synchronized (state ) {
101
- done = state .done ;
102
- if (!done ) {
103
- state .subscribers .add (s );
104
- } else {
105
- e = state .exception ;
106
- }
107
- }
108
- if (done ) {
109
- if (e != null ) {
110
- s .onError (e );
111
- } else {
112
- s .onCompleted ();
113
- }
114
- return ;
115
- }
116
- s .add (Subscriptions .create (new Action0 () {
117
-
118
- @ Override
119
- public void call () {
120
- synchronized (state ) {
121
- state .subscribers .remove (s );
122
- }
123
- }
124
- }));
90
+ s .onError (new IllegalStateException ("Only one subscriber allowed!" ));
125
91
}
126
92
}
127
93
@@ -136,64 +102,17 @@ private BufferUntilSubscriber(State<T> state) {
136
102
@ Override
137
103
public void onCompleted () {
138
104
state .observerRef .get ().onCompleted ();
139
- // notify the rest
140
- Subscriber <?>[] list ;
141
- synchronized (state ) {
142
- if (!state .done ) {
143
- return ;
144
- }
145
- state .done = true ;
146
- if (state .subscribers .isEmpty ()) {
147
- return ;
148
- }
149
- list = state .subscribers .toArray (new Subscriber <?>[state .subscribers .size ()]);
150
- state .subscribers .clear ();
151
- }
152
- for (Subscriber <?> s : list ) {
153
- s .onCompleted ();
154
- }
155
105
}
156
106
157
107
@ Override
158
108
public void onError (Throwable e ) {
159
109
state .observerRef .get ().onError (e );
160
- // notify the rest
161
- Subscriber <?>[] list ;
162
- synchronized (state ) {
163
- if (!state .done ) {
164
- return ;
165
- }
166
- state .done = true ;
167
- state .exception = e ;
168
- if (state .subscribers .isEmpty ()) {
169
- return ;
170
- }
171
- list = state .subscribers .toArray (new Subscriber <?>[state .subscribers .size ()]);
172
- state .subscribers .clear ();
173
- }
174
- for (Subscriber <?> s : list ) {
175
- s .onError (e );
176
- }
177
110
}
178
111
179
112
@ Override
180
113
@ SuppressWarnings ({ "unchecked" , "rawtypes" })
181
114
public void onNext (T t ) {
182
115
state .observerRef .get ().onNext (t );
183
- // notify the rest
184
- Subscriber [] list ;
185
- synchronized (state ) {
186
- if (state .done ) {
187
- return ;
188
- }
189
- if (state .subscribers .isEmpty ()) {
190
- return ;
191
- }
192
- list = state .subscribers .toArray (new Subscriber [state .subscribers .size ()]);
193
- }
194
- for (Subscriber s : list ) {
195
- s .onNext (t );
196
- }
197
116
}
198
117
199
118
/**
@@ -242,6 +161,7 @@ private void drainIfNeededAndSwitchToActual() {
242
161
nl .accept (this , o );
243
162
}
244
163
// now we can safely change over to the actual and get rid of the pass-thru
164
+ // but only if not unsubscribed
245
165
observerRef .compareAndSet (this , actual );
246
166
}
247
167
0 commit comments