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
1c34029e
authored
Apr 28, 2020
by
olly
Committed by
Oliver Woodman
May 01, 2020
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
ConditionVariable: Fix block(long) to correctly handle large timeouts
PiperOrigin-RevId: 308815613
parent
be07b3ca
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
47 additions
and
11 deletions
library/core/src/main/java/com/google/android/exoplayer2/util/ConditionVariable.java
library/core/src/test/java/com/google/android/exoplayer2/util/ConditionVariableTest.java
testutils/src/test/java/com/google/android/exoplayer2/testutil/TestUtilTest.java
library/core/src/main/java/com/google/android/exoplayer2/util/ConditionVariable.java
View file @
1c34029e
...
@@ -86,18 +86,27 @@ public class ConditionVariable {
...
@@ -86,18 +86,27 @@ public class ConditionVariable {
}
}
/**
/**
* Blocks until the condition is opened or until {@code timeout
} milliseconds
have passed.
* Blocks until the condition is opened or until {@code timeout
Ms}
have passed.
*
*
* @param timeout The maximum time to wait in milliseconds.
* @param timeoutMs The maximum time to wait in milliseconds. If {@code timeoutMs <= 0} then the
* call will return immediately without blocking.
* @return True if the condition was opened, false if the call returns because of the timeout.
* @return True if the condition was opened, false if the call returns because of the timeout.
* @throws InterruptedException If the thread is interrupted.
* @throws InterruptedException If the thread is interrupted.
*/
*/
public
synchronized
boolean
block
(
long
timeout
)
throws
InterruptedException
{
public
synchronized
boolean
block
(
long
timeoutMs
)
throws
InterruptedException
{
long
now
=
clock
.
elapsedRealtime
();
if
(
timeoutMs
<=
0
)
{
long
end
=
now
+
timeout
;
return
isOpen
;
while
(!
isOpen
&&
now
<
end
)
{
}
wait
(
end
-
now
);
long
nowMs
=
clock
.
elapsedRealtime
();
now
=
clock
.
elapsedRealtime
();
long
endMs
=
nowMs
+
timeoutMs
;
if
(
endMs
<
nowMs
)
{
// timeoutMs is large enough for (nowMs + timeoutMs) to rollover. Block indefinitely.
block
();
}
else
{
while
(!
isOpen
&&
nowMs
<
endMs
)
{
wait
(
endMs
-
nowMs
);
nowMs
=
clock
.
elapsedRealtime
();
}
}
}
return
isOpen
;
return
isOpen
;
}
}
...
...
library/core/src/test/java/com/google/android/exoplayer2/util/ConditionVariableTest.java
View file @
1c34029e
...
@@ -43,7 +43,7 @@ public class ConditionVariableTest {
...
@@ -43,7 +43,7 @@ public class ConditionVariableTest {
public
void
blockWithTimeout_blocksForAtLeastTimeout
()
throws
InterruptedException
{
public
void
blockWithTimeout_blocksForAtLeastTimeout
()
throws
InterruptedException
{
ConditionVariable
conditionVariable
=
buildTestConditionVariable
();
ConditionVariable
conditionVariable
=
buildTestConditionVariable
();
long
startTimeMs
=
System
.
currentTimeMillis
();
long
startTimeMs
=
System
.
currentTimeMillis
();
assertThat
(
conditionVariable
.
block
(
/* timeout= */
500
)).
isFalse
();
assertThat
(
conditionVariable
.
block
(
/* timeout
Ms
= */
500
)).
isFalse
();
long
endTimeMs
=
System
.
currentTimeMillis
();
long
endTimeMs
=
System
.
currentTimeMillis
();
assertThat
(
endTimeMs
-
startTimeMs
).
isAtLeast
(
500
);
assertThat
(
endTimeMs
-
startTimeMs
).
isAtLeast
(
500
);
}
}
...
@@ -76,6 +76,33 @@ public class ConditionVariableTest {
...
@@ -76,6 +76,33 @@ public class ConditionVariableTest {
}
}
@Test
@Test
public
void
blockWithMaxTimeout_blocks
()
throws
InterruptedException
{
ConditionVariable
conditionVariable
=
buildTestConditionVariable
();
AtomicBoolean
blockReturned
=
new
AtomicBoolean
();
AtomicBoolean
blockWasInterrupted
=
new
AtomicBoolean
();
Thread
blockingThread
=
new
Thread
(
()
->
{
try
{
conditionVariable
.
block
(
/* timeoutMs= */
Long
.
MAX_VALUE
);
blockReturned
.
set
(
true
);
}
catch
(
InterruptedException
e
)
{
blockWasInterrupted
.
set
(
true
);
}
});
blockingThread
.
start
();
Thread
.
sleep
(
500
);
assertThat
(
blockReturned
.
get
()).
isFalse
();
blockingThread
.
interrupt
();
blockingThread
.
join
();
assertThat
(
blockWasInterrupted
.
get
()).
isTrue
();
assertThat
(
conditionVariable
.
isOpen
()).
isFalse
();
}
@Test
public
void
open_unblocksBlock
()
throws
InterruptedException
{
public
void
open_unblocksBlock
()
throws
InterruptedException
{
ConditionVariable
conditionVariable
=
buildTestConditionVariable
();
ConditionVariable
conditionVariable
=
buildTestConditionVariable
();
...
...
testutils/src/test/java/com/google/android/exoplayer2/testutil/TestUtilTest.java
View file @
1c34029e
...
@@ -30,7 +30,7 @@ public class TestUtilTest {
...
@@ -30,7 +30,7 @@ public class TestUtilTest {
public
void
createRobolectricConditionVariable_blockWithTimeout_timesOut
()
public
void
createRobolectricConditionVariable_blockWithTimeout_timesOut
()
throws
InterruptedException
{
throws
InterruptedException
{
ConditionVariable
conditionVariable
=
TestUtil
.
createRobolectricConditionVariable
();
ConditionVariable
conditionVariable
=
TestUtil
.
createRobolectricConditionVariable
();
assertThat
(
conditionVariable
.
block
(
/* timeout= */
1
)).
isFalse
();
assertThat
(
conditionVariable
.
block
(
/* timeout
Ms
= */
1
)).
isFalse
();
assertThat
(
conditionVariable
.
isOpen
()).
isFalse
();
assertThat
(
conditionVariable
.
isOpen
()).
isFalse
();
}
}
...
@@ -39,7 +39,7 @@ public class TestUtilTest {
...
@@ -39,7 +39,7 @@ public class TestUtilTest {
throws
InterruptedException
{
throws
InterruptedException
{
ConditionVariable
conditionVariable
=
TestUtil
.
createRobolectricConditionVariable
();
ConditionVariable
conditionVariable
=
TestUtil
.
createRobolectricConditionVariable
();
long
startTimeMs
=
System
.
currentTimeMillis
();
long
startTimeMs
=
System
.
currentTimeMillis
();
assertThat
(
conditionVariable
.
block
(
/* timeout= */
500
)).
isFalse
();
assertThat
(
conditionVariable
.
block
(
/* timeout
Ms
= */
500
)).
isFalse
();
long
endTimeMs
=
System
.
currentTimeMillis
();
long
endTimeMs
=
System
.
currentTimeMillis
();
assertThat
(
endTimeMs
-
startTimeMs
).
isAtLeast
(
500
);
assertThat
(
endTimeMs
-
startTimeMs
).
isAtLeast
(
500
);
}
}
...
...
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