@@ -152,7 +152,7 @@ public Engine(
152
152
* @param height The target height in pixels of the desired resource.
153
153
* @param cb The callback that will be called when the load completes.
154
154
*/
155
- public synchronized <R > LoadStatus load (
155
+ public <R > LoadStatus load (
156
156
GlideContext glideContext ,
157
157
Object model ,
158
158
Key signature ,
@@ -185,24 +185,65 @@ public synchronized <R> LoadStatus load(
185
185
transcodeClass ,
186
186
options );
187
187
188
- EngineResource <?> active = loadFromActiveResources (key , isMemoryCacheable );
189
- if (active != null ) {
190
- cb .onResourceReady (active , DataSource .MEMORY_CACHE );
191
- if (VERBOSE_IS_LOGGABLE ) {
192
- logWithTimeAndKey ("Loaded resource from active resources" , startTime , key );
193
- }
194
- return null ;
195
- }
188
+ EngineResource <?> memoryResource ;
189
+ synchronized (this ) {
190
+ memoryResource = loadFromMemory (key , isMemoryCacheable , startTime );
196
191
197
- EngineResource <?> cached = loadFromCache (key , isMemoryCacheable );
198
- if (cached != null ) {
199
- cb .onResourceReady (cached , DataSource .MEMORY_CACHE );
200
- if (VERBOSE_IS_LOGGABLE ) {
201
- logWithTimeAndKey ("Loaded resource from cache" , startTime , key );
192
+ if (memoryResource == null ) {
193
+ return waitForExistingOrStartNewJob (
194
+ glideContext ,
195
+ model ,
196
+ signature ,
197
+ width ,
198
+ height ,
199
+ resourceClass ,
200
+ transcodeClass ,
201
+ priority ,
202
+ diskCacheStrategy ,
203
+ transformations ,
204
+ isTransformationRequired ,
205
+ isScaleOnlyOrNoTransform ,
206
+ options ,
207
+ isMemoryCacheable ,
208
+ useUnlimitedSourceExecutorPool ,
209
+ useAnimationPool ,
210
+ onlyRetrieveFromCache ,
211
+ cb ,
212
+ callbackExecutor ,
213
+ key ,
214
+ startTime );
202
215
}
203
- return null ;
204
216
}
205
217
218
+ // Avoid calling back while holding the engine lock, doing so makes it easier for callers to
219
+ // deadlock.
220
+ cb .onResourceReady (memoryResource , DataSource .MEMORY_CACHE );
221
+ return null ;
222
+ }
223
+
224
+ private <R > LoadStatus waitForExistingOrStartNewJob (
225
+ GlideContext glideContext ,
226
+ Object model ,
227
+ Key signature ,
228
+ int width ,
229
+ int height ,
230
+ Class <?> resourceClass ,
231
+ Class <R > transcodeClass ,
232
+ Priority priority ,
233
+ DiskCacheStrategy diskCacheStrategy ,
234
+ Map <Class <?>, Transformation <?>> transformations ,
235
+ boolean isTransformationRequired ,
236
+ boolean isScaleOnlyOrNoTransform ,
237
+ Options options ,
238
+ boolean isMemoryCacheable ,
239
+ boolean useUnlimitedSourceExecutorPool ,
240
+ boolean useAnimationPool ,
241
+ boolean onlyRetrieveFromCache ,
242
+ ResourceCallback cb ,
243
+ Executor callbackExecutor ,
244
+ EngineKey key ,
245
+ long startTime ) {
246
+
206
247
EngineJob <?> current = jobs .get (key , onlyRetrieveFromCache );
207
248
if (current != null ) {
208
249
current .addCallback (cb , callbackExecutor );
@@ -250,15 +291,38 @@ public synchronized <R> LoadStatus load(
250
291
return new LoadStatus (cb , engineJob );
251
292
}
252
293
294
+ @ Nullable
295
+ private EngineResource <?> loadFromMemory (
296
+ EngineKey key , boolean isMemoryCacheable , long startTime ) {
297
+ if (!isMemoryCacheable ) {
298
+ return null ;
299
+ }
300
+
301
+ EngineResource <?> active = loadFromActiveResources (key );
302
+ if (active != null ) {
303
+ if (VERBOSE_IS_LOGGABLE ) {
304
+ logWithTimeAndKey ("Loaded resource from active resources" , startTime , key );
305
+ }
306
+ return active ;
307
+ }
308
+
309
+ EngineResource <?> cached = loadFromCache (key );
310
+ if (cached != null ) {
311
+ if (VERBOSE_IS_LOGGABLE ) {
312
+ logWithTimeAndKey ("Loaded resource from cache" , startTime , key );
313
+ }
314
+ return cached ;
315
+ }
316
+
317
+ return null ;
318
+ }
319
+
253
320
private static void logWithTimeAndKey (String log , long startTime , Key key ) {
254
321
Log .v (TAG , log + " in " + LogTime .getElapsedMillis (startTime ) + "ms, key: " + key );
255
322
}
256
323
257
324
@ Nullable
258
- private EngineResource <?> loadFromActiveResources (Key key , boolean isMemoryCacheable ) {
259
- if (!isMemoryCacheable ) {
260
- return null ;
261
- }
325
+ private EngineResource <?> loadFromActiveResources (Key key ) {
262
326
EngineResource <?> active = activeResources .get (key );
263
327
if (active != null ) {
264
328
active .acquire ();
@@ -267,11 +331,7 @@ private EngineResource<?> loadFromActiveResources(Key key, boolean isMemoryCache
267
331
return active ;
268
332
}
269
333
270
- private EngineResource <?> loadFromCache (Key key , boolean isMemoryCacheable ) {
271
- if (!isMemoryCacheable ) {
272
- return null ;
273
- }
274
-
334
+ private EngineResource <?> loadFromCache (Key key ) {
275
335
EngineResource <?> cached = getEngineResourceFromCache (key );
276
336
if (cached != null ) {
277
337
cached .acquire ();
0 commit comments