Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: libadblockplus-android-settings/src/org/adblockplus/libadblockplus/android/settings/AdblockHelper.java

Issue 29371750: Issue 4794 - adblock engine creating/releasing concurrency (Closed)
Patch Set: Created Jan. 13, 2017, 11:44 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2016 Eyeo GmbH 3 * Copyright (C) 2006-2016 Eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 } 99 }
100 100
101 private void createAdblock() 101 private void createAdblock()
102 { 102 {
103 Log.d(TAG, "Creating adblock engine ..."); 103 Log.d(TAG, "Creating adblock engine ...");
104 104
105 // read and apply current settings 105 // read and apply current settings
106 SharedPreferences prefs = context.getSharedPreferences(preferenceName, Conte xt.MODE_PRIVATE); 106 SharedPreferences prefs = context.getSharedPreferences(preferenceName, Conte xt.MODE_PRIVATE);
107 storage = new SharedPrefsStorage(prefs); 107 storage = new SharedPrefsStorage(prefs);
108 108
109 // latch is required for async (see `waitForReady()`)
110 engineCreated = new CountDownLatch(1);
111
112 engine = AdblockEngine.create( 109 engine = AdblockEngine.create(
113 AdblockEngine.generateAppInfo(context, developmentBuild), 110 AdblockEngine.generateAppInfo(context, developmentBuild),
114 context.getCacheDir().getAbsolutePath(), 111 context.getCacheDir().getAbsolutePath(),
115 true); // `true` as we need element hiding 112 true); // `true` as we need element hiding
116 Log.d(TAG, "AdblockHelper engine created"); 113 Log.d(TAG, "AdblockHelper engine created");
117 114
118 AdblockSettings settings = storage.load(); 115 AdblockSettings settings = storage.load();
119 if (settings != null) 116 if (settings != null)
120 { 117 {
121 Log.d(TAG, "Applying saved adblock settings to adblock engine"); 118 Log.d(TAG, "Applying saved adblock settings to adblock engine");
122 // apply last saved settings to adblock engine 119 // apply last saved settings to adblock engine
123 120
124 // all the settings except `enabled` and whitelisted domains are saved by adblock engine itself 121 // all the settings except `enabled` and whitelisted domains are saved by adblock engine itself
125 engine.setEnabled(settings.isAdblockEnabled()); 122 engine.setEnabled(settings.isAdblockEnabled());
126 engine.setWhitelistedDomains(settings.getWhitelistedDomains()); 123 engine.setWhitelistedDomains(settings.getWhitelistedDomains());
127 } 124 }
128 else 125 else
129 { 126 {
130 Log.w(TAG, "No saved adblock settings"); 127 Log.w(TAG, "No saved adblock settings");
131 } 128 }
132
133 // unlock waiting client thread
134 engineCreated.countDown();
135 } 129 }
136 130
137 /** 131 /**
138 * Wait until everything is ready (used for `retain(true)`) 132 * Wait until everything is ready (used for `retain(true)`)
139 * Warning: locks current thread 133 * Warning: locks current thread
140 */ 134 */
141 public void waitForReady() 135 public void waitForReady()
142 { 136 {
143 if (engineCreated == null) 137 if (engineCreated == null)
144 { 138 {
145 throw new RuntimeException("AdblockHelper Plus usage exception: call retai n(...) first"); 139 throw new RuntimeException("AdblockHelper Plus usage exception: call retai n(true) first");
146 } 140 }
147 141
148 try 142 try
149 { 143 {
150 Log.d(TAG, "Waiting for ready ..."); 144 Log.d(TAG, "Waiting for ready ...");
151 engineCreated.await(); 145 engineCreated.await();
152 Log.d(TAG, "Ready"); 146 Log.d(TAG, "Ready");
153 } 147 }
154 catch (InterruptedException e) 148 catch (InterruptedException e)
155 { 149 {
156 Log.w(TAG, "Interrupted", e); 150 Log.w(TAG, "Interrupted", e);
157 } 151 }
158 } 152 }
159 153
160 private void disposeAdblock() 154 private void disposeAdblock()
161 { 155 {
162 Log.w(TAG, "Disposing adblock engine"); 156 Log.w(TAG, "Disposing adblock engine");
163 157
164 engine.dispose(); 158 engine.dispose();
165 engine = null; 159 engine = null;
166 160
167 // to unlock waiting client in WaitForReady()
168 engineCreated.countDown();
169 engineCreated = null;
170
171 storage = null; 161 storage = null;
172 } 162 }
173 163
174 /** 164 /**
175 * Get registered clients count 165 * Get registered clients count
176 * @return registered clients count 166 * @return registered clients count
177 */ 167 */
178 public int getCounter() 168 public int getCounter()
179 { 169 {
180 return referenceCounter.get(); 170 return referenceCounter.get();
181 } 171 }
182 172
183 /** 173 /**
184 * Register AdblockHelper engine client 174 * Register AdblockHelper engine client
185 * @param asynchronous If `true` engines will be created in background thread without locking of 175 * @param asynchronous If `true` engines will be created in background thread without locking of
186 * current thread. Use waitForReady() before getEngine() l ater. 176 * current thread. Use waitForReady() before getEngine() l ater.
187 * If `false` locks current thread. 177 * If `false` locks current thread.
188 */ 178 */
189 public synchronized void retain(boolean asynchronous) 179 public synchronized void retain(boolean asynchronous)
190 { 180 {
191 if (referenceCounter.getAndIncrement() == 0) 181 if (referenceCounter.getAndIncrement() == 0)
192 { 182 {
193 if (!asynchronous) 183 if (!asynchronous)
194 { 184 {
195 createAdblock(); 185 createAdblock();
196 } 186 }
197 else 187 else
198 { 188 {
189 // latch is required for async (see `waitForReady()`)
190 engineCreated = new CountDownLatch(1);
191
199 new Thread(new Runnable() 192 new Thread(new Runnable()
200 { 193 {
201 @Override 194 @Override
202 public void run() 195 public void run()
203 { 196 {
204 createAdblock(); 197 createAdblock();
198
199 // unlock waiting client thread
200 engineCreated.countDown();
205 } 201 }
206 }).start(); 202 }).start();
207 } 203 }
208 } 204 }
209 } 205 }
210 206
211 /** 207 /**
212 * Unregister AdblockHelper engine client 208 * Unregister AdblockHelper engine client
213 */ 209 */
214 public synchronized void release() 210 public synchronized void release()
215 { 211 {
216 if (referenceCounter.decrementAndGet() == 0) 212 if (referenceCounter.decrementAndGet() == 0)
217 { 213 {
218 waitForReady(); 214 if (engineCreated != null)
219 disposeAdblock(); 215 {
216 // retained asynchronously
217 waitForReady();
218 disposeAdblock();
219
220 // to unlock waiting client in waitForReady()
221 engineCreated.countDown();
222 engineCreated = null;
223 }
224 else
225 {
226 disposeAdblock();
227 }
220 } 228 }
221 } 229 }
222 } 230 }
OLDNEW

Powered by Google App Engine
This is Rietveld