Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
30bc77f2
authored
May 13, 2020
by
olly
Committed by
Oliver Woodman
May 14, 2020
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Prevent leaking of the Thread.interrupt flag to other LoadTasks
PiperOrigin-RevId: 311290214
parent
df0d115b
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
45 additions
and
19 deletions
library/core/src/main/java/com/google/android/exoplayer2/upstream/Loader.java
library/core/src/main/java/com/google/android/exoplayer2/upstream/Loader.java
View file @
30bc77f2
...
@@ -32,6 +32,7 @@ import java.lang.annotation.Documented;
...
@@ -32,6 +32,7 @@ import java.lang.annotation.Documented;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.RetentionPolicy
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.atomic.AtomicBoolean
;
/**
/**
* Manages the background loading of {@link Loadable}s.
* Manages the background loading of {@link Loadable}s.
...
@@ -56,6 +57,21 @@ public final class Loader implements LoaderErrorThrower {
...
@@ -56,6 +57,21 @@ public final class Loader implements LoaderErrorThrower {
/**
/**
* Cancels the load.
* Cancels the load.
*
* <p>Loadable implementations should ensure that a currently executing {@link #load()} call
* will exit reasonably quickly after this method is called. The {@link #load()} call may exit
* either by returning or by throwing an {@link IOException}.
*
* <p>If there is a currently executing {@link #load()} call, then the thread on which that call
* is being made will be interrupted immediately after the call to this method. Hence
* implementations do not need to (and should not attempt to) interrupt the loading thread
* themselves.
*
* <p>Although the loading thread will be interrupted, Loadable implementations should not use
* the interrupted status of the loading thread in {@link #load()} to determine whether the load
* has been canceled. This approach is not robust [Internal ref: b/79223737]. Instead,
* implementations should use their own flag to signal cancelation (for example, using {@link
* AtomicBoolean}).
*/
*/
void
cancelLoad
();
void
cancelLoad
();
...
@@ -307,10 +323,9 @@ public final class Loader implements LoaderErrorThrower {
...
@@ -307,10 +323,9 @@ public final class Loader implements LoaderErrorThrower {
private
static
final
String
TAG
=
"LoadTask"
;
private
static
final
String
TAG
=
"LoadTask"
;
private
static
final
int
MSG_START
=
0
;
private
static
final
int
MSG_START
=
0
;
private
static
final
int
MSG_CANCEL
=
1
;
private
static
final
int
MSG_FINISH
=
1
;
private
static
final
int
MSG_END_OF_SOURCE
=
2
;
private
static
final
int
MSG_IO_EXCEPTION
=
2
;
private
static
final
int
MSG_IO_EXCEPTION
=
3
;
private
static
final
int
MSG_FATAL_ERROR
=
3
;
private
static
final
int
MSG_FATAL_ERROR
=
4
;
public
final
int
defaultMinRetryCount
;
public
final
int
defaultMinRetryCount
;
...
@@ -321,8 +336,8 @@ public final class Loader implements LoaderErrorThrower {
...
@@ -321,8 +336,8 @@ public final class Loader implements LoaderErrorThrower {
@Nullable
private
IOException
currentError
;
@Nullable
private
IOException
currentError
;
private
int
errorCount
;
private
int
errorCount
;
@Nullable
private
volatile
Thread
executorThread
;
@Nullable
private
Thread
executorThread
;
private
volatile
boolean
canceled
;
private
boolean
canceled
;
private
volatile
boolean
released
;
private
volatile
boolean
released
;
public
LoadTask
(
Looper
looper
,
T
loadable
,
Loader
.
Callback
<
T
>
callback
,
public
LoadTask
(
Looper
looper
,
T
loadable
,
Loader
.
Callback
<
T
>
callback
,
...
@@ -354,16 +369,21 @@ public final class Loader implements LoaderErrorThrower {
...
@@ -354,16 +369,21 @@ public final class Loader implements LoaderErrorThrower {
this
.
released
=
released
;
this
.
released
=
released
;
currentError
=
null
;
currentError
=
null
;
if
(
hasMessages
(
MSG_START
))
{
if
(
hasMessages
(
MSG_START
))
{
// The task has not been given to the executor yet.
canceled
=
true
;
removeMessages
(
MSG_START
);
removeMessages
(
MSG_START
);
if
(!
released
)
{
if
(!
released
)
{
sendEmptyMessage
(
MSG_
CANCEL
);
sendEmptyMessage
(
MSG_
FINISH
);
}
}
}
else
{
}
else
{
canceled
=
true
;
// The task has been given to the executor.
loadable
.
cancelLoad
();
synchronized
(
this
)
{
@Nullable
Thread
executorThread
=
this
.
executorThread
;
canceled
=
true
;
if
(
executorThread
!=
null
)
{
loadable
.
cancelLoad
();
executorThread
.
interrupt
();
@Nullable
Thread
executorThread
=
this
.
executorThread
;
if
(
executorThread
!=
null
)
{
executorThread
.
interrupt
();
}
}
}
}
}
if
(
released
)
{
if
(
released
)
{
...
@@ -382,8 +402,12 @@ public final class Loader implements LoaderErrorThrower {
...
@@ -382,8 +402,12 @@ public final class Loader implements LoaderErrorThrower {
@Override
@Override
public
void
run
()
{
public
void
run
()
{
try
{
try
{
executorThread
=
Thread
.
currentThread
();
boolean
shouldLoad
;
if
(!
canceled
)
{
synchronized
(
this
)
{
shouldLoad
=
!
canceled
;
executorThread
=
Thread
.
currentThread
();
}
if
(
shouldLoad
)
{
TraceUtil
.
beginSection
(
"load:"
+
loadable
.
getClass
().
getSimpleName
());
TraceUtil
.
beginSection
(
"load:"
+
loadable
.
getClass
().
getSimpleName
());
try
{
try
{
loadable
.
load
();
loadable
.
load
();
...
@@ -391,8 +415,13 @@ public final class Loader implements LoaderErrorThrower {
...
@@ -391,8 +415,13 @@ public final class Loader implements LoaderErrorThrower {
TraceUtil
.
endSection
();
TraceUtil
.
endSection
();
}
}
}
}
synchronized
(
this
)
{
executorThread
=
null
;
// Clear the interrupted flag if set, to avoid it leaking into a subsequent task.
Thread
.
interrupted
();
}
if
(!
released
)
{
if
(!
released
)
{
sendEmptyMessage
(
MSG_
END_OF_SOURCE
);
sendEmptyMessage
(
MSG_
FINISH
);
}
}
}
catch
(
IOException
e
)
{
}
catch
(
IOException
e
)
{
if
(!
released
)
{
if
(!
released
)
{
...
@@ -445,10 +474,7 @@ public final class Loader implements LoaderErrorThrower {
...
@@ -445,10 +474,7 @@ public final class Loader implements LoaderErrorThrower {
return
;
return
;
}
}
switch
(
msg
.
what
)
{
switch
(
msg
.
what
)
{
case
MSG_CANCEL:
case
MSG_FINISH:
callback
.
onLoadCanceled
(
loadable
,
nowMs
,
durationMs
,
false
);
break
;
case
MSG_END_OF_SOURCE:
try
{
try
{
callback
.
onLoadCompleted
(
loadable
,
nowMs
,
durationMs
);
callback
.
onLoadCompleted
(
loadable
,
nowMs
,
durationMs
);
}
catch
(
RuntimeException
e
)
{
}
catch
(
RuntimeException
e
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment