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

Fix a potential memory leak in schedulePeriodically #2642

Merged
merged 3 commits into from
Feb 10, 2015
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions src/main/java/rx/Scheduler.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import rx.functions.Action0;
import rx.schedulers.Schedulers;
import rx.subscriptions.MultipleAssignmentSubscription;
import rx.subscriptions.SerialSubscription;

/**
* A {@code Scheduler} is an object that schedules units of work. You can find common implementations of this
Expand Down Expand Up @@ -119,11 +120,17 @@ public void call() {
if (!mas.isUnsubscribed()) {
action.call();
long nextTick = startInNanos + (++count * periodInNanos);
mas.set(schedule(this, nextTick - TimeUnit.MILLISECONDS.toNanos(now()), TimeUnit.NANOSECONDS));
SerialSubscription s = new SerialSubscription();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is no need to change this here: the initial SerialSubscription can safely overwritted by the result of the schedule as it is not reentrant.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean if period is large, the new Subscription created in the next action won't be able to replace the one here, and if period is small, the leak won't be a problem?

Just to make sure we are in the same page.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. I mean once the action is executed on the worker, each invocation of call is guaranteed to be serial, therefore, there is no need to have another level of SerialSubscription indirection.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha. Forgot it...

// Should call `mas.set` before `schedule`, or the new Subscription may replace the old one.
mas.set(s);
s.set(schedule(this, nextTick - TimeUnit.MILLISECONDS.toNanos(now()), TimeUnit.NANOSECONDS));
}
}
};
mas.set(schedule(recursiveAction, initialDelay, unit));
SerialSubscription s = new SerialSubscription();
// Should call `mas.set` before `schedule`, or the new Subscription may replace the old one.
mas.set(s);
s.set(schedule(recursiveAction, initialDelay, unit));
return mas;
}

Expand Down