Coverage Report

Created: 2026-05-30 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/logging-log4cxx/src/main/cpp/timebasedrollingpolicy.cpp
Line
Count
Source
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
#define NOMINMAX /* tell windows to not define min/max macros */
18
#include <log4cxx/log4cxx.h>
19
#include <log4cxx/logstring.h>
20
#include <log4cxx/rolling/timebasedrollingpolicy.h>
21
#include <log4cxx/pattern/filedatepatternconverter.h>
22
#include <log4cxx/helpers/date.h>
23
#include <log4cxx/rolling/filerenameaction.h>
24
#include <log4cxx/helpers/loglog.h>
25
#include <log4cxx/helpers/exception.h>
26
#include <log4cxx/rolling/gzcompressaction.h>
27
#include <log4cxx/rolling/zipcompressaction.h>
28
#include <log4cxx/helpers/stringhelper.h>
29
#include <log4cxx/helpers/optionconverter.h>
30
#include <log4cxx/helpers/transcoder.h>
31
#include <log4cxx/fileappender.h>
32
#include <algorithm>
33
#include <iostream>
34
#include <apr_mmap.h>
35
36
using namespace LOG4CXX_NS;
37
using namespace LOG4CXX_NS::rolling;
38
using namespace LOG4CXX_NS::helpers;
39
using namespace LOG4CXX_NS::pattern;
40
41
IMPLEMENT_LOG4CXX_OBJECT(TimeBasedRollingPolicy)
42
43
struct TimeBasedRollingPolicy::TimeBasedRollingPolicyPrivate{
44
#if LOG4CXX_HAS_MULTIPROCESS_ROLLING_FILE_APPENDER
45
  TimeBasedRollingPolicyPrivate() :
46
    _mmap(nullptr),
47
    _file_map(nullptr),
48
    _lock_file(nullptr),
49
    bAlreadyInitialized(false),
50
    bRefreshCurFile(false){}
51
#else
52
0
  TimeBasedRollingPolicyPrivate(){}
53
#endif
54
55
    /**
56
     * Time for next determination if time for rollover.
57
     */
58
    log4cxx_time_t nextCheck{0};
59
60
    /**
61
     * File name at last rollover.
62
     */
63
    LogString lastFileName;
64
65
    /**
66
     * Length of any file type suffix (.gz, .zip).
67
     */
68
    int suffixLength{0};
69
70
    /**
71
     * mmap pointer
72
     */
73
    apr_mmap_t* _mmap;
74
75
    /*
76
     * pool for mmap handler
77
     * */
78
    LOG4CXX_NS::helpers::Pool _mmapPool;
79
80
    /**
81
     * mmap file descriptor
82
     */
83
    apr_file_t* _file_map;
84
85
    /**
86
     * mmap file name
87
     */
88
    std::string _mapFileName;
89
90
    /*
91
     * lock file handle
92
     * */
93
    apr_file_t* _lock_file;
94
95
    /**
96
     * Check nextCheck if it has already been set
97
     * Timebased rolling policy has an issue when working at low rps.
98
     * Under low rps, multiple processes will not be scheduled in time for the second chance(do rolling),
99
     * so the rolling mechanism will not be triggered even if the time period is out of date.
100
     * This results in log entries will be accumulated for serveral minutes to be rolling.
101
     * Adding this flag to provide rolling opportunity for a process even if it is writing the first log entry
102
     */
103
    bool bAlreadyInitialized;
104
105
    /*
106
     * If the current file name contains date information, retrieve the current writting file from mmap
107
     * */
108
    bool bRefreshCurFile;
109
110
    /*
111
     * mmap file name
112
     * */
113
    LogString _fileNamePattern;
114
115
    bool multiprocess = false;
116
    bool throwIOExceptionOnForkFailure = true;
117
};
118
119
120
#define MMAP_FILE_SUFFIX ".map"
121
#define LOCK_FILE_SUFFIX ".maplck"
122
#define MAX_FILE_LEN 2048
123
124
#if LOG4CXX_HAS_MULTIPROCESS_ROLLING_FILE_APPENDER
125
namespace
126
{
127
LogString readMappedFileName(apr_mmap_t* mmap)
128
{
129
  if (!mmap || !mmap->mm)
130
  {
131
    return LogString();
132
  }
133
134
  const auto* first = static_cast<const logchar*>(mmap->mm);
135
  const auto* last = first + (MAX_FILE_LEN / sizeof(logchar));
136
  const auto* terminator = std::find(first, last, logchar(0));
137
138
  if (terminator == last)
139
  {
140
    LogLog::warn(LOG4CXX_STR("Ignoring invalid multiprocess rolling map file: missing string terminator"));
141
    return LogString();
142
  }
143
144
  return LogString(first, terminator);
145
}
146
}
147
148
bool TimeBasedRollingPolicy::isMapFileEmpty(LOG4CXX_NS::helpers::Pool& pool)
149
{
150
  apr_finfo_t finfo;
151
  apr_status_t st = apr_stat(&finfo, m_priv->_mapFileName.c_str(), APR_FINFO_SIZE, pool.getAPRPool());
152
153
  if (st != APR_SUCCESS)
154
  {
155
    LogLog::warn(helpers::Exception::makeMessage(LOG4CXX_STR("apr_stat"), st));
156
  }
157
158
  if (st == APR_SUCCESS && (0 == finfo.size ||
159
    (m_priv->_mmap && 0 == *static_cast<logchar*>(m_priv->_mmap->mm))))
160
  {
161
    return true;
162
  }
163
164
  return false;
165
}
166
167
void TimeBasedRollingPolicy::initMMapFile(const LogString& lastFileName, LOG4CXX_NS::helpers::Pool& pool)
168
{
169
  int iRet = 0;
170
171
  if (!m_priv->_mmap)
172
  {
173
    LOG4CXX_ENCODE_CHAR(mapFile, m_priv->_fileNamePattern);
174
    iRet = createMMapFile(mapFile, pool);
175
  }
176
177
  if (!iRet && isMapFileEmpty(pool))
178
  {
179
    lockMMapFile(APR_FLOCK_EXCLUSIVE);
180
    memset(m_priv->_mmap->mm, 0, MAX_FILE_LEN);
181
    size_t byteCount = sizeof (logchar) * lastFileName.size();
182
    if (byteCount <= MAX_FILE_LEN - sizeof (logchar))
183
      memcpy(m_priv->_mmap->mm, lastFileName.c_str(), byteCount);
184
    unLockMMapFile();
185
  }
186
}
187
188
const std::string TimeBasedRollingPolicy::createFile(const std::string& fileName, const std::string& suffix, LOG4CXX_NS::helpers::Pool& pool)
189
{
190
  char szUid[MAX_FILE_LEN] = "0000";
191
#ifndef _WIN32 // The uid provided by the Windows version of apr_uid_current is not a constant value
192
  apr_uid_t uid;
193
  apr_gid_t groupid;
194
  if (APR_SUCCESS == apr_uid_current(&uid, &groupid, pool.getAPRPool()))
195
    snprintf(szUid, MAX_FILE_LEN, "%u", uid);
196
#endif
197
  return fileName + szUid + suffix;
198
}
199
200
int TimeBasedRollingPolicy::createMMapFile(const std::string& fileName, LOG4CXX_NS::helpers::Pool& pool)
201
{
202
  m_priv->_mapFileName = createFile(fileName, MMAP_FILE_SUFFIX, pool);
203
204
  apr_status_t stat = apr_file_open(&m_priv->_file_map, m_priv->_mapFileName.c_str(), APR_CREATE | APR_READ | APR_WRITE, APR_OS_DEFAULT, m_priv->_mmapPool.getAPRPool());
205
206
  if (stat != APR_SUCCESS)
207
  {
208
    LogString msg = helpers::Exception::makeMessage(LOG4CXX_STR("apr_file_open"), stat);
209
    msg += LOG4CXX_STR(". Check the privilege or try to remove [");
210
    helpers::Transcoder::decode(m_priv->_mapFileName, msg);
211
    msg += LOG4CXX_STR("] if it exists.");
212
    LogLog::warn(msg);
213
    return -1;
214
  }
215
216
  if (isMapFileEmpty(pool))
217
  {
218
    stat = apr_file_trunc(m_priv->_file_map, MAX_FILE_LEN + 1);
219
220
    if (stat != APR_SUCCESS)
221
    {
222
      LogLog::warn(helpers::Exception::makeMessage(LOG4CXX_STR("apr_file_trunc"), stat));
223
      apr_file_close(m_priv->_file_map);
224
      return -1;
225
    }
226
  }
227
228
  stat = apr_mmap_create(&m_priv->_mmap, m_priv->_file_map, 0, MAX_FILE_LEN, APR_MMAP_WRITE | APR_MMAP_READ, m_priv->_mmapPool.getAPRPool());
229
230
  if (stat != APR_SUCCESS)
231
  {
232
    LogLog::warn(helpers::Exception::makeMessage(LOG4CXX_STR("apr_mmap_create"), stat));
233
    apr_file_close(m_priv->_file_map);
234
    return -1;
235
  }
236
237
  return 0;
238
}
239
240
int TimeBasedRollingPolicy::lockMMapFile(int type)
241
{
242
  apr_status_t stat = apr_file_lock(m_priv->_lock_file, type);
243
244
  if (stat != APR_SUCCESS)
245
  {
246
    LogLog::warn(helpers::Exception::makeMessage(LOG4CXX_STR("apr_file_lock for mmap"), stat));
247
  }
248
249
  return stat;
250
}
251
252
int TimeBasedRollingPolicy::unLockMMapFile()
253
{
254
  apr_status_t stat = apr_file_unlock(m_priv->_lock_file);
255
256
  if (stat != APR_SUCCESS)
257
  {
258
    LogLog::warn(helpers::Exception::makeMessage(LOG4CXX_STR("apr_file_unlock for mmap"), stat));
259
  }
260
261
  return stat;
262
}
263
#else
264
0
int TimeBasedRollingPolicy::createMMapFile(const std::string&, LOG4CXX_NS::helpers::Pool&) {
265
0
  return 0;
266
0
}
267
268
0
bool TimeBasedRollingPolicy::isMapFileEmpty(LOG4CXX_NS::helpers::Pool&){
269
0
  return true;
270
0
}
271
272
0
void TimeBasedRollingPolicy::initMMapFile(const LogString&, LOG4CXX_NS::helpers::Pool&){}
273
274
0
int TimeBasedRollingPolicy::lockMMapFile(int){
275
0
  return 0;
276
0
}
277
278
0
int TimeBasedRollingPolicy::unLockMMapFile(){
279
0
  return 0;
280
0
}
281
282
0
const std::string TimeBasedRollingPolicy::createFile(const std::string&, const std::string&, LOG4CXX_NS::helpers::Pool&){
283
0
  return "";
284
0
}
285
#endif
286
287
TimeBasedRollingPolicy::TimeBasedRollingPolicy() :
288
0
  m_priv(std::make_unique<TimeBasedRollingPolicyPrivate>())
289
0
{
290
0
}
Unexecuted instantiation: log4cxx::rolling::TimeBasedRollingPolicy::TimeBasedRollingPolicy()
Unexecuted instantiation: log4cxx::rolling::TimeBasedRollingPolicy::TimeBasedRollingPolicy()
291
292
0
TimeBasedRollingPolicy::~TimeBasedRollingPolicy(){}
293
294
void TimeBasedRollingPolicy::activateOptions( LOG4CXX_ACTIVATE_OPTIONS_FORMAL_PARAMETERS )
295
0
{
296
  // find out period from the filename pattern
297
0
  if (getFileNamePattern().length() > 0)
298
0
  {
299
0
    parseFileNamePattern();
300
0
  }
301
0
  else
302
0
  {
303
0
    LogLog::warn(
304
0
      LOG4CXX_STR("The FileNamePattern option must be set before using TimeBasedRollingPolicy. "));
305
0
    throw IllegalStateException();
306
0
  }
307
308
0
  PatternConverterPtr dtc(getDatePatternConverter());
309
310
0
  if (dtc == NULL)
311
0
  {
312
0
    throw NullPointerException(LOG4CXX_STR("DatePatternConverter"));
313
0
  }
314
315
0
  Pool pool;
316
0
  LogString buf;
317
0
  ObjectPtr obj = std::make_shared<Date>();
318
0
  formatFileName(obj, buf);
319
0
  m_priv->lastFileName = buf;
320
321
0
  m_priv->suffixLength = 0;
322
323
0
  if (m_priv->lastFileName.length() >= 3)
324
0
  {
325
0
    if (m_priv->lastFileName.compare(m_priv->lastFileName.length() - 3, 3, LOG4CXX_STR(".gz")) == 0)
326
0
    {
327
0
      m_priv->suffixLength = 3;
328
0
    }
329
0
    else if (m_priv->lastFileName.length() >= 4 && m_priv->lastFileName.compare(m_priv->lastFileName.length() - 4, 4, LOG4CXX_STR(".zip")) == 0)
330
0
    {
331
0
      m_priv->suffixLength = 4;
332
0
    }
333
0
  }
334
0
}
335
336
337
#define RULES_PUT(spec, cls) \
338
0
  specs.insert(PatternMap::value_type(LogString(LOG4CXX_STR(spec)), (PatternConstructor) cls ::newInstance))
339
340
LOG4CXX_NS::pattern::PatternMap TimeBasedRollingPolicy::getFormatSpecifiers() const
341
0
{
342
0
  PatternMap specs;
343
0
  RULES_PUT("d", FileDatePatternConverter);
344
0
  RULES_PUT("date", FileDatePatternConverter);
345
0
  return specs;
346
0
}
347
348
/**
349
 * {@inheritDoc}
350
 */
351
RolloverDescriptionPtr TimeBasedRollingPolicy::initialize( LOG4CXX_ROLLING_POLICY_INITIALIZE_FORMAL_PARAMETERS )
352
0
{
353
0
  Date now;
354
0
  log4cxx_time_t n = now.getTime();
355
0
  m_priv->nextCheck = now.getNextSecond();
356
357
0
  File currentFile(currentActiveFile);
358
359
0
  LogString buf;
360
0
  ObjectPtr obj = std::make_shared<Date>(currentFile.exists() ? currentFile.lastModified() : n);
361
0
  formatFileName(obj, buf);
362
0
  m_priv->lastFileName = buf;
363
364
0
  ActionPtr noAction;
365
366
0
  if (currentActiveFile.length() > 0)
367
0
  {
368
0
    return std::make_shared<RolloverDescription>(
369
0
          currentActiveFile, append, noAction, noAction);
370
0
  }
371
0
  else
372
0
  {
373
0
    m_priv->bRefreshCurFile = true;
374
0
    return std::make_shared<RolloverDescription>(
375
0
          m_priv->lastFileName.substr(0, m_priv->lastFileName.length() - m_priv->suffixLength), append,
376
0
          noAction, noAction);
377
0
  }
378
0
}
379
380
RolloverDescriptionPtr TimeBasedRollingPolicy::rollover( LOG4CXX_ROLLING_POLICY_ROLLOVER_FORMAL_PARAMETERS )
381
0
{
382
0
  Date now;
383
0
  log4cxx_time_t n = now.getTime();
384
0
  m_priv->nextCheck = now.getNextSecond();
385
386
0
  LogString buf;
387
0
  ObjectPtr obj = std::make_shared<Date>(n);
388
0
  formatFileName(obj, buf);
389
390
0
  LogString newFileName(buf);
391
392
0
  if( m_priv->multiprocess ){
393
#if LOG4CXX_HAS_MULTIPROCESS_ROLLING_FILE_APPENDER
394
395
    if (!m_priv->bAlreadyInitialized)
396
    {
397
      if (getPatternConverterList().size())
398
      {
399
        (*(getPatternConverterList().begin()))->format(obj, m_priv->_fileNamePattern);
400
      }
401
      else
402
      {
403
        m_priv->_fileNamePattern = m_priv->lastFileName;
404
      }
405
406
      if (!m_priv->_lock_file)
407
      {
408
        LOG4CXX_ENCODE_CHAR(mapFile, m_priv->_fileNamePattern);
409
        const std::string lockname = createFile(mapFile, LOCK_FILE_SUFFIX, m_priv->_mmapPool);
410
        apr_status_t stat = apr_file_open(&m_priv->_lock_file, lockname.c_str(), APR_CREATE | APR_READ | APR_WRITE, APR_OS_DEFAULT, m_priv->_mmapPool.getAPRPool());
411
412
        if (stat != APR_SUCCESS)
413
        {
414
          LOG4CXX_DECODE_CHAR(msg, lockname);
415
          msg += LOG4CXX_STR(": apr_file_open");
416
          LogLog::warn(helpers::Exception::makeMessage(msg, stat));
417
        }
418
      }
419
420
      initMMapFile(m_priv->lastFileName, m_priv->_mmapPool);
421
    }
422
    m_priv->bAlreadyInitialized = true;
423
424
    if (m_priv->_mmap && !isMapFileEmpty(m_priv->_mmapPool))
425
    {
426
      lockMMapFile(APR_FLOCK_SHARED);
427
      LogString mapLastFile(readMappedFileName(m_priv->_mmap));
428
      unLockMMapFile();
429
      if (!mapLastFile.empty())
430
        m_priv->lastFileName = mapLastFile;
431
    }
432
    else
433
    {
434
      m_priv->_mmap = NULL;
435
      initMMapFile(m_priv->lastFileName, m_priv->_mmapPool);
436
    }
437
#endif
438
0
  }
439
440
  //
441
  //  if file names haven't changed, no rollover
442
  //
443
0
  if (newFileName == m_priv->lastFileName)
444
0
  {
445
0
    RolloverDescriptionPtr desc;
446
0
    return desc;
447
0
  }
448
449
0
  ActionPtr renameAction;
450
0
  ActionPtr compressAction;
451
0
  LogString lastBaseName(
452
0
    m_priv->lastFileName.substr(0, m_priv->lastFileName.length() - m_priv->suffixLength));
453
0
  LogString nextActiveFile(
454
0
    newFileName.substr(0, newFileName.length() - m_priv->suffixLength));
455
456
0
  if(getCreateIntermediateDirectories()){
457
0
    File compressedFile(m_priv->lastFileName);
458
0
    File compressedParent (compressedFile.getParent());
459
0
    compressedParent.mkdirs();
460
0
  }
461
462
  //
463
  //   if currentActiveFile is not lastBaseName then
464
  //        active file name is not following file pattern
465
  //        and requires a rename plus maintaining the same name
466
0
  if (currentActiveFile != lastBaseName)
467
0
  {
468
0
    renameAction = std::make_shared<FileRenameAction>(
469
0
          File().setPath(currentActiveFile), File().setPath(lastBaseName), true);
470
0
    nextActiveFile = currentActiveFile;
471
0
  }
472
473
0
  if (m_priv->suffixLength == 3)
474
0
  {
475
0
    GZCompressActionPtr comp = std::make_shared<GZCompressAction>(
476
0
          File().setPath(lastBaseName), File().setPath(m_priv->lastFileName), true);
477
0
    comp->setThrowIOExceptionOnForkFailure(m_priv->throwIOExceptionOnForkFailure);
478
0
    compressAction = comp;
479
0
  }
480
481
0
  if (m_priv->suffixLength == 4)
482
0
  {
483
0
    ZipCompressActionPtr comp = std::make_shared<ZipCompressAction>(
484
0
          File().setPath(lastBaseName), File().setPath(m_priv->lastFileName), true);
485
0
    comp->setThrowIOExceptionOnForkFailure(m_priv->throwIOExceptionOnForkFailure);
486
0
    compressAction = comp;
487
0
  }
488
489
0
  if( m_priv->multiprocess ){
490
#if LOG4CXX_HAS_MULTIPROCESS_ROLLING_FILE_APPENDER
491
    size_t byteCount = sizeof (logchar) * newFileName.size();
492
    if (MAX_FILE_LEN - sizeof (logchar) < byteCount)
493
    {
494
      LogString msg(newFileName + LOG4CXX_STR(": cannot exceed "));
495
      StringHelper::toString(MAX_FILE_LEN / sizeof (logchar), msg);
496
      msg += LOG4CXX_STR(" characters");
497
      throw IllegalArgumentException(msg);
498
    }
499
    if (m_priv->_mmap && !isMapFileEmpty(m_priv->_mmapPool))
500
    {
501
      lockMMapFile(APR_FLOCK_EXCLUSIVE);
502
      memset(m_priv->_mmap->mm, 0, MAX_FILE_LEN);
503
      memcpy(m_priv->_mmap->mm, newFileName.c_str(), byteCount);
504
      unLockMMapFile();
505
    }
506
    else
507
    {
508
      m_priv->_mmap = NULL;
509
      initMMapFile(newFileName, m_priv->_mmapPool);
510
    }
511
#endif
512
0
  }else{
513
0
    m_priv->lastFileName = newFileName;
514
0
  }
515
516
0
  return std::make_shared<RolloverDescription>(nextActiveFile, append, renameAction, compressAction);
517
0
}
518
519
bool TimeBasedRollingPolicy::isTriggeringEvent(
520
  Appender* appender,
521
  const LOG4CXX_NS::spi::LoggingEventPtr& /* event */,
522
  const LogString&  filename,
523
  size_t /* fileLength */)
524
0
{
525
0
  if( m_priv->multiprocess ){
526
#if LOG4CXX_HAS_MULTIPROCESS_ROLLING_FILE_APPENDER
527
    if (m_priv->bRefreshCurFile && m_priv->_mmap && !isMapFileEmpty(m_priv->_mmapPool))
528
    {
529
      lockMMapFile(APR_FLOCK_SHARED);
530
      LogString mapCurrent(readMappedFileName(m_priv->_mmap));
531
      unLockMMapFile();
532
533
      if (!mapCurrent.empty() && static_cast<size_t>(m_priv->suffixLength) <= mapCurrent.length())
534
      {
535
        LogString mapCurrentBase(mapCurrent.substr(0, mapCurrent.length() - m_priv->suffixLength));
536
537
        if (!mapCurrentBase.empty() && mapCurrentBase != filename)
538
        {
539
          if (auto fappend = dynamic_cast<FileAppender*>(appender))
540
            fappend->setFile(mapCurrentBase);
541
        }
542
      }
543
    }
544
545
    return ( Date::currentTime() > m_priv->nextCheck) || (!m_priv->bAlreadyInitialized);
546
#endif
547
0
  }
548
549
0
  return Date::currentTime() > m_priv->nextCheck;
550
0
}
551
552
0
void TimeBasedRollingPolicy::setMultiprocess(bool multiprocess){
553
#if LOG4CXX_HAS_MULTIPROCESS_ROLLING_FILE_APPENDER
554
  // If we don't have the multiprocess stuff, disregard any attempt to set this value
555
  m_priv->multiprocess = multiprocess;
556
#endif
557
0
}
558
559
void TimeBasedRollingPolicy::setOption(const LogString& option,
560
  const LogString& value)
561
0
{
562
0
  if (StringHelper::equalsIgnoreCase(option,
563
0
      LOG4CXX_STR("THROWIOEXCEPTIONONFORKFAILURE"),
564
0
      LOG4CXX_STR("throwioexceptiononforkfailure")))
565
0
  {
566
0
    m_priv->throwIOExceptionOnForkFailure = OptionConverter::toBoolean(value, true);
567
0
  }
568
0
  else
569
0
  {
570
0
    RollingPolicyBase::setOption(option, value);
571
0
  }
572
0
}
573
574
/**
575
 * Was the name in shared memory set by this process?
576
 */
577
bool TimeBasedRollingPolicy::isLastFileNameUnchanged()
578
0
{
579
0
  bool result = true;
580
0
  if( m_priv->multiprocess ){
581
#if LOG4CXX_HAS_MULTIPROCESS_ROLLING_FILE_APPENDER
582
    if (m_priv->_mmap)
583
    {
584
      lockMMapFile(APR_FLOCK_SHARED);
585
      LogString mapCurrent(readMappedFileName(m_priv->_mmap));
586
      unLockMMapFile();
587
      result = (mapCurrent == m_priv->lastFileName);
588
    }
589
#endif
590
0
  }
591
0
  return result;
592
0
}
593
594
/**
595
 * Load the name (set by some other process) from shared memory
596
 */
597
void TimeBasedRollingPolicy::loadLastFileName()
598
0
{
599
0
  if( m_priv->multiprocess ){
600
#if LOG4CXX_HAS_MULTIPROCESS_ROLLING_FILE_APPENDER
601
    if (m_priv->_mmap)
602
    {
603
      lockMMapFile(APR_FLOCK_SHARED);
604
      LogString mapLastFile(readMappedFileName(m_priv->_mmap));
605
      unLockMMapFile();
606
      if (!mapLastFile.empty())
607
        m_priv->lastFileName = mapLastFile;
608
    }
609
#endif
610
0
  }
611
0
}