Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NPE in pollQueue #1354

Closed
Bananeweizen opened this issue Jun 11, 2014 · 5 comments
Closed

NPE in pollQueue #1354

Bananeweizen opened this issue Jun 11, 2014 · 5 comments

Comments

@Bananeweizen
Copy link

Since using 0.19 I see some sporadic NPEs where the complete stack trace contains only rx methods. Therefore I cannot really say what conditions in our code trigger that NPE.

06-11 23:18:24.060: E/AndroidRuntime(15279): java.lang.NullPointerException
06-11 23:18:24.060: E/AndroidRuntime(15279):    at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.pollQueue(OperatorObserveOn.java:135)
06-11 23:18:24.060: E/AndroidRuntime(15279):    at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.access$000(OperatorObserveOn.java:61)
06-11 23:18:24.060: E/AndroidRuntime(15279):    at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber$1.call(OperatorObserveOn.java:121)
06-11 23:18:24.060: E/AndroidRuntime(15279):    at rx.android.schedulers.HandlerThreadScheduler$InnerHandlerThreadScheduler$1.run(HandlerThreadScheduler.java:77)
06-11 23:18:24.060: E/AndroidRuntime(15279):    at android.os.Handler.handleCallback(Handler.java:733)
06-11 23:18:24.060: E/AndroidRuntime(15279):    at android.os.Handler.dispatchMessage(Handler.java:95)
06-11 23:18:24.060: E/AndroidRuntime(15279):    at android.os.Looper.loop(Looper.java:136)
06-11 23:18:24.060: E/AndroidRuntime(15279):    at android.app.ActivityThread.main(ActivityThread.java:5144)
06-11 23:18:24.060: E/AndroidRuntime(15279):    at java.lang.reflect.Method.invokeNative(Native Method)
06-11 23:18:24.060: E/AndroidRuntime(15279):    at java.lang.reflect.Method.invoke(Method.java:515)
06-11 23:18:24.060: E/AndroidRuntime(15279):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
06-11 23:18:24.060: E/AndroidRuntime(15279):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:611)
06-11 23:18:24.060: E/AndroidRuntime(15279):    at dalvik.system.NativeStart.main(Native Method)
´´´
@akarnokd
Copy link
Member

Hi. I can't see anything obviously wrong with the ObserveOn; it appears either vs is null or the vs.array is null, which both should be impossible since vs is never set to null and vs.array should contain an object array with at least a single value because the pollQueue is executed only after it has gained its first item. So either the AtomicLongFieldUpdater on Android doesn't behave correctly or JIT compilation generates incorrect code or memory fences.

@samueltardieu
Copy link
Contributor

@akarnokd : what if onNext is called twice at the same time? Wouldn't that cause a race condition, where both could execute their queue.add (successively since this part of code is synchronized), one of them would execute its schedule which calls pollQueue which empties the list, then the other does the same while the list is now empty?

If Murphy's law kicks in and one of the onNext is stopped for some time right before schedule, I don't immediately see anything to prevent this.

@samueltardieu
Copy link
Contributor

(I'm not sure this can happen though, as COUNTER_UPDATER would have gone to -1 at this time and a new pollQueue should not be scheduled as the initial state of the counter is not 0)

@akarnokd
Copy link
Member

You're right. The queue is of length 2 and the counter is decremented to -1 by pollQueue and then incremented to 0 by onNext without scheduling another pollQueue. Due to -1 and the == after addAndGet, it doesn't quit and now reads a FastList with null array. Changing the == 0 to > 0 should fix the problem. I can't do a PR until Monday.

@samueltardieu
Copy link
Contributor

I can do one in order to get some reviews (and I think you mean <= 0, or you want to put the test in the while part which also makes sense and seems even more readable to me).

Edit: putting it in the while would force to widen the scope of vs which is not elegant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants