Skip to content

It is possible for HandlerScheduler$ScheduledRunnable.run to still be called on a disposed object #424

@stevelilly

Description

@stevelilly

I began investigating this as we have been seeing some strange crashes, where seemingly the only explanation was our subscriber was invoked after it was disposed (both the observe and the dispose in the main thread).

I have posted an example project here.
https://github.com/stevelilly/rxandroid-racecondition
Tested against rxandroid:2.0.2 + rxjava:2.1.13

This report is based on the belief that when running the following code in the main thread it should
not be possible to reach the exception:

Single.fromCallable(Object::new)
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(object -> {
        throw new IllegalStateException("should never be called");
    })
    .dispose();

After a few thousand calls I often encounter the exception. More interestingly, in the debugger
we can see that the HandlerScheduler$ScheduledRunnable has already been disposed, yet its run() method is still called.

Debugging run() on disposed Runnable

AFAICT the code in the HandlerScheduler is using removeCallbacks and removeCallbacksAndMessages in the proper way, however it appears it is not safe to call delegate.run() without first checking disposed.

This seems to affect API 24+ much more often than API 23 when I test it, but this could just be the
specific timings of my emulator.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions