Chromium Code Reviews| OLD | NEW |
|---|---|
| (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 complex, and a {@link raise} function in Executor inheritance to execute all | |
|
Lambros
2016/05/27 22:26:06
s/complex/complexity/
s/Executor inheritance/the d
Hzj_jie
2016/05/28 00:32:06
Done.
| |
| 12 * queued object. | |
|
Lambros
2016/05/27 22:26:06
s/object/objects/
Hzj_jie
2016/05/28 00:32:07
Done.
| |
| 13 * | |
| 14 * @param <ParamType> The parameter used in {@link ParameterRunnable} callback. | |
|
Lambros
2016/05/27 22:26:06
We should probably comply with the Google style gu
Hzj_jie
2016/05/28 00:32:06
Done.
| |
| 15 */ | |
| 16 public class Event<ParamType> { | |
| 17 /** | |
| 18 * A runnable with parameter. | |
|
Lambros
2016/05/27 22:26:06
Elsewhere, we've formatted single-line JavaDoc as
Hzj_jie
2016/05/28 00:32:07
I did not see a coding style for this, but yes, we
| |
| 19 */ | |
| 20 public static interface ParameterRunnable<ParamType> { | |
| 21 void run(ParamType p); | |
| 22 } | |
| 23 | |
| 24 /** | |
| 25 * A callback with parameter. | |
| 26 */ | |
| 27 public static interface ParameterCallback<ReturnType, ParamType> { | |
| 28 ReturnType run(ParamType p); | |
| 29 } | |
| 30 | |
| 31 /** | |
| 32 * An event provider version of {@link Event} implementation, provides {@lin k raise} function to | |
| 33 * execute appended {@link ParameterRunnable}. | |
| 34 */ | |
| 35 public static final class Executor<ParamType> extends Event<ParamType> { | |
| 36 public void clear() { | |
|
Lambros
2016/05/27 22:26:06
Need JavaDoc for public methods (linter will compl
Hzj_jie
2016/05/28 00:32:07
Done.
| |
| 37 synchronized (mSet) { | |
| 38 mSet.clear(); | |
| 39 } | |
| 40 } | |
| 41 | |
| 42 /** | |
| 43 * Executes all queued {@link ParameterRunnable} with |parameter|, retur ns an integer of | |
| 44 * total callbacks executed. Note, if an 'add' function call is executin g concurrently | |
| 45 * with the 'raise' function call, the newly added object may not be exe cuted. | |
| 46 */ | |
| 47 public int raise(ParamType parameter) { | |
| 48 Object[] array; | |
| 49 synchronized (mSet) { | |
| 50 array = mSet.toArray(); | |
| 51 } | |
| 52 int count = 0; | |
| 53 for (Object obj : array) { | |
| 54 execute(obj, parameter); | |
| 55 count++; | |
| 56 } | |
| 57 return count; | |
| 58 } | |
| 59 | |
| 60 /** | |
| 61 * Executes |obj| as ParameterRunnable<ParamType> with |parameter| as Pa ramType. | |
| 62 */ | |
| 63 @SuppressWarnings("unchecked") | |
|
Lambros
2016/05/27 22:26:06
I'm not sure about this. Android style guide:
http
Hzj_jie
2016/05/28 00:32:06
Oops, I have tried several ways, but looks like we
| |
| 64 private void execute(Object obj, ParamType parameter) { | |
| 65 ParameterRunnable<ParamType> runnable = (ParameterRunnable<ParamType >) obj; | |
| 66 runnable.run(parameter); | |
| 67 } | |
| 68 } | |
| 69 | |
| 70 /** | |
| 71 * A self removable {@link ParameterRunner}, uses a boolean {@link Parameter Callback} to decide | |
| 72 * whether removes self from {@link Event} or not. | |
| 73 */ | |
| 74 private static class SelfRemovableParameterRunnable<ParamType> | |
| 75 implements ParameterRunnable<ParamType> { | |
| 76 private final ParameterCallback<Boolean, ParamType> mCallback; | |
| 77 private final Event<ParamType> mOwner; | |
| 78 | |
| 79 // This lock is used to make sure mEvent is correctly set before remove in run function. | |
| 80 // i.e. mOwner.add and assigment of mEvent need to be atomic. | |
| 81 private final Object mLock; | |
| 82 private final Object mEvent; | |
| 83 | |
| 84 private SelfRemovableParameterRunnable(Event<ParamType> owner, | |
| 85 ParameterCallback<Boolean, ParamT ype> callback) { | |
| 86 Preconditions.notNull(callback); | |
| 87 mCallback = callback; | |
| 88 mOwner = owner; | |
| 89 mLock = new Object(); | |
| 90 synchronized (mLock) { | |
| 91 mEvent = mOwner.add(this); | |
|
Lambros
2016/05/27 22:26:06
Please verify that FindBugs is happy with leaking
Hzj_jie
2016/05/28 00:32:06
No, findbugs does not raise any issue. And synchro
| |
| 92 } | |
| 93 Preconditions.notNull(mEvent); | |
| 94 } | |
| 95 | |
| 96 public final void run(ParamType p) { | |
| 97 synchronized (mLock) { | |
| 98 if (mOwner.contains(mEvent)) { | |
| 99 if (!mCallback.run(p)) { | |
|
Lambros
2016/05/31 17:50:35
I know the CL has landed now, but I see a couple o
| |
| 100 Preconditions.isTrue(mOwner.remove(mEvent)); | |
| 101 } | |
| 102 } | |
| 103 } | |
| 104 } | |
| 105 } | |
| 106 | |
| 107 protected final HashSet<ParameterRunnable<ParamType>> mSet; | |
| 108 | |
| 109 public Event() { | |
| 110 mSet = new HashSet<>(); | |
| 111 } | |
| 112 | |
| 113 /** | |
| 114 * Adds a {@link ParameterRunnable} object into current instance, returns an object which can | |
| 115 * be used to {@link remove} the runnable from this instance. If |runnable| is null or it has | |
| 116 * been added to this instance already, this function returns null. | |
| 117 */ | |
| 118 public Object add(ParameterRunnable<ParamType> runnable) { | |
| 119 if (runnable == null) { | |
| 120 return null; | |
| 121 } | |
| 122 synchronized (mSet) { | |
| 123 if (mSet.add(runnable)) { | |
| 124 return runnable; | |
| 125 } | |
| 126 } | |
| 127 return null; | |
| 128 } | |
| 129 | |
| 130 /** | |
| 131 * Adds a self removable {@link ParameterRunnable} object into current insta nce, the runnable | |
|
Lambros
2016/05/27 22:26:06
Grammar nit:
This is 2 sentences, so:
Either s/,/;
Hzj_jie
2016/05/28 00:32:06
Done.
| |
| 132 * will remove itself from {@link Event} instance when callback returns fals e. | |
| 133 */ | |
| 134 public void addSelfRemovable(ParameterCallback<Boolean, ParamType> callback) { | |
| 135 Preconditions.notNull(callback); | |
| 136 // SelfRemovableParameterRunner is self-contained, i.e. consumers do not need to have a | |
|
Lambros
2016/05/27 22:26:07
Blank line before comment.
Hzj_jie
2016/05/28 00:32:06
Done.
| |
| 137 // reference of this instance, but all the logic is in new function. | |
| 138 new SelfRemovableParameterRunnable<ParamType>(this, callback); | |
| 139 } | |
| 140 | |
| 141 /** | |
| 142 * Removes an object that was previously returned by {@link add}. Returns fa lse if the object | |
| 143 * is not in the event queue, or not returned by {@link add} function. | |
| 144 */ | |
| 145 public boolean remove(Object obj) { | |
| 146 if (obj == null) { | |
|
Lambros
2016/05/27 22:26:06
Maybe remove this test?
Hzj_jie
2016/05/28 00:32:07
Done.
| |
| 147 return false; | |
| 148 } | |
| 149 synchronized (mSet) { | |
| 150 return mSet.remove(obj); | |
| 151 } | |
| 152 } | |
| 153 | |
| 154 /** | |
| 155 * Returns whether current instance contains the object that was previously returned by | |
| 156 * {@link add}. | |
| 157 */ | |
| 158 public boolean contains(Object obj) { | |
| 159 if (obj == null) { | |
|
Lambros
2016/05/27 22:26:06
Maybe remove this test?
Hzj_jie
2016/05/28 00:32:06
Done.
| |
| 160 return false; | |
| 161 } | |
| 162 synchronized (mSet) { | |
| 163 return mSet.contains(obj); | |
| 164 } | |
| 165 } | |
| 166 | |
| 167 /** | |
| 168 * Returns the total count of runnables attached to current instance. | |
| 169 */ | |
| 170 public int size() { | |
| 171 synchronized (mSet) { | |
| 172 return mSet.size(); | |
| 173 } | |
| 174 } | |
| 175 | |
| 176 /** | |
| 177 * Returns true if there is no runnable attached to current instance. | |
| 178 */ | |
| 179 public boolean isEmpty() { | |
| 180 synchronized (mSet) { | |
| 181 return mSet.isEmpty(); | |
| 182 } | |
| 183 } | |
| 184 } | |
| OLD | NEW |