1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-18 00:54:19 +00:00

Android: ensure that web calls are done off the main thread and fix data races.

This commit is contained in:
Lukasz Kozakiewicz 2017-08-24 11:37:41 +02:00 committed by hogliux
parent ac5797da58
commit 644ba82e00
2 changed files with 87 additions and 51 deletions

View file

@ -949,36 +949,30 @@ public class JuceAppActivity extends Activity
public final boolean connect()
{
try
synchronized (createStreamLock)
{
if (hasBeenCancelled.get())
return false;
try
{
synchronized (createStreamLock)
try
{
if (hasBeenCancelled.get())
return false;
inputStream = getCancellableStream (true);
}
}
catch (ExecutionException e)
{
if (connection.getResponseCode() < 400)
catch (ExecutionException e)
{
if (connection.getResponseCode() < 400)
{
statusCode[0] = connection.getResponseCode();
connection.disconnect();
return false;
}
}
finally
{
statusCode[0] = connection.getResponseCode();
connection.disconnect();
return false;
}
}
finally
{
statusCode[0] = connection.getResponseCode();
}
synchronized (createStreamLock)
{
if (hasBeenCancelled.get())
return false;
try
{
@ -989,49 +983,89 @@ public class JuceAppActivity extends Activity
}
catch (ExecutionException e)
{}
for (java.util.Map.Entry<String, java.util.List<String>> entry : connection.getHeaderFields().entrySet())
if (entry.getKey() != null && entry.getValue() != null)
responseHeaders.append (entry.getKey() + ": "
+ android.text.TextUtils.join (",", entry.getValue()) + "\n");
return true;
}
catch (IOException e)
{
return false;
}
for (java.util.Map.Entry<String, java.util.List<String>> entry : connection.getHeaderFields().entrySet())
if (entry.getKey() != null && entry.getValue() != null)
responseHeaders.append (entry.getKey() + ": "
+ android.text.TextUtils.join (",", entry.getValue()) + "\n");
return true;
}
catch (IOException e)
}
static class DisconnectionRunnable implements Runnable
{
public DisconnectionRunnable (HttpURLConnection theConnection,
InputStream theInputStream,
ReentrantLock theCreateStreamLock,
Object theCreateFutureLock,
Future<BufferedInputStream> theStreamFuture)
{
return false;
connectionToDisconnect = theConnection;
inputStream = theInputStream;
createStreamLock = theCreateStreamLock;
createFutureLock = theCreateFutureLock;
streamFuture = theStreamFuture;
}
public void run()
{
try
{
if (! createStreamLock.tryLock())
{
synchronized (createFutureLock)
{
if (streamFuture != null)
streamFuture.cancel (true);
}
createStreamLock.lock();
}
if (connectionToDisconnect != null)
connectionToDisconnect.disconnect();
if (inputStream != null)
inputStream.close();
}
catch (IOException e)
{}
finally
{
createStreamLock.unlock();
}
}
private HttpURLConnection connectionToDisconnect;
private InputStream inputStream;
private ReentrantLock createStreamLock;
private Object createFutureLock;
Future<BufferedInputStream> streamFuture;
}
public final void release()
{
hasBeenCancelled.set (true);
DisconnectionRunnable disconnectionRunnable = new DisconnectionRunnable (connection,
inputStream,
createStreamLock,
createFutureLock,
streamFuture);
try
synchronized (createStreamLock)
{
if (! createStreamLock.tryLock())
{
synchronized (createFutureLock)
{
if (streamFuture != null)
streamFuture.cancel (true);
}
hasBeenCancelled.set (true);
createStreamLock.lock();
}
if (inputStream != null)
inputStream.close();
}
catch (IOException e)
{}
finally
{
createStreamLock.unlock();
connection = null;
}
connection.disconnect();
Thread disconnectionThread = new Thread(disconnectionRunnable);
disconnectionThread.start();
}
public final int read (byte[] buffer, int numBytes)

View file

@ -201,6 +201,8 @@ public:
{
jassert (buffer != nullptr && bytesToRead >= 0);
const ScopedLock lock (createStreamLock);
if (stream == nullptr)
return 0;