-
Notifications
You must be signed in to change notification settings - Fork 7.6k
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
2.x: distinguish between sync and async dispose in ScheduledRunnable #5715
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -26,7 +26,12 @@ public final class ScheduledRunnable extends AtomicReferenceArray<Object> | |||
private static final long serialVersionUID = -6120223772001106981L; | ||||
final Runnable actual; | ||||
|
||||
static final Object DISPOSED = new Object(); | ||||
/** Indicates that the parent tracking this task has been notified about its completion. */ | ||||
static final Object PARENT_DISPOSED = new Object(); | ||||
/** Indicates the dispose() was called from within the run/call method. */ | ||||
static final Object SYNC_DISPOSED = new Object(); | ||||
/** Indicates the dispose() was called from another thread. */ | ||||
static final Object ASYNC_DISPOSED = new Object(); | ||||
|
||||
static final Object DONE = new Object(); | ||||
|
||||
|
@@ -66,13 +71,13 @@ public void run() { | |||
} finally { | ||||
lazySet(THREAD_INDEX, null); | ||||
Object o = get(PARENT_INDEX); | ||||
if (o != DISPOSED && o != null && compareAndSet(PARENT_INDEX, o, DONE)) { | ||||
if (o != PARENT_DISPOSED && compareAndSet(PARENT_INDEX, o, DONE) && o != null) { | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change of Though it doesn't affect Do we need that change? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. With the previous order, if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Makes sense, can you please add a test to cover that then? When I changed order back to original one on your branch, whole There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unit tests added. |
||||
((DisposableContainer)o).delete(this); | ||||
} | ||||
|
||||
for (;;) { | ||||
o = get(FUTURE_INDEX); | ||||
if (o == DISPOSED || compareAndSet(FUTURE_INDEX, o, DONE)) { | ||||
if (o == SYNC_DISPOSED || o == ASYNC_DISPOSED || compareAndSet(FUTURE_INDEX, o, DONE)) { | ||||
break; | ||||
} | ||||
} | ||||
|
@@ -85,8 +90,12 @@ public void setFuture(Future<?> f) { | |||
if (o == DONE) { | ||||
return; | ||||
} | ||||
if (o == DISPOSED) { | ||||
f.cancel(get(THREAD_INDEX) != Thread.currentThread()); | ||||
if (o == SYNC_DISPOSED) { | ||||
f.cancel(false); | ||||
return; | ||||
} | ||||
if (o == ASYNC_DISPOSED) { | ||||
f.cancel(true); | ||||
return; | ||||
} | ||||
if (compareAndSet(FUTURE_INDEX, o, f)) { | ||||
|
@@ -99,23 +108,24 @@ public void setFuture(Future<?> f) { | |||
public void dispose() { | ||||
for (;;) { | ||||
Object o = get(FUTURE_INDEX); | ||||
if (o == DONE || o == DISPOSED) { | ||||
if (o == DONE || o == SYNC_DISPOSED || o == ASYNC_DISPOSED) { | ||||
break; | ||||
} | ||||
if (compareAndSet(FUTURE_INDEX, o, DISPOSED)) { | ||||
boolean async = get(THREAD_INDEX) != Thread.currentThread(); | ||||
if (compareAndSet(FUTURE_INDEX, o, async ? ASYNC_DISPOSED : SYNC_DISPOSED)) { | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm, what worries me here is that we base
Yes, it's The worst scenario is that if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cancelling from the current thread could only happen while the Since we are running with single-threaded thread pools, any subsequent task on the same pool having the same Thread will find the references marked as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Aha, I see now, 👍 |
||||
if (o != null) { | ||||
((Future<?>)o).cancel(get(THREAD_INDEX) != Thread.currentThread()); | ||||
((Future<?>)o).cancel(async); | ||||
} | ||||
break; | ||||
} | ||||
} | ||||
|
||||
for (;;) { | ||||
Object o = get(PARENT_INDEX); | ||||
if (o == DONE || o == DISPOSED || o == null) { | ||||
if (o == DONE || o == PARENT_DISPOSED || o == null) { | ||||
return; | ||||
} | ||||
if (compareAndSet(PARENT_INDEX, o, DISPOSED)) { | ||||
if (compareAndSet(PARENT_INDEX, o, PARENT_DISPOSED)) { | ||||
((DisposableContainer)o).delete(this); | ||||
return; | ||||
} | ||||
|
@@ -124,7 +134,7 @@ public void dispose() { | |||
|
||||
@Override | ||||
public boolean isDisposed() { | ||||
Object o = get(FUTURE_INDEX); | ||||
return o == DISPOSED || o == DONE; | ||||
Object o = get(PARENT_INDEX); | ||||
return o == PARENT_DISPOSED || o == DONE; | ||||
} | ||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
supernit:
ASYNC
doesn't mean another thread :)But for name conciseness I guess it's fine