1886 |
|
* throws TimeoutException on timeout. |
1887 |
|
*/ |
1888 |
|
private Object timedGet(long nanos) throws TimeoutException { |
1889 |
< |
if (Thread.interrupted()) |
1890 |
< |
return null; |
1891 |
< |
if (nanos > 0L) { |
1892 |
< |
long d = System.nanoTime() + nanos; |
1893 |
< |
long deadline = (d == 0L) ? 1L : d; // avoid 0 |
1894 |
< |
Signaller q = null; |
1895 |
< |
boolean queued = false; |
1896 |
< |
Object r; |
1897 |
< |
while ((r = result) == null) { // similar to untimed |
1898 |
< |
if (q == null) { |
1899 |
< |
q = new Signaller(true, nanos, deadline); |
1900 |
< |
if (Thread.currentThread() instanceof ForkJoinWorkerThread) |
1901 |
< |
ForkJoinPool.helpAsyncBlocker(defaultExecutor(), q); |
1902 |
< |
} |
1903 |
< |
else if (!queued) |
1904 |
< |
queued = tryPushStack(q); |
1905 |
< |
else if (q.nanos <= 0L) |
1906 |
< |
break; |
1907 |
< |
else { |
1908 |
< |
try { |
1909 |
< |
ForkJoinPool.managedBlock(q); |
1910 |
< |
} catch (InterruptedException ie) { |
1911 |
< |
q.interrupted = true; |
1912 |
< |
} |
1913 |
< |
if (q.interrupted) |
1914 |
< |
break; |
1915 |
< |
} |
1889 |
> |
long d = System.nanoTime() + nanos; |
1890 |
> |
long deadline = (d == 0L) ? 1L : d; // avoid 0 |
1891 |
> |
boolean interrupted = false, queued = false; |
1892 |
> |
Signaller q = null; |
1893 |
> |
Object r = null; |
1894 |
> |
for (;;) { // order of checking interrupt, result, timeout matters |
1895 |
> |
if (interrupted || (interrupted = Thread.interrupted())) |
1896 |
> |
break; |
1897 |
> |
else if ((r = result) != null) |
1898 |
> |
break; |
1899 |
> |
else if (nanos <= 0L) |
1900 |
> |
break; |
1901 |
> |
else if (q == null) { |
1902 |
> |
q = new Signaller(true, nanos, deadline); |
1903 |
> |
if (Thread.currentThread() instanceof ForkJoinWorkerThread) |
1904 |
> |
ForkJoinPool.helpAsyncBlocker(defaultExecutor(), q); |
1905 |
|
} |
1906 |
< |
if (q != null && queued) { |
1907 |
< |
q.thread = null; |
1908 |
< |
if (r == null) |
1909 |
< |
cleanStack(); |
1906 |
> |
else if (!queued) |
1907 |
> |
queued = tryPushStack(q); |
1908 |
> |
else { |
1909 |
> |
try { |
1910 |
> |
ForkJoinPool.managedBlock(q); |
1911 |
> |
interrupted = q.interrupted; |
1912 |
> |
nanos = q.nanos; |
1913 |
> |
} catch (InterruptedException ie) { |
1914 |
> |
interrupted = true; |
1915 |
> |
} |
1916 |
|
} |
1922 |
– |
if (r != null || (r = result) != null) |
1923 |
– |
postComplete(); |
1924 |
– |
if (r != null || (q != null && q.interrupted)) |
1925 |
– |
return r; |
1917 |
|
} |
1918 |
< |
throw new TimeoutException(); |
1918 |
> |
if (q != null) { |
1919 |
> |
q.thread = null; |
1920 |
> |
if (r == null) |
1921 |
> |
cleanStack(); |
1922 |
> |
} |
1923 |
> |
if (r == null && !interrupted) |
1924 |
> |
throw new TimeoutException(); |
1925 |
> |
else if (r != null) { |
1926 |
> |
if (interrupted) |
1927 |
> |
Thread.currentThread().interrupt(); |
1928 |
> |
postComplete(); |
1929 |
> |
} |
1930 |
> |
return r; |
1931 |
|
} |
1932 |
|
|
1933 |
|
/* ------------- public methods -------------- */ |