Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(165)

Side by Side Diff: remoting/android/java/src/org/chromium/chromoting/Event.java

Issue 1999583002: Add Event and EventTest (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Resolve review comments Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.chromoting;
6
7 import java.util.HashSet;
8
9 /**
10 * A thread-safe event queue which provides both {@link #add} and {@link #remove } functions with
11 * O(log(n)) time complexity, and a {@link raise} function in the derived class
12 * {@link Event.Raisable} to execute all queued callbacks.
13 *
14 * @param <ParamT> The parameter used in {@link ParameterRunnable} callback.
15 */
16 public class Event<ParamT> {
17 /** A runnable with parameter. */
18 public static interface ParameterRunnable<ParamT> {
19 void run(ParamT p);
20 }
21
22 /** A callback with parameter. */
23 public static interface ParameterCallback<ReturnT, ParamT> {
24 ReturnT run(ParamT p);
25 }
26
27 /**
28 * An event provider version of {@link Event} implementation, provides {@lin k raise} function to
29 * execute appended {@link ParameterRunnable}, and {@link clear} function to clear all appended
30 * callbacks.
31 */
32 public static final class Raisable<ParamT> extends Event<ParamT> {
33 /** Clears all appended callbacks */
34 public void clear() {
35 synchronized (mSet) {
36 mSet.clear();
37 }
38 }
39
40 /**
41 * Executes all queued {@link ParameterRunnable} with |parameter|, retur ns an integer of
42 * total callbacks executed. Note, if an 'add' function call is executin g concurrently
43 * with the 'raise' function call, the newly added object may not be exe cuted.
44 */
45 public int raise(ParamT parameter) {
46 Object[] array;
47 synchronized (mSet) {
48 array = mSet.toArray();
49 }
50 int count = 0;
51 for (Object obj : array) {
52 execute(obj, parameter);
53 count++;
54 }
55 return count;
56 }
57
58 /** Executes |obj| as ParameterRunnable<ParamT> with |parameter| as Para mT. */
59 @SuppressWarnings("unchecked")
60 private void execute(Object obj, ParamT parameter) {
61 ParameterRunnable<ParamT> runnable = (ParameterRunnable<ParamT>) obj ;
62 runnable.run(parameter);
63 }
64 }
65
66 /**
67 * A self removable {@link ParameterRunner}, uses a boolean {@link Parameter Callback} to decide
68 * whether removes self from {@link Event} or not.
69 */
70 private static class SelfRemovableParameterRunnable<ParamT>
71 implements ParameterRunnable<ParamT> {
72 private final ParameterCallback<Boolean, ParamT> mCallback;
73 private final Event<ParamT> mOwner;
74
75 // This lock is used to make sure mEvent is correctly set before remove in run function.
76 // i.e. mOwner.add and assigment of mEvent need to be atomic.
77 private final Object mLock;
78 private final Object mEvent;
79
80 private SelfRemovableParameterRunnable(Event<ParamT> owner,
81 ParameterCallback<Boolean, ParamT > callback) {
82 Preconditions.notNull(callback);
83 mCallback = callback;
84 mOwner = owner;
85 mLock = new Object();
86 synchronized (mLock) {
87 mEvent = mOwner.add(this);
88 }
89 Preconditions.notNull(mEvent);
90 }
91
92 public final void run(ParamT p) {
93 synchronized (mLock) {
94 if (mOwner.contains(mEvent)) {
95 if (!mCallback.run(p)) {
96 // Event.Raisable.clear may be called in a different thr ead.
97 mOwner.remove(mEvent);
98 }
99 }
100 }
101 }
102 }
103
104 protected final HashSet<ParameterRunnable<ParamT>> mSet;
105
106 public Event() {
107 mSet = new HashSet<>();
108 }
109
110 /**
111 * Adds a {@link ParameterRunnable} object into current instance, returns an object which can
112 * be used to {@link remove} the runnable from this instance. If |runnable| is null or it has
113 * been added to this instance already, this function returns null.
114 */
115 public Object add(ParameterRunnable<ParamT> runnable) {
116 if (runnable == null) {
117 return null;
118 }
119 synchronized (mSet) {
120 if (mSet.add(runnable)) {
121 return runnable;
122 }
123 }
124 return null;
125 }
126
127 /**
128 * Adds a self removable {@link ParameterRunnable} object into current insta nce; the runnable
129 * will remove itself from {@link Event} instance when callback returns fals e.
130 */
131 public void addSelfRemovable(ParameterCallback<Boolean, ParamT> callback) {
132 Preconditions.notNull(callback);
133
134 // SelfRemovableParameterRunner is self-contained, i.e. consumers do not need to have a
135 // reference of this instance, but all the logic is in new function.
136 new SelfRemovableParameterRunnable<ParamT>(this, callback);
137 }
138
139 /**
140 * Removes an object that was previously returned by {@link add}. Returns fa lse if the object
141 * is not in the event queue, or not returned by {@link add} function.
142 */
143 public boolean remove(Object obj) {
144 synchronized (mSet) {
145 return mSet.remove(obj);
146 }
147 }
148
149 /**
150 * Returns whether current instance contains the object that was previously returned by
151 * {@link add}.
152 */
153 public boolean contains(Object obj) {
154 synchronized (mSet) {
155 return mSet.contains(obj);
156 }
157 }
158
159 /**
160 * Returns the total count of runnables attached to current instance.
161 */
162 public int size() {
163 synchronized (mSet) {
164 return mSet.size();
165 }
166 }
167
168 /**
169 * Returns true if there is no runnable attached to current instance.
170 */
171 public boolean isEmpty() {
172 synchronized (mSet) {
173 return mSet.isEmpty();
174 }
175 }
176 }
OLDNEW
« no previous file with comments | « remoting/android/client_java_tmpl.gni ('k') | remoting/android/java/src/org/chromium/chromoting/Preconditions.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698