23
23
#include " firebird.h"
24
24
25
25
#include " iberror.h"
26
+ #include " ../common/classes/TempFile.h"
26
27
#include " ../common/config/config.h"
27
28
#include " ../common/config/dir_list.h"
28
29
#include " ../common/gdsassert.h"
29
- #include " ../yvalve/gds_proto.h"
30
- #include " ../jrd/err_proto.h"
31
30
#include " ../common/isc_proto.h"
32
31
#include " ../common/os/path_utils.h"
32
+ #include " ../jrd/jrd.h"
33
33
34
34
#include " ../jrd/TempSpace.h"
35
35
36
- using Firebird::TempFile;
36
+ using namespace Firebird ;
37
+ using namespace Jrd ;
37
38
38
39
// Static definitions/initializations
39
40
40
- const size_t MIN_TEMP_BLOCK_SIZE = 64 * 1024 ;
41
-
42
- Firebird::GlobalPtr<Firebird::Mutex> TempSpace::initMutex;
43
- Firebird::TempDirectoryList* TempSpace::tempDirs = NULL ;
41
+ GlobalPtr<Mutex> TempSpace::initMutex;
42
+ TempDirectoryList* TempSpace::tempDirs = NULL ;
44
43
FB_SIZE_T TempSpace::minBlockSize = 0 ;
45
- offset_t TempSpace::globalCacheUsage = 0 ;
44
+
45
+ namespace
46
+ {
47
+ const size_t MIN_TEMP_BLOCK_SIZE = 64 * 1024 ;
48
+
49
+ class TempCacheLimitGuard
50
+ {
51
+ public:
52
+ explicit TempCacheLimitGuard (FB_SIZE_T size)
53
+ : m_dbb(GET_DBB()), m_size(size),
54
+ m_guard(m_dbb->dbb_temp_cache_mutex, FB_FUNCTION)
55
+ {
56
+ m_allowed = (m_dbb->dbb_temp_cache_size + size <= m_dbb->dbb_config ->getTempCacheLimit ());
57
+ }
58
+
59
+ bool isAllowed () const
60
+ {
61
+ return m_allowed;
62
+ }
63
+
64
+ void increment ()
65
+ {
66
+ fb_assert (m_allowed);
67
+ m_dbb->dbb_temp_cache_size += m_size;
68
+ }
69
+
70
+ static void decrement (FB_SIZE_T size)
71
+ {
72
+ Database* const dbb = GET_DBB ();
73
+ MutexLockGuard guard (dbb->dbb_temp_cache_mutex , FB_FUNCTION);
74
+ dbb->dbb_temp_cache_size -= size;
75
+ }
76
+
77
+ private:
78
+ Database* const m_dbb;
79
+ FB_SIZE_T m_size;
80
+ MutexLockGuard m_guard;
81
+ bool m_allowed;
82
+ };
83
+ }
46
84
47
85
//
48
86
// In-memory block class
@@ -98,7 +136,7 @@ FB_SIZE_T TempSpace::FileBlock::write(offset_t offset, const void* buffer, FB_SI
98
136
// Constructor
99
137
//
100
138
101
- TempSpace::TempSpace (MemoryPool& p, const Firebird:: PathName& prefix, bool dynamic)
139
+ TempSpace::TempSpace (MemoryPool& p, const PathName& prefix, bool dynamic)
102
140
: pool(p), filePrefix(p, prefix),
103
141
logicalSize(0 ), physicalSize(0 ), localCacheUsage(0 ),
104
142
head(NULL ), tail(NULL ), tempFiles(p),
@@ -107,11 +145,11 @@ TempSpace::TempSpace(MemoryPool& p, const Firebird::PathName& prefix, bool dynam
107
145
{
108
146
if (!tempDirs)
109
147
{
110
- Firebird:: MutexLockGuard guard (initMutex, FB_FUNCTION);
148
+ MutexLockGuard guard (initMutex, FB_FUNCTION);
111
149
if (!tempDirs)
112
150
{
113
151
MemoryPool& def_pool = *getDefaultMemoryPool ();
114
- tempDirs = FB_NEW_POOL (def_pool) Firebird:: TempDirectoryList (def_pool);
152
+ tempDirs = FB_NEW_POOL (def_pool) TempDirectoryList (def_pool);
115
153
minBlockSize = Config::getTempBlockSize ();
116
154
117
155
if (minBlockSize < MIN_TEMP_BLOCK_SIZE)
@@ -137,12 +175,10 @@ TempSpace::~TempSpace()
137
175
head = temp;
138
176
}
139
177
140
- globalCacheUsage -= localCacheUsage;
178
+ TempCacheLimitGuard::decrement ( localCacheUsage) ;
141
179
142
180
while (tempFiles.getCount ())
143
- {
144
181
delete tempFiles.pop ();
145
- }
146
182
}
147
183
148
184
//
@@ -275,18 +311,22 @@ void TempSpace::extend(FB_SIZE_T size)
275
311
276
312
Block* block = NULL ;
277
313
278
- if (globalCacheUsage + size <= size_t (Config::getTempCacheLimit ()))
279
- {
280
- try
281
- {
282
- // allocate block in virtual memory
283
- block = FB_NEW_POOL (pool) MemoryBlock (FB_NEW_POOL (pool) UCHAR[size], tail, size);
284
- localCacheUsage += size;
285
- globalCacheUsage += size;
286
- }
287
- catch (const Firebird::BadAlloc&)
314
+ { // scope
315
+ TempCacheLimitGuard guard (size);
316
+
317
+ if (guard.isAllowed ())
288
318
{
289
- // not enough memory
319
+ try
320
+ {
321
+ // allocate block in virtual memory
322
+ block = FB_NEW_POOL (pool) MemoryBlock (FB_NEW_POOL (pool) UCHAR[size], tail, size);
323
+ localCacheUsage += size;
324
+ guard.increment ();
325
+ }
326
+ catch (const BadAlloc&)
327
+ {
328
+ // not enough memory
329
+ }
290
330
}
291
331
}
292
332
@@ -371,18 +411,18 @@ TempSpace::Block* TempSpace::findBlock(offset_t& offset) const
371
411
372
412
TempFile* TempSpace::setupFile (FB_SIZE_T size)
373
413
{
374
- Firebird:: StaticStatusVector status_vector;
414
+ StaticStatusVector status_vector;
375
415
376
416
for (FB_SIZE_T i = 0 ; i < tempDirs->getCount (); i++)
377
417
{
378
418
TempFile* file = NULL ;
379
419
380
- Firebird:: PathName directory = (*tempDirs)[i];
420
+ PathName directory = (*tempDirs)[i];
381
421
PathUtils::ensureSeparator (directory);
382
422
383
423
for (FB_SIZE_T j = 0 ; j < tempFiles.getCount (); j++)
384
424
{
385
- Firebird:: PathName dirname, filename;
425
+ PathName dirname, filename;
386
426
PathUtils::splitLastComponent (dirname, filename, tempFiles[j]->getName ());
387
427
PathUtils::ensureSeparator (dirname);
388
428
if (!directory.compare (dirname))
@@ -402,7 +442,7 @@ TempFile* TempSpace::setupFile(FB_SIZE_T size)
402
442
403
443
file->extend (size);
404
444
}
405
- catch (const Firebird:: system_error& ex)
445
+ catch (const system_error& ex)
406
446
{
407
447
ex.stuffException (status_vector);
408
448
continue ;
@@ -412,8 +452,8 @@ TempFile* TempSpace::setupFile(FB_SIZE_T size)
412
452
}
413
453
414
454
// no room in all directories
415
- Firebird:: Arg::Gds status (isc_out_of_temp_space);
416
- status.append (Firebird:: Arg::StatusVector (status_vector.begin ()));
455
+ Arg::Gds status (isc_out_of_temp_space);
456
+ status.append (Arg::StatusVector (status_vector.begin ()));
417
457
iscLogStatus (NULL , status.value ());
418
458
status.raise ();
419
459
@@ -480,7 +520,7 @@ void TempSpace::releaseSpace(offset_t position, FB_SIZE_T size)
480
520
const offset_t end = position + size;
481
521
fb_assert (end <= getSize ()); // Block ends in file
482
522
483
- if (freeSegments.locate (Firebird:: locEqual, end))
523
+ if (freeSegments.locate (locEqual, end))
484
524
{
485
525
// The next segment is found to be adjacent
486
526
Segment* const next_seg = &freeSegments.current ();
@@ -502,7 +542,7 @@ void TempSpace::releaseSpace(offset_t position, FB_SIZE_T size)
502
542
return ;
503
543
}
504
544
505
- if (freeSegments.locate (Firebird:: locLess, position))
545
+ if (freeSegments.locate (locLess, position))
506
546
{
507
547
// Check the prior segment for being adjacent
508
548
Segment* const prior_seg = &freeSegments.current ();
0 commit comments