@@ -7,7 +7,14 @@ use ffbuildtool::ItemProgress;
7
7
use serde:: { Deserialize , Serialize } ;
8
8
use state:: { get_app_statics, AppState , FlatServer , FrontendServers , Server , ServerInfo , Versions } ;
9
9
10
- use std:: { collections:: HashMap , env, sync:: OnceLock } ;
10
+ use std:: {
11
+ collections:: HashSet ,
12
+ env,
13
+ sync:: {
14
+ atomic:: { AtomicU64 , Ordering } ,
15
+ Arc , OnceLock , RwLock ,
16
+ } ,
17
+ } ;
11
18
use tokio:: sync:: Mutex ;
12
19
13
20
use log:: * ;
@@ -245,14 +252,13 @@ async fn prep_launch(
245
252
246
253
#[ tauri:: command]
247
254
async fn validate_version_game ( app_handle : tauri:: AppHandle , uuid : Uuid ) -> CommandResult < bool > {
248
- static TRACKING : OnceLock < std :: sync :: Mutex < HashMap < Uuid , u64 > > > = OnceLock :: new ( ) ;
255
+ static IN_PROGRESS : OnceLock < RwLock < HashSet < Uuid > > > = OnceLock :: new ( ) ;
249
256
250
- fn callback ( uuid : & Uuid , _item_name : & str , item_progress : ItemProgress ) {
257
+ let total_size = Arc :: new ( AtomicU64 :: new ( 0 ) ) ;
258
+ let callback = move |uuid : & Uuid , _item_name : & str , item_progress : ItemProgress | {
251
259
if let ItemProgress :: Completed ( sz) = item_progress {
252
- let mut tracking = TRACKING . get ( ) . unwrap ( ) . lock ( ) . unwrap ( ) ;
253
- let old_sz = tracking. get ( uuid) . copied ( ) . unwrap ( ) ;
260
+ let old_sz = total_size. fetch_add ( sz, Ordering :: AcqRel ) ;
254
261
let new_sz = old_sz + sz;
255
- tracking. insert ( * uuid, new_sz) ;
256
262
let event = ValidationEvent {
257
263
uuid : * uuid,
258
264
sz : new_sz,
@@ -261,7 +267,8 @@ async fn validate_version_game(app_handle: tauri::AppHandle, uuid: Uuid) -> Comm
261
267
warn ! ( "Failed to emit validated_item_game event: {}" , e) ;
262
268
}
263
269
}
264
- }
270
+ } ;
271
+ let callback = Arc :: new ( callback) ;
265
272
266
273
let internal = async {
267
274
let state = app_handle. state :: < Mutex < AppState > > ( ) ;
@@ -275,21 +282,27 @@ async fn validate_version_game(app_handle: tauri::AppHandle, uuid: Uuid) -> Comm
275
282
drop ( state) ; // give up the state lock
276
283
277
284
{
278
- let mut tracking = TRACKING
279
- . get_or_init ( || std:: sync:: Mutex :: new ( HashMap :: new ( ) ) )
280
- . lock ( )
285
+ let tracking = IN_PROGRESS
286
+ . get_or_init ( || std:: sync:: RwLock :: new ( HashSet :: new ( ) ) )
287
+ . read ( )
281
288
. unwrap ( ) ;
282
- if tracking. contains_key ( & uuid) {
289
+ if tracking. contains ( & uuid) {
283
290
return Err ( format ! ( "Already validating game cache for {}" , uuid) . into ( ) ) ;
284
291
}
285
- tracking. insert ( uuid, 0 ) ;
292
+ }
293
+
294
+ {
295
+ let mut tracking = IN_PROGRESS . get ( ) . unwrap ( ) . write ( ) . unwrap ( ) ;
296
+ tracking. insert ( uuid) ;
286
297
}
287
298
288
299
let passed = version
289
300
. validate_uncompressed ( & path. to_string_lossy ( ) , Some ( callback) )
290
301
. await
291
302
. is_ok_and ( |corrupted| corrupted. is_empty ( ) ) ;
292
- TRACKING . get ( ) . unwrap ( ) . lock ( ) . unwrap ( ) . remove ( & uuid) ;
303
+
304
+ let mut tracking = IN_PROGRESS . get ( ) . unwrap ( ) . write ( ) . unwrap ( ) ;
305
+ tracking. remove ( & uuid) ;
293
306
Ok ( passed)
294
307
} ;
295
308
debug ! ( "validate_version_game {}" , uuid) ;
@@ -298,14 +311,13 @@ async fn validate_version_game(app_handle: tauri::AppHandle, uuid: Uuid) -> Comm
298
311
299
312
#[ tauri:: command]
300
313
async fn validate_version_offline ( app_handle : tauri:: AppHandle , uuid : Uuid ) -> CommandResult < bool > {
301
- static TRACKING : OnceLock < std:: sync:: Mutex < HashMap < Uuid , u64 > > > = OnceLock :: new ( ) ;
314
+ static IN_PROGRESS : OnceLock < std:: sync:: RwLock < HashSet < Uuid > > > = OnceLock :: new ( ) ;
302
315
303
- fn callback ( uuid : & Uuid , _item_name : & str , item_progress : ItemProgress ) {
316
+ let total_size = Arc :: new ( AtomicU64 :: new ( 0 ) ) ;
317
+ let callback = move |uuid : & Uuid , _item_name : & str , item_progress : ItemProgress | {
304
318
if let ItemProgress :: Completed ( sz) = item_progress {
305
- let mut tracking = TRACKING . get ( ) . unwrap ( ) . lock ( ) . unwrap ( ) ;
306
- let old_sz = tracking. get ( uuid) . copied ( ) . unwrap ( ) ;
319
+ let old_sz = total_size. fetch_add ( sz, Ordering :: AcqRel ) ;
307
320
let new_sz = old_sz + sz;
308
- tracking. insert ( * uuid, new_sz) ;
309
321
let event = ValidationEvent {
310
322
uuid : * uuid,
311
323
sz : new_sz,
@@ -317,7 +329,8 @@ async fn validate_version_offline(app_handle: tauri::AppHandle, uuid: Uuid) -> C
317
329
warn ! ( "Failed to emit validated_item_offline event: {}" , e) ;
318
330
}
319
331
}
320
- }
332
+ } ;
333
+ let callback = Arc :: new ( callback) ;
321
334
322
335
let internal = async {
323
336
let state = app_handle. state :: < Mutex < AppState > > ( ) ;
@@ -331,21 +344,27 @@ async fn validate_version_offline(app_handle: tauri::AppHandle, uuid: Uuid) -> C
331
344
drop ( state) ; // give up the state lock
332
345
333
346
{
334
- let mut tracking = TRACKING
335
- . get_or_init ( || std:: sync:: Mutex :: new ( HashMap :: new ( ) ) )
336
- . lock ( )
347
+ let tracking = IN_PROGRESS
348
+ . get_or_init ( || std:: sync:: RwLock :: new ( HashSet :: new ( ) ) )
349
+ . read ( )
337
350
. unwrap ( ) ;
338
- if tracking. contains_key ( & uuid) {
351
+ if tracking. contains ( & uuid) {
339
352
return Err ( format ! ( "Already validating offline cache for {}" , uuid) . into ( ) ) ;
340
353
}
341
- tracking. insert ( uuid, 0 ) ;
354
+ }
355
+
356
+ {
357
+ let mut tracking = IN_PROGRESS . get ( ) . unwrap ( ) . write ( ) . unwrap ( ) ;
358
+ tracking. insert ( uuid) ;
342
359
}
343
360
344
361
let passed = version
345
362
. validate_compressed ( & path. to_string_lossy ( ) , Some ( callback) )
346
363
. await
347
364
. is_ok_and ( |corrupted| corrupted. is_empty ( ) ) ;
348
- TRACKING . get ( ) . unwrap ( ) . lock ( ) . unwrap ( ) . remove ( & uuid) ;
365
+
366
+ let mut tracking = IN_PROGRESS . get ( ) . unwrap ( ) . write ( ) . unwrap ( ) ;
367
+ tracking. remove ( & uuid) ;
349
368
Ok ( passed)
350
369
} ;
351
370
debug ! ( "validate_version_offline {}" , uuid) ;
0 commit comments