21
21
#include < util/system/thread.h>
22
22
23
23
#include < functional>
24
+ #include < atomic>
24
25
25
26
#if defined(_unix_)
26
27
#include < pthread.h>
@@ -135,7 +136,7 @@ class TStorage::TImpl: public TIntrusiveListItem<TImpl> {
135
136
private:
136
137
void Reinit () {
137
138
for (auto & v : Registered) {
138
- v.ResetRandom ();
139
+ v.ResetAtFork ();
139
140
}
140
141
}
141
142
@@ -153,6 +154,9 @@ class TStorage::TImpl: public TIntrusiveListItem<TImpl> {
153
154
, IsTemp(storagePath.empty())
154
155
, MaxFiles(maxFiles)
155
156
, MaxSize(maxSize)
157
+ , CurrentFiles(0 )
158
+ , CurrentSize(0 )
159
+ , Dirty(false )
156
160
{
157
161
// TFsPath is not thread safe. It can initialize internal Split at any time. Force do it right now
158
162
StorageDir.PathSplit ();
@@ -172,8 +176,8 @@ class TStorage::TImpl: public TIntrusiveListItem<TImpl> {
172
176
TAtforkReinit::Get ().Register (this );
173
177
YQL_LOG (INFO) << " FileStorage initialized in " << StorageDir.GetPath ().Quote ()
174
178
<< " , temporary dir: " << ProcessTempDir.GetPath ().Quote ()
175
- << " , files: " << CurrentFiles
176
- << " , total size: " << CurrentSize;
179
+ << " , files: " << CurrentFiles. load ()
180
+ << " , total size: " << CurrentSize. load () ;
177
181
}
178
182
179
183
~TImpl () {
@@ -219,8 +223,8 @@ class TStorage::TImpl: public TIntrusiveListItem<TImpl> {
219
223
SetCacheFilePermissionsNoThrow (hardlinkFile);
220
224
221
225
if (NFs::HardLink (hardlinkFile, storageFile)) {
222
- AtomicIncrement ( CurrentFiles) ;
223
- AtomicAdd ( CurrentSize, fileSize) ;
226
+ ++ CurrentFiles;
227
+ CurrentSize += fileSize;
224
228
}
225
229
// Ignore HardLink fail. Another process managed to download before us
226
230
TouchFile (storageFile.c_str ());
@@ -281,10 +285,10 @@ class TStorage::TImpl: public TIntrusiveListItem<TImpl> {
281
285
const i64 newFileSize = Max<i64>(0 , GetFileLength (dstStorageFile.c_str ()));
282
286
283
287
if (!prevFileExisted) {
284
- AtomicIncrement ( CurrentFiles) ;
288
+ ++ CurrentFiles;
285
289
}
286
290
287
- AtomicAdd ( CurrentSize, newFileSize - prevFileSize) ;
291
+ CurrentSize += newFileSize - prevFileSize;
288
292
}
289
293
290
294
bool RemoveFromStorage (const TString& existingStorageFileName) {
@@ -300,19 +304,19 @@ class TStorage::TImpl: public TIntrusiveListItem<TImpl> {
300
304
const bool result = NFs::Remove (storageFile);
301
305
302
306
if (result || !storageFile.Exists ()) {
303
- AtomicDecrement ( CurrentFiles) ;
304
- AtomicAdd ( CurrentSize, - prevFileSize) ;
307
+ ++ CurrentFiles;
308
+ CurrentSize -= prevFileSize;
305
309
}
306
310
307
311
return result;
308
312
}
309
313
310
314
ui64 GetOccupiedSize () const {
311
- return AtomicGet ( CurrentSize);
315
+ return CurrentSize. load ( );
312
316
}
313
317
314
318
size_t GetCount () const {
315
- return AtomicGet ( CurrentFiles);
319
+ return CurrentFiles. load ( );
316
320
}
317
321
318
322
TString GetTempName () {
@@ -365,15 +369,17 @@ class TStorage::TImpl: public TIntrusiveListItem<TImpl> {
365
369
CurrentSize = actualSize;
366
370
}
367
371
368
- bool NeedToCleanup () {
369
- return static_cast <ui64>(AtomicGet (CurrentFiles)) > MaxFiles ||
370
- static_cast <ui64>(AtomicGet (CurrentSize)) > MaxSize;
372
+ bool NeedToCleanup () const {
373
+ return Dirty.load ()
374
+ || static_cast <ui64>(CurrentFiles.load ()) > MaxFiles
375
+ || static_cast <ui64>(CurrentSize.load ()) > MaxSize;
371
376
}
372
377
373
378
void Cleanup () {
374
379
if (!NeedToCleanup ()) {
375
380
return ;
376
381
}
382
+ Dirty.store (false );
377
383
378
384
with_lock (CleanupLock) {
379
385
TVector<TString> names;
@@ -422,15 +428,17 @@ class TStorage::TImpl: public TIntrusiveListItem<TImpl> {
422
428
}
423
429
}
424
430
425
- AtomicSet ( CurrentFiles, actualFiles);
426
- AtomicSet ( CurrentSize, actualSize);
431
+ CurrentFiles. store ( actualFiles);
432
+ CurrentSize. store ( actualSize);
427
433
}
428
434
}
429
435
430
- void ResetRandom () {
436
+ void ResetAtFork () {
431
437
with_lock (RndLock) {
432
438
Rnd.ResetSeed ();
433
439
}
440
+ // Force cleanup on next file add, because other processes may change the state
441
+ Dirty.store (true );
434
442
}
435
443
436
444
private:
@@ -441,8 +449,9 @@ class TStorage::TImpl: public TIntrusiveListItem<TImpl> {
441
449
const bool IsTemp;
442
450
const ui64 MaxFiles;
443
451
const ui64 MaxSize;
444
- TAtomic CurrentFiles = 0 ;
445
- TAtomic CurrentSize = 0 ;
452
+ std::atomic<i64> CurrentFiles = 0 ;
453
+ std::atomic<i64> CurrentSize = 0 ;
454
+ std::atomic_bool Dirty;
446
455
TMutex RndLock;
447
456
TRandGuid Rnd;
448
457
};
0 commit comments