OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. |
| 3 * |
| 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ |
| 10 |
| 11 package org.appspot.apprtc.util; |
| 12 |
| 13 import java.util.concurrent.ArrayBlockingQueue; |
| 14 import java.util.concurrent.BlockingQueue; |
| 15 |
| 16 import static org.junit.Assert.fail; |
| 17 |
| 18 /** |
| 19 * LooperExecutor that doesn't use Looper because its implementation in Robolect
ric is not suited |
| 20 * for our needs. Also implements executeAndWait that can be used to wait until
the runnable has |
| 21 * been executed. |
| 22 */ |
| 23 public class RobolectricLooperExecutor extends LooperExecutor { |
| 24 private volatile boolean running = false; |
| 25 private static final int RUNNABLE_QUEUE_CAPACITY = 256; |
| 26 private final BlockingQueue<Runnable> runnableQueue |
| 27 = new ArrayBlockingQueue<>(RUNNABLE_QUEUE_CAPACITY); |
| 28 private long threadId; |
| 29 |
| 30 /** |
| 31 * Executes the runnable passed to the constructor and sets isDone flag afterw
ards. |
| 32 */ |
| 33 private static class ExecuteAndWaitRunnable implements Runnable { |
| 34 public boolean isDone = false; |
| 35 private final Runnable runnable; |
| 36 |
| 37 ExecuteAndWaitRunnable(Runnable runnable) { |
| 38 this.runnable = runnable; |
| 39 } |
| 40 |
| 41 @Override |
| 42 public void run() { |
| 43 runnable.run(); |
| 44 |
| 45 synchronized (this) { |
| 46 isDone = true; |
| 47 notifyAll(); |
| 48 } |
| 49 } |
| 50 } |
| 51 |
| 52 @Override |
| 53 public void run() { |
| 54 threadId = Thread.currentThread().getId(); |
| 55 |
| 56 while (running) { |
| 57 final Runnable runnable; |
| 58 |
| 59 try { |
| 60 runnable = runnableQueue.take(); |
| 61 } catch (InterruptedException e) { |
| 62 if (running) { |
| 63 fail(e.getMessage()); |
| 64 } |
| 65 return; |
| 66 } |
| 67 |
| 68 runnable.run(); |
| 69 } |
| 70 } |
| 71 |
| 72 @Override |
| 73 public synchronized void requestStart() { |
| 74 if (running) { |
| 75 return; |
| 76 } |
| 77 running = true; |
| 78 start(); |
| 79 } |
| 80 |
| 81 @Override |
| 82 public synchronized void requestStop() { |
| 83 running = false; |
| 84 interrupt(); |
| 85 } |
| 86 |
| 87 @Override |
| 88 public synchronized void execute(Runnable runnable) { |
| 89 try { |
| 90 runnableQueue.put(runnable); |
| 91 } catch (InterruptedException e) { |
| 92 fail(e.getMessage()); |
| 93 } |
| 94 } |
| 95 |
| 96 /** |
| 97 * Queues runnable to be run and waits for it to be executed by the executor t
hread |
| 98 */ |
| 99 public void executeAndWait(Runnable runnable) { |
| 100 ExecuteAndWaitRunnable executeAndWaitRunnable = new ExecuteAndWaitRunnable(r
unnable); |
| 101 execute(executeAndWaitRunnable); |
| 102 |
| 103 synchronized (executeAndWaitRunnable) { |
| 104 while (!executeAndWaitRunnable.isDone) { |
| 105 try { |
| 106 executeAndWaitRunnable.wait(); |
| 107 } catch (InterruptedException e) { |
| 108 fail(e.getMessage()); |
| 109 } |
| 110 } |
| 111 } |
| 112 } |
| 113 |
| 114 @Override |
| 115 public boolean checkOnLooperThread() { |
| 116 return (Thread.currentThread().getId() == threadId); |
| 117 } |
| 118 } |
OLD | NEW |