Coverage Report

Created: 2026-08-31 06:56

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
  // Create the coordination file with owner-only permissions: the
205
  // cooperating processes share the same uid (embedded in the file name),
206
  // and any other local user able to take a shared fcntl lock on a
207
  // world-readable coordination file could block rollover (and with it
208
  // every logging thread) indefinitely.
209
  apr_status_t stat = apr_file_open(&m_priv->_file_map, m_priv->_mapFileName.c_str(), APR_CREATE | APR_READ | APR_WRITE, APR_FPROT_UREAD | APR_FPROT_UWRITE, m_priv->_mmapPool.getAPRPool());
210
211
  if (stat != APR_SUCCESS)
212
  {
213
    LogString msg = helpers::Exception::makeMessage(LOG4CXX_STR("apr_file_open"), stat);
214
    msg += LOG4CXX_STR(". Check the privilege or try to remove [");
215
    helpers::Transcoder::decode(m_priv->_mapFileName, msg);
216
    msg += LOG4CXX_STR("] if it exists.");
217
    LogLog::warn(msg);
218
    return -1;
219
  }
220
221
  if (isMapFileEmpty(pool))
222
  {
223
    stat = apr_file_trunc(m_priv->_file_map, MAX_FILE_LEN + 1);
224
225
    if (stat != APR_SUCCESS)
226
    {
227
      LogLog::warn(helpers::Exception::makeMessage(LOG4CXX_STR("apr_file_trunc"), stat));
228
      apr_file_close(m_priv->_file_map);
229
      return -1;
230
    }
231
  }
232
233
  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());
234
235
  if (stat != APR_SUCCESS)
236
  {
237
    LogLog::warn(helpers::Exception::makeMessage(LOG4CXX_STR("apr_mmap_create"), stat));
238
    apr_file_close(m_priv->_file_map);
239
    return -1;
240
  }
241
242
  return 0;
243
}
244
245
int TimeBasedRollingPolicy::lockMMapFile(int type)
246
{
247
  apr_status_t stat = apr_file_lock(m_priv->_lock_file, type);
248
249
  if (stat != APR_SUCCESS)
250
  {
251
    LogLog::warn(helpers::Exception::makeMessage(LOG4CXX_STR("apr_file_lock for mmap"), stat));
252
  }
253
254
  return stat;
255
}
256
257
int TimeBasedRollingPolicy::unLockMMapFile()
258
{
259
  apr_status_t stat = apr_file_unlock(m_priv->_lock_file);
260
261
  if (stat != APR_SUCCESS)
262
  {
263
    LogLog::warn(helpers::Exception::makeMessage(LOG4CXX_STR("apr_file_unlock for mmap"), stat));
264
  }
265
266
  return stat;
267
}
268
#else
269
0
int TimeBasedRollingPolicy::createMMapFile(const std::string&, LOG4CXX_NS::helpers::Pool&) {
270
0
  return 0;
271
0
}
272
273
0
bool TimeBasedRollingPolicy::isMapFileEmpty(LOG4CXX_NS::helpers::Pool&){
274
0
  return true;
275
0
}
276
277
0
void TimeBasedRollingPolicy::initMMapFile(const LogString&, LOG4CXX_NS::helpers::Pool&){}
278
279
0
int TimeBasedRollingPolicy::lockMMapFile(int){
280
0
  return 0;
281
0
}
282
283
0
int TimeBasedRollingPolicy::unLockMMapFile(){
284
0
  return 0;
285
0
}
286
287
0
const std::string TimeBasedRollingPolicy::createFile(const std::string&, const std::string&, LOG4CXX_NS::helpers::Pool&){
288
0
  return "";
289
0
}
290
#endif
291
292
TimeBasedRollingPolicy::TimeBasedRollingPolicy() :
293
0
  m_priv(std::make_unique<TimeBasedRollingPolicyPrivate>())
294
0
{
295
0
}
Unexecuted instantiation: log4cxx::rolling::TimeBasedRollingPolicy::TimeBasedRollingPolicy()
Unexecuted instantiation: log4cxx::rolling::TimeBasedRollingPolicy::TimeBasedRollingPolicy()
296
297
0
TimeBasedRollingPolicy::~TimeBasedRollingPolicy(){}
298
299
void TimeBasedRollingPolicy::activateOptions( LOG4CXX_ACTIVATE_OPTIONS_FORMAL_PARAMETERS )
300
0
{
301
  // find out period from the filename pattern
302
0
  if (getFileNamePattern().length() > 0)
303
0
  {
304
0
    parseFileNamePattern();
305
0
  }
306
0
  else
307
0
  {
308
0
    LogLog::warn(
309
0
      LOG4CXX_STR("The FileNamePattern option must be set before using TimeBasedRollingPolicy. "));
310
0
    throw IllegalStateException();
311
0
  }
312
313
0
  PatternConverterPtr dtc(getDatePatternConverter());
314
315
0
  if (dtc == NULL)
316
0
  {
317
0
    throw NullPointerException(LOG4CXX_STR("DatePatternConverter"));
318
0
  }
319
320
0
  Pool pool;
321
0
  LogString buf;
322
0
  ObjectPtr obj = std::make_shared<Date>();
323
0
  formatFileName(obj, buf);
324
0
  m_priv->lastFileName = buf;
325
326
0
  m_priv->suffixLength = 0;
327
328
0
  if (m_priv->lastFileName.length() >= 3)
329
0
  {
330
0
    if (m_priv->lastFileName.compare(m_priv->lastFileName.length() - 3, 3, LOG4CXX_STR(".gz")) == 0)
331
0
    {
332
0
      m_priv->suffixLength = 3;
333
0
    }
334
0
    else if (m_priv->lastFileName.length() >= 4 && m_priv->lastFileName.compare(m_priv->lastFileName.length() - 4, 4, LOG4CXX_STR(".zip")) == 0)
335
0
    {
336
0
      m_priv->suffixLength = 4;
337
0
    }
338
0
  }
339
0
}
340
341
342
#define RULES_PUT(spec, cls) \
343
0
  specs.insert(PatternMap::value_type(LogString(LOG4CXX_STR(spec)), (PatternConstructor) cls ::newInstance))
344
345
LOG4CXX_NS::pattern::PatternMap TimeBasedRollingPolicy::getFormatSpecifiers() const
346
0
{
347
0
  PatternMap specs;
348
0
  RULES_PUT("d", FileDatePatternConverter);
349
0
  RULES_PUT("date", FileDatePatternConverter);
350
0
  return specs;
351
0
}
352
353
/**
354
 * {@inheritDoc}
355
 */
356
RolloverDescriptionPtr TimeBasedRollingPolicy::initialize( LOG4CXX_ROLLING_POLICY_INITIALIZE_FORMAL_PARAMETERS )
357
0
{
358
0
  Date now;
359
0
  log4cxx_time_t n = now.getTime();
360
0
  m_priv->nextCheck = now.getNextSecond();
361
362
0
  File currentFile(currentActiveFile);
363
364
0
  LogString buf;
365
0
  ObjectPtr obj = std::make_shared<Date>(currentFile.exists() ? currentFile.lastModified() : n);
366
0
  formatFileName(obj, buf);
367
0
  m_priv->lastFileName = buf;
368
369
0
  ActionPtr noAction;
370
371
0
  if (currentActiveFile.length() > 0)
372
0
  {
373
0
    return std::make_shared<RolloverDescription>(
374
0
          currentActiveFile, append, noAction, noAction);
375
0
  }
376
0
  else
377
0
  {
378
0
    m_priv->bRefreshCurFile = true;
379
0
    return std::make_shared<RolloverDescription>(
380
0
          m_priv->lastFileName.substr(0, m_priv->lastFileName.length() - m_priv->suffixLength), append,
381
0
          noAction, noAction);
382
0
  }
383
0
}
384
385
RolloverDescriptionPtr TimeBasedRollingPolicy::rollover( LOG4CXX_ROLLING_POLICY_ROLLOVER_FORMAL_PARAMETERS )
386
0
{
387
0
  Date now;
388
0
  log4cxx_time_t n = now.getTime();
389
0
  m_priv->nextCheck = now.getNextSecond();
390
391
0
  LogString buf;
392
0
  ObjectPtr obj = std::make_shared<Date>(n);
393
0
  formatFileName(obj, buf);
394
395
0
  LogString newFileName(buf);
396
397
0
  if( m_priv->multiprocess ){
398
#if LOG4CXX_HAS_MULTIPROCESS_ROLLING_FILE_APPENDER
399
400
    if (!m_priv->bAlreadyInitialized)
401
    {
402
      if (getPatternConverterList().size())
403
      {
404
        (*(getPatternConverterList().begin()))->format(obj, m_priv->_fileNamePattern);
405
      }
406
      else
407
      {
408
        m_priv->_fileNamePattern = m_priv->lastFileName;
409
      }
410
411
      if (!m_priv->_lock_file)
412
      {
413
        LOG4CXX_ENCODE_CHAR(mapFile, m_priv->_fileNamePattern);
414
        const std::string lockname = createFile(mapFile, LOCK_FILE_SUFFIX, m_priv->_mmapPool);
415
        // Owner-only permissions: see the comment in createMMapFile.
416
        apr_status_t stat = apr_file_open(&m_priv->_lock_file, lockname.c_str(), APR_CREATE | APR_READ | APR_WRITE, APR_FPROT_UREAD | APR_FPROT_UWRITE, m_priv->_mmapPool.getAPRPool());
417
418
        if (stat != APR_SUCCESS)
419
        {
420
          LOG4CXX_DECODE_CHAR(msg, lockname);
421
          msg += LOG4CXX_STR(": apr_file_open");
422
          LogLog::warn(helpers::Exception::makeMessage(msg, stat));
423
        }
424
      }
425
426
      initMMapFile(m_priv->lastFileName, m_priv->_mmapPool);
427
    }
428
    m_priv->bAlreadyInitialized = true;
429
430
    if (m_priv->_mmap && !isMapFileEmpty(m_priv->_mmapPool))
431
    {
432
      lockMMapFile(APR_FLOCK_SHARED);
433
      LogString mapLastFile(readMappedFileName(m_priv->_mmap));
434
      unLockMMapFile();
435
      if (!mapLastFile.empty())
436
        m_priv->lastFileName = mapLastFile;
437
    }
438
    else
439
    {
440
      m_priv->_mmap = NULL;
441
      initMMapFile(m_priv->lastFileName, m_priv->_mmapPool);
442
    }
443
#endif
444
0
  }
445
446
  //
447
  //  if file names haven't changed, no rollover
448
  //
449
0
  if (newFileName == m_priv->lastFileName)
450
0
  {
451
0
    RolloverDescriptionPtr desc;
452
0
    return desc;
453
0
  }
454
455
0
  ActionPtr renameAction;
456
0
  ActionPtr compressAction;
457
0
  LogString lastBaseName(
458
0
    m_priv->lastFileName.substr(0, m_priv->lastFileName.length() - m_priv->suffixLength));
459
0
  LogString nextActiveFile(
460
0
    newFileName.substr(0, newFileName.length() - m_priv->suffixLength));
461
462
0
  if(getCreateIntermediateDirectories()){
463
0
    File compressedFile(m_priv->lastFileName);
464
0
    File compressedParent (compressedFile.getParent());
465
0
    compressedParent.mkdirs();
466
0
  }
467
468
  //
469
  //   if currentActiveFile is not lastBaseName then
470
  //        active file name is not following file pattern
471
  //        and requires a rename plus maintaining the same name
472
0
  if (currentActiveFile != lastBaseName)
473
0
  {
474
0
    renameAction = std::make_shared<FileRenameAction>(
475
0
          File().setPath(currentActiveFile), File().setPath(lastBaseName), true);
476
0
    nextActiveFile = currentActiveFile;
477
0
  }
478
479
0
  if (m_priv->suffixLength == 3)
480
0
  {
481
0
    GZCompressActionPtr comp = std::make_shared<GZCompressAction>(
482
0
          File().setPath(lastBaseName), File().setPath(m_priv->lastFileName), true);
483
0
    comp->setThrowIOExceptionOnForkFailure(m_priv->throwIOExceptionOnForkFailure);
484
0
    compressAction = comp;
485
0
  }
486
487
0
  if (m_priv->suffixLength == 4)
488
0
  {
489
0
    ZipCompressActionPtr comp = std::make_shared<ZipCompressAction>(
490
0
          File().setPath(lastBaseName), File().setPath(m_priv->lastFileName), true);
491
0
    comp->setThrowIOExceptionOnForkFailure(m_priv->throwIOExceptionOnForkFailure);
492
0
    compressAction = comp;
493
0
  }
494
495
0
  if( m_priv->multiprocess ){
496
#if LOG4CXX_HAS_MULTIPROCESS_ROLLING_FILE_APPENDER
497
    size_t byteCount = sizeof (logchar) * newFileName.size();
498
    if (MAX_FILE_LEN - sizeof (logchar) < byteCount)
499
    {
500
      LogString msg(newFileName + LOG4CXX_STR(": cannot exceed "));
501
      StringHelper::toString(MAX_FILE_LEN / sizeof (logchar), msg);
502
      msg += LOG4CXX_STR(" characters");
503
      throw IllegalArgumentException(msg);
504
    }
505
    if (m_priv->_mmap && !isMapFileEmpty(m_priv->_mmapPool))
506
    {
507
      lockMMapFile(APR_FLOCK_EXCLUSIVE);
508
      memset(m_priv->_mmap->mm, 0, MAX_FILE_LEN);
509
      memcpy(m_priv->_mmap->mm, newFileName.c_str(), byteCount);
510
      unLockMMapFile();
511
    }
512
    else
513
    {
514
      m_priv->_mmap = NULL;
515
      initMMapFile(newFileName, m_priv->_mmapPool);
516
    }
517
#endif
518
0
  }else{
519
0
    m_priv->lastFileName = newFileName;
520
0
  }
521
522
0
  return std::make_shared<RolloverDescription>(nextActiveFile, append, renameAction, compressAction);
523
0
}
524
525
bool TimeBasedRollingPolicy::isTriggeringEvent(
526
  Appender* appender,
527
  const LOG4CXX_NS::spi::LoggingEventPtr& /* event */,
528
  const LogString&  filename,
529
  size_t /* fileLength */)
530
0
{
531
0
  if( m_priv->multiprocess ){
532
#if LOG4CXX_HAS_MULTIPROCESS_ROLLING_FILE_APPENDER
533
    if (m_priv->bRefreshCurFile && m_priv->_mmap && !isMapFileEmpty(m_priv->_mmapPool))
534
    {
535
      lockMMapFile(APR_FLOCK_SHARED);
536
      LogString mapCurrent(readMappedFileName(m_priv->_mmap));
537
      unLockMMapFile();
538
539
      if (!mapCurrent.empty() && static_cast<size_t>(m_priv->suffixLength) <= mapCurrent.length())
540
      {
541
        LogString mapCurrentBase(mapCurrent.substr(0, mapCurrent.length() - m_priv->suffixLength));
542
543
        if (!mapCurrentBase.empty() && mapCurrentBase != filename)
544
        {
545
          if (auto fappend = dynamic_cast<FileAppender*>(appender))
546
            fappend->setFile(mapCurrentBase);
547
        }
548
      }
549
    }
550
551
    return ( Date::currentTime() > m_priv->nextCheck) || (!m_priv->bAlreadyInitialized);
552
#endif
553
0
  }
554
555
0
  return Date::currentTime() > m_priv->nextCheck;
556
0
}
557
558
0
void TimeBasedRollingPolicy::setMultiprocess(bool multiprocess){
559
#if LOG4CXX_HAS_MULTIPROCESS_ROLLING_FILE_APPENDER
560
  // If we don't have the multiprocess stuff, disregard any attempt to set this value
561
  m_priv->multiprocess = multiprocess;
562
#endif
563
0
}
564
565
void TimeBasedRollingPolicy::setOption(const LogString& option,
566
  const LogString& value)
567
0
{
568
0
  if (StringHelper::equalsIgnoreCase(option,
569
0
      LOG4CXX_STR("THROWIOEXCEPTIONONFORKFAILURE"),
570
0
      LOG4CXX_STR("throwioexceptiononforkfailure")))
571
0
  {
572
0
    m_priv->throwIOExceptionOnForkFailure = OptionConverter::toBoolean(value, true);
573
0
  }
574
0
  else
575
0
  {
576
0
    RollingPolicyBase::setOption(option, value);
577
0
  }
578
0
}
579
580
/**
581
 * Was the name in shared memory set by this process?
582
 */
583
bool TimeBasedRollingPolicy::isLastFileNameUnchanged()
584
0
{
585
0
  bool result = true;
586
0
  if( m_priv->multiprocess ){
587
#if LOG4CXX_HAS_MULTIPROCESS_ROLLING_FILE_APPENDER
588
    if (m_priv->_mmap)
589
    {
590
      lockMMapFile(APR_FLOCK_SHARED);
591
      LogString mapCurrent(readMappedFileName(m_priv->_mmap));
592
      unLockMMapFile();
593
      result = (mapCurrent == m_priv->lastFileName);
594
    }
595
#endif
596
0
  }
597
0
  return result;
598
0
}
599
600
/**
601
 * Load the name (set by some other process) from shared memory
602
 */
603
void TimeBasedRollingPolicy::loadLastFileName()
604
0
{
605
0
  if( m_priv->multiprocess ){
606
#if LOG4CXX_HAS_MULTIPROCESS_ROLLING_FILE_APPENDER
607
    if (m_priv->_mmap)
608
    {
609
      lockMMapFile(APR_FLOCK_SHARED);
610
      LogString mapLastFile(readMappedFileName(m_priv->_mmap));
611
      unLockMMapFile();
612
      if (!mapLastFile.empty())
613
        m_priv->lastFileName = mapLastFile;
614
    }
615
#endif
616
0
  }
617
0
}