张洋 5 месяцев назад
Родитель
Сommit
fa345bf07f
89 измененных файлов с 1727 добавлено и 2408 удалено
  1. BIN
      bin/Win32/Release/zhipuzi_pos_windows/log4cplusU.dll
  2. BIN
      dll/debug/log4cplusUD.dll
  3. BIN
      dll/release/log4cplusU.dll
  4. 63 12
      include/log4cplus/appender.h
  5. 28 8
      include/log4cplus/asyncappender.h
  6. 1 1
      include/log4cplus/boost/deviceappender.hxx
  7. 73 0
      include/log4cplus/callbackappender.h
  8. 1 1
      include/log4cplus/clfsappender.h
  9. 50 9
      include/log4cplus/clogger.h
  10. 0 12
      include/log4cplus/config.h.cmake.in
  11. 6 88
      include/log4cplus/config.h.in
  12. 40 21
      include/log4cplus/config.hxx
  13. 3 47
      include/log4cplus/config/defines.hxx.in
  14. 1 1
      include/log4cplus/config/macosx.h
  15. 8 28
      include/log4cplus/config/win32.h
  16. 42 0
      include/log4cplus/config/windowsh-inc-full.h
  17. 1 1
      include/log4cplus/config/windowsh-inc.h
  18. 17 1
      include/log4cplus/configurator.h
  19. 21 1
      include/log4cplus/consoleappender.h
  20. 56 0
      include/log4cplus/exception.h
  21. 11 5
      include/log4cplus/fileappender.h
  22. 1 1
      include/log4cplus/fstreams.h
  23. 1 1
      include/log4cplus/helpers/appenderattachableimpl.h
  24. 1 1
      include/log4cplus/helpers/connectorthread.h
  25. 91 0
      include/log4cplus/helpers/eventcounter.h
  26. 1 1
      include/log4cplus/helpers/fileinfo.h
  27. 1 1
      include/log4cplus/helpers/lockfile.h
  28. 1 1
      include/log4cplus/helpers/loglog.h
  29. 0 64
      include/log4cplus/helpers/logloguser.h
  30. 24 23
      include/log4cplus/helpers/pointer.h
  31. 11 1
      include/log4cplus/helpers/property.h
  32. 7 7
      include/log4cplus/helpers/queue.h
  33. 0 43
      include/log4cplus/helpers/sleep.h
  34. 1 1
      include/log4cplus/helpers/snprintf.h
  35. 38 16
      include/log4cplus/helpers/socket.h
  36. 1 1
      include/log4cplus/helpers/socketbuffer.h
  37. 29 8
      include/log4cplus/helpers/stringhelper.h
  38. 4 7
      include/log4cplus/helpers/thread-config.h
  39. 111 121
      include/log4cplus/helpers/timehelper.h
  40. 22 23
      include/log4cplus/hierarchy.h
  41. 8 9
      include/log4cplus/hierarchylocker.h
  42. 62 0
      include/log4cplus/initializer.h
  43. 151 0
      include/log4cplus/internal/customloglevelmanager.h
  44. 1 1
      include/log4cplus/internal/cygwin-win32.h
  45. 5 1
      include/log4cplus/internal/env.h
  46. 1 1
      include/log4cplus/internal/internal.h
  47. 5 8
      include/log4cplus/internal/socket.h
  48. 8 7
      include/log4cplus/layout.h
  49. 66 0
      include/log4cplus/log4cplus.h
  50. 9 4
      include/log4cplus/log4judpappender.h
  51. 48 48
      include/log4cplus/logger.h
  52. 31 96
      include/log4cplus/loggingmacros.h
  53. 25 34
      include/log4cplus/loglevel.h
  54. 1 1
      include/log4cplus/mdc.h
  55. 8 8
      include/log4cplus/msttsappender.h
  56. 14 11
      include/log4cplus/ndc.h
  57. 1 1
      include/log4cplus/nteventlogappender.h
  58. 1 1
      include/log4cplus/nullappender.h
  59. 8 8
      include/log4cplus/qt4debugappender.h
  60. 8 8
      include/log4cplus/qt5debugappender.h
  61. 11 6
      include/log4cplus/socketappender.h
  62. 3 5
      include/log4cplus/spi/appenderattachable.h
  63. 12 12
      include/log4cplus/spi/factory.h
  64. 141 24
      include/log4cplus/spi/filter.h
  65. 8 3
      include/log4cplus/spi/loggerfactory.h
  66. 21 26
      include/log4cplus/spi/loggerimpl.h
  67. 5 7
      include/log4cplus/spi/loggingevent.h
  68. 1 1
      include/log4cplus/spi/objectregistry.h
  69. 2 2
      include/log4cplus/spi/rootlogger.h
  70. 1 1
      include/log4cplus/streams.h
  71. 18 5
      include/log4cplus/syslogappender.h
  72. 1 1
      include/log4cplus/tchar.h
  73. 6 221
      include/log4cplus/thread/impl/syncprims-cxx11.h
  74. 9 181
      include/log4cplus/thread/impl/syncprims-impl.h
  75. 8 8
      include/log4cplus/thread/impl/syncprims-pmsm.h
  76. 0 507
      include/log4cplus/thread/impl/syncprims-pthreads.h
  77. 0 328
      include/log4cplus/thread/impl/syncprims-win32.h
  78. 1 65
      include/log4cplus/thread/impl/threads-impl.h
  79. 21 8
      include/log4cplus/thread/impl/tls.h
  80. 133 80
      include/log4cplus/thread/syncprims-pub-impl.h
  81. 47 75
      include/log4cplus/thread/syncprims.h
  82. 31 14
      include/log4cplus/thread/threads.h
  83. 7 6
      include/log4cplus/tracelogger.h
  84. 3 9
      include/log4cplus/tstring.h
  85. 7 7
      include/log4cplus/version.h
  86. 1 1
      include/log4cplus/win32consoleappender.h
  87. 1 1
      include/log4cplus/win32debugappender.h
  88. BIN
      lib/debug/log4cplusUD.lib
  89. BIN
      lib/release/log4cplusU.lib

BIN
bin/Win32/Release/zhipuzi_pos_windows/log4cplusU.dll


BIN
dll/debug/log4cplusUD.dll


BIN
dll/release/log4cplusU.dll


+ 63 - 12
include/log4cplus/appender.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2001-2015 Tad E. Smith
+// Copyright 2001-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -38,6 +38,9 @@
 #include <log4cplus/helpers/lockfile.h>
 
 #include <memory>
+#include <mutex>
+#include <atomic>
+#include <condition_variable>
 
 
 namespace log4cplus {
@@ -124,6 +127,11 @@ namespace log4cplus {
      * is mandatory.
      * \sa FileAppender
      * </dd>
+     *
+     * <dt><tt>AsyncAppend</tt></dt>
+     * <dd>Set this property to <tt>true</tt> if you want all appends using
+     * this appender to be done asynchronously. Default is <tt>false</tt>.</dd>
+     *
      * </dl>
      */
     class LOG4CPLUS_EXPORT Appender
@@ -151,7 +159,7 @@ namespace log4cplus {
         /**
          * Release any resources allocated within the appender such as file
          * handles, network connections, etc.
-         * 
+         *
          * It is a programming error to append to a closed appender.
          */
         virtual void close() = 0;
@@ -166,6 +174,20 @@ namespace log4cplus {
          * delegating actual logging to the subclasses specific {@link
          * #append} method.
          */
+        void syncDoAppend(const log4cplus::spi::InternalLoggingEvent& event);
+
+        /**
+         * This method performs book keeping related to asynchronous logging
+         * and executes `syncDoAppend()` to do the actual logging.
+         */
+
+        void asyncDoAppend(const log4cplus::spi::InternalLoggingEvent& event);
+
+        /**
+         * This function checks `async` flag. It either executes
+         * `syncDoAppend()` directly or enqueues its execution to thread pool
+         * thread.
+         */
         void doAppend(const log4cplus::spi::InternalLoggingEvent& event);
 
         /**
@@ -183,7 +205,7 @@ namespace log4cplus {
         /**
          * Set the {@link ErrorHandler} for this Appender.
          */
-        virtual void setErrorHandler(std::auto_ptr<ErrorHandler> eh);
+        virtual void setErrorHandler(std::unique_ptr<ErrorHandler> eh);
 
         /**
          * Return the currently set {@link ErrorHandler} for this
@@ -196,11 +218,11 @@ namespace log4cplus {
          * their own (fixed) layouts or do not use one. For example, the
          * SocketAppender ignores the layout set here.
          */
-        virtual void setLayout(std::auto_ptr<Layout> layout);
+        virtual void setLayout(std::unique_ptr<Layout> layout);
 
         /**
          * Returns the layout of this appender. The value may be NULL.
-         * 
+         *
          * This class owns the returned pointer.
          */
         virtual Layout* getLayout();
@@ -208,12 +230,23 @@ namespace log4cplus {
         /**
          * Set the filter chain on this Appender.
          */
-        void setFilter(log4cplus::spi::FilterPtr f) { filter = f; }
+        void setFilter(log4cplus::spi::FilterPtr f);
 
         /**
          * Get the filter chain on this Appender.
          */
-        log4cplus::spi::FilterPtr getFilter() const { return filter; }
+        log4cplus::spi::FilterPtr getFilter() const;
+
+        /**
+         * Add filter at the end of the filters chain.
+         */
+        void addFilter (log4cplus::spi::FilterPtr f);
+
+        /**
+         * Add filter at the end of the filters chain.
+         */
+        void addFilter (std::function<
+            spi::FilterResult (const log4cplus::spi::InternalLoggingEvent &)>);
 
         /**
          * Returns this appenders threshold LogLevel. See the {@link
@@ -224,7 +257,7 @@ namespace log4cplus {
         /**
          * Set the threshold LogLevel. All log events with lower LogLevel
          * than the threshold LogLevel are ignored by the appender.
-         * 
+         *
          * In configuration files this option is specified by setting the
          * value of the <b>Threshold</b> option to a LogLevel
          * string, such as "DEBUG", "INFO" and so on.
@@ -240,6 +273,12 @@ namespace log4cplus {
             return ((ll != NOT_SET_LOG_LEVEL) && (ll >= threshold));
         }
 
+        /**
+         * This method waits for all events that are being asynchronously
+         * logged to finish.
+         */
+        void waitToFinishAsyncLogging();
+
     protected:
       // Methods
         /**
@@ -254,7 +293,7 @@ namespace log4cplus {
       // Data
         /** The layout variable does not need to be set if the appender
          *  implementation has its own layout. */
-        std::auto_ptr<Layout> layout;
+        std::unique_ptr<Layout> layout;
 
         /** Appenders are named. */
         log4cplus::tstring name;
@@ -267,17 +306,30 @@ namespace log4cplus {
         log4cplus::spi::FilterPtr filter;
 
         /** It is assumed and enforced that errorHandler is never null. */
-        std::auto_ptr<ErrorHandler> errorHandler;
+        std::unique_ptr<ErrorHandler> errorHandler;
 
         //! Optional system wide synchronization lock.
-        std::auto_ptr<helpers::LockFile> lockFile;
+        std::unique_ptr<helpers::LockFile> lockFile;
 
         //! Use lock file for inter-process synchronization of access
         //! to log file.
         bool useLockFile;
 
+        //! Asynchronous append.
+        bool async;
+#if ! defined (LOG4CPLUS_SINGLE_THREADED)
+        std::atomic<std::size_t> in_flight;
+        std::mutex in_flight_mutex;
+        std::condition_variable in_flight_condition;
+#endif
+
         /** Is this appender closed? */
         bool closed;
+
+    private:
+#if ! defined (LOG4CPLUS_SINGLE_THREADED)
+        void subtract_in_flight();
+#endif
     };
 
     /** This is a pointer to an Appender. */
@@ -286,4 +338,3 @@ namespace log4cplus {
 } // end namespace log4cplus
 
 #endif // LOG4CPLUS_APPENDER_HEADER_
-

+ 28 - 8
include/log4cplus/asyncappender.h

@@ -2,21 +2,21 @@
 // Module:  Log4cplus
 // File:    asyncappender.h
 // Created: 1/2009
-// Author:  Vaclav Haisman  
+// Author:  Vaclav Haisman
 //
 //
-//  Copyright (C) 2009-2015, Vaclav Haisman. All rights reserved.
-//  
+//  Copyright (C) 2009-2017, Vaclav Haisman. All rights reserved.
+//
 //  Redistribution and use in source and binary forms, with or without modifica-
 //  tion, are permitted provided that the following conditions are met:
-//  
+//
 //  1. Redistributions of  source code must  retain the above copyright  notice,
 //     this list of conditions and the following disclaimer.
-//  
+//
 //  2. Redistributions in binary form must reproduce the above copyright notice,
 //     this list of conditions and the following disclaimer in the documentation
 //     and/or other materials provided with the distribution.
-//  
+//
 //  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 //  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 //  FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
@@ -27,8 +27,8 @@
 //  ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
 //  (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
 //  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-   
- 
+
+
 //
 
 /** @file */
@@ -54,6 +54,26 @@ namespace log4cplus
 {
 
 
+/**
+   This `Appender` is a wrapper to which other appenders can be attached. The
+   attached appendres are then appended to from a separate thread which reads
+   events appended to this appender from a queue.
+
+   <h3>Properties</h3>
+   <dl>
+
+   <dt><tt>QueueLimit</tt></dt>
+   <dd>Events queue size limit. Default is 100.</dd>
+   </dt>
+
+   <dt><tt>Appender</tt></dt>
+   <dd>`Appender` and its properties to use as sink for logged events.</dd>
+   </dt>
+
+   </dl>
+
+   \sa helpers::AppenderAttachableImpl
+ */
 class LOG4CPLUS_EXPORT AsyncAppender
     : public Appender
     , public helpers::AppenderAttachableImpl

+ 1 - 1
include/log4cplus/boost/deviceappender.hxx

@@ -1,4 +1,4 @@
-//  Copyright (C) 2009-2015, Vaclav Haisman. All rights reserved.
+//  Copyright (C) 2009-2017, Vaclav Haisman. All rights reserved.
 //
 //  Redistribution and use in source and binary forms, with or without modifica-
 //  tion, are permitted provided that the following conditions are met:

+ 73 - 0
include/log4cplus/callbackappender.h

@@ -0,0 +1,73 @@
+// -*- C++ -*-
+//  Copyright (C) 2015-2017, Vaclav Haisman. All rights reserved.
+//
+//  Redistribution and use in source and binary forms, with or without modifica-
+//  tion, are permitted provided that the following conditions are met:
+//
+//  1. Redistributions of  source code must  retain the above copyright  notice,
+//     this list of conditions and the following disclaimer.
+//
+//  2. Redistributions in binary form must reproduce the above copyright notice,
+//     this list of conditions and the following disclaimer in the documentation
+//     and/or other materials provided with the distribution.
+//
+//  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+//  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+//  FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
+//  APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
+//  INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
+//  DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
+//  OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
+//  ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
+//  (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
+//  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+/** @file */
+
+#ifndef LOG4CPLUS_CALLBACK_APPENDER_HEADER_
+#define LOG4CPLUS_CALLBACK_APPENDER_HEADER_
+
+#include <log4cplus/config.hxx>
+
+#if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
+#pragma once
+#endif
+
+#include <log4cplus/appender.h>
+#include <log4cplus/clogger.h>
+
+
+namespace log4cplus {
+
+/**
+* Send log events to a C function callback.
+*/
+class LOG4CPLUS_EXPORT CallbackAppender
+    : public Appender {
+public:
+    CallbackAppender();
+    CallbackAppender(log4cplus_log_event_callback_t callback, void * cookie);
+    CallbackAppender(const log4cplus::helpers::Properties&);
+
+    virtual ~CallbackAppender();
+    virtual void close();
+
+    void setCookie(void *);
+    void setCallback(log4cplus_log_event_callback_t);
+
+protected:
+    virtual void append(const log4cplus::spi::InternalLoggingEvent& event);
+
+private:
+    log4cplus_log_event_callback_t callback;
+    void * cookie;
+
+    // Disallow copying of instances of this class
+    CallbackAppender(const CallbackAppender&) = delete;
+    CallbackAppender& operator=(const CallbackAppender&) = delete;
+};
+
+} // end namespace log4cplus
+
+#endif // LOG4CPLUS_CALLBACK_APPENDER_HEADER_

+ 1 - 1
include/log4cplus/clfsappender.h

@@ -5,7 +5,7 @@
 // Author:  Vaclav Zeman
 //
 //
-//  Copyright (C) 2012-2015, Vaclav Zeman. All rights reserved.
+//  Copyright (C) 2012-2017, Vaclav Zeman. All rights reserved.
 //  
 //  Redistribution and use in source and binary forms, with or without modifica-
 //  tion, are permitted provided that the following conditions are met:

+ 50 - 9
include/log4cplus/clogger.h

@@ -6,7 +6,7 @@
  * Author:  Jens Rehsack
  *
  *
- * Copyright 2011-2015 Jens Rehsack & Tad E. Smith
+ * Copyright 2011-2017 Jens Rehsack & Tad E. Smith
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@
  * limitations under the License.
  */
 
-/** @file 
+/** @file
  * This header defines the C API for log4cplus and the logging macros. */
 
 #ifndef LOG4CPLUS_CLOGGERHEADER_
@@ -41,8 +41,11 @@ extern "C"
 
 // TODO UNICDE capable
 
-typedef void *logger_t;
-typedef int loglevel_t;
+typedef void * log4cplus_logger_t;
+typedef log4cplus_logger_t logger_t;
+
+typedef int log4cplus_loglevel_t;
+typedef log4cplus_loglevel_t loglevel_t;
 
 #define L4CP_OFF_LOG_LEVEL 60000
 #define L4CP_FATAL_LOG_LEVEL 50000
@@ -55,29 +58,67 @@ typedef int loglevel_t;
 #define L4CP_NOT_SET_LOG_LEVEL -1
 
 #ifdef UNICODE
-#  define LOG4CPLUS_TEXT2(STRING) L##STRING
 typedef wchar_t log4cplus_char_t;
 #else
-#  define LOG4CPLUS_TEXT2(STRING) STRING
 typedef char log4cplus_char_t;
 #endif // UNICODE
+
+#if ! defined (LOG4CPLUS_TEXT)
+#ifdef UNICODE
+#  define LOG4CPLUS_TEXT2(STRING) L##STRING
+#else
+#  define LOG4CPLUS_TEXT2(STRING) STRING
+#endif // UNICODE
 #define LOG4CPLUS_TEXT(STRING) LOG4CPLUS_TEXT2(STRING)
+#endif // LOG4CPLUS_TEXT
+
+LOG4CPLUS_EXPORT void * log4cplus_initialize(void);
+LOG4CPLUS_EXPORT int log4cplus_deinitialize(void * initializer);
 
 LOG4CPLUS_EXPORT int log4cplus_file_configure(const log4cplus_char_t *pathname);
+LOG4CPLUS_EXPORT int log4cplus_file_reconfigure(const log4cplus_char_t *pathname);
 LOG4CPLUS_EXPORT int log4cplus_str_configure(const log4cplus_char_t *config);
+LOG4CPLUS_EXPORT int log4cplus_str_reconfigure(const log4cplus_char_t *config);
 LOG4CPLUS_EXPORT int log4cplus_basic_configure(void);
+LOG4CPLUS_EXPORT int log4cplus_basic_reconfigure(int logToStdErr);
 LOG4CPLUS_EXPORT void log4cplus_shutdown(void);
 
 LOG4CPLUS_EXPORT int log4cplus_logger_exists(const log4cplus_char_t *name);
 LOG4CPLUS_EXPORT int log4cplus_logger_is_enabled_for(
-    const log4cplus_char_t *name, loglevel_t ll);
+    const log4cplus_char_t *name, log4cplus_loglevel_t ll);
+
 LOG4CPLUS_EXPORT int log4cplus_logger_log(const log4cplus_char_t *name,
-    loglevel_t ll, const log4cplus_char_t *msgfmt, ...)
+    log4cplus_loglevel_t ll, const log4cplus_char_t *msgfmt, ...)
     LOG4CPLUS_FORMAT_ATTRIBUTE (__printf__, 3, 4);
+
+LOG4CPLUS_EXPORT int log4cplus_logger_log_str(const log4cplus_char_t *name,
+    log4cplus_loglevel_t ll, const log4cplus_char_t *msg);
+
 LOG4CPLUS_EXPORT int log4cplus_logger_force_log(const log4cplus_char_t *name,
-    loglevel_t ll, const log4cplus_char_t *msgfmt, ...)
+    log4cplus_loglevel_t ll, const log4cplus_char_t *msgfmt, ...)
     LOG4CPLUS_FORMAT_ATTRIBUTE (__printf__, 3, 4);
 
+LOG4CPLUS_EXPORT int log4cplus_logger_force_log_str(const log4cplus_char_t *name,
+    log4cplus_loglevel_t ll, const log4cplus_char_t *msg);
+
+//! CallbackAppender callback type.
+typedef void (* log4cplus_log_event_callback_t)(void * cookie,
+    log4cplus_char_t const * message, log4cplus_char_t const * loggerName,
+    log4cplus_loglevel_t ll, log4cplus_char_t const * thread,
+    log4cplus_char_t const * thread2,
+    unsigned long long timestamp_secs, unsigned long timestamp_usecs,
+    log4cplus_char_t const * file, log4cplus_char_t const * function, int line);
+
+LOG4CPLUS_EXPORT int log4cplus_add_callback_appender(
+    const log4cplus_char_t * logger, log4cplus_log_event_callback_t callback,
+    void * cookie);
+
+// Custom LogLevel
+LOG4CPLUS_EXPORT int log4cplus_add_log_level(unsigned int ll,
+    const log4cplus_char_t *ll_name);
+LOG4CPLUS_EXPORT int log4cplus_remove_log_level(unsigned int ll,
+    const log4cplus_char_t *ll_name);
+
 #ifdef __cplusplus
 }
 #endif

+ 0 - 12
include/log4cplus/config.h.cmake.in

@@ -168,9 +168,6 @@
 /* Defined if the compiler understands __declspec(dllexport) or construct. */
 #define LOG4CPLUS_DECLSPEC_IMPORT @LOG4CPLUS_DECLSPEC_IMPORT@ /**/
 
-/* */
-#cmakedefine LOG4CPLUS_HAVE_C99_VARIADIC_MACROS 1
-
 /* */
 #cmakedefine LOG4CPLUS_HAVE_CLOCK_GETTIME 1
 
@@ -204,9 +201,6 @@
 /* */
 #cmakedefine LOG4CPLUS_HAVE_GMTIME_R 1
 
-/* */
-#cmakedefine LOG4CPLUS_HAVE_GNU_VARIADIC_MACROS 1
-
 /* */
 #cmakedefine LOG4CPLUS_HAVE_HTONL 1
 
@@ -318,12 +312,6 @@
 /* */
 #cmakedefine LOG4CPLUS_HAVE__VSNWPRINTF_S 1
 
-/* */
-#cmakedefine LOG4CPLUS_HAVE___SYNC_ADD_AND_FETCH 1
-
-/* */
-#cmakedefine LOG4CPLUS_HAVE___SYNC_SUB_AND_FETCH 1
-
 /* Define if this is a single-threaded library. */
 #undef LOG4CPLUS_SINGLE_THREADED
 

+ 6 - 88
include/log4cplus/config.h.in

@@ -4,28 +4,8 @@
 
 #define LOG4CPLUS_CONFIG_H
 
-/* Defined if the compiler supports C99 style variadic macros with
-   __VA_ARGS__. */
-#undef HAS_C99_VARIADIC_MACROS
-
-/* Defined if the compiler supports GNU style variadic macros. */
-#undef HAS_GNU_VARIADIC_MACROS
-
-/* Defined if the compiler provides atomic_dec_uint_nv(). */
-#undef HAVE_ATOMIC_DEC_UINT_NV
-
-/* Defined if the compiler provides atomic_inc_uint(). */
-#undef HAVE_ATOMIC_INC_UINT
-
-/* Define to 1 if you have the `clock_gettime' function. */
-#undef HAVE_CLOCK_GETTIME
-
-/* Define to 1 if you have the `clock_nanosleep' function. */
-#undef HAVE_CLOCK_NANOSLEEP
-
-/* Defined if the compiler provides C++11 <atomic> header and increment,
-   decrement operations. */
-#undef HAVE_CXX11_ATOMICS
+/* define if the compiler supports basic C++11 syntax */
+#undef HAVE_CXX11
 
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #undef HAVE_DLFCN_H
@@ -55,9 +35,6 @@
 /* Define to 1 if you have the `getpid' function. */
 #undef HAVE_GETPID
 
-/* Define to 1 if you have the `gettimeofday' function. */
-#undef HAVE_GETTIMEOFDAY
-
 /* Define to 1 if you have the `gmtime_r' function. */
 #undef HAVE_GMTIME_R
 
@@ -115,9 +92,6 @@
 /* Define to 1 if you have the <memory.h> header file. */
 #undef HAVE_MEMORY_H
 
-/* Define to 1 if you have the `nanosleep' function. */
-#undef HAVE_NANOSLEEP
-
 /* Define to 1 if you have the `ntohl' function. */
 #undef HAVE_NTOHL
 
@@ -212,12 +186,6 @@
 /* Define to 1 if you have the `_vsnwprintf_s' function. */
 #undef HAVE__VSNWPRINTF_S
 
-/* Defined if the compiler provides __atomic_add_fetch(). */
-#undef HAVE___ATOMIC_ADD_FETCH
-
-/* Defined if the compiler provides __atomic_sub_fetch(). */
-#undef HAVE___ATOMIC_SUB_FETCH
-
 /* Defined if the compiler supports __FUNCTION__ macro. */
 #undef HAVE___FUNCTION___MACRO
 
@@ -227,12 +195,6 @@
 /* Defined if the compiler supports __PRETTY_FUNCTION__ macro. */
 #undef HAVE___PRETTY_FUNCTION___MACRO
 
-/* Defined if the compiler provides __sync_add_and_fetch(). */
-#undef HAVE___SYNC_ADD_AND_FETCH
-
-/* Defined if the compiler provides __sync_sub_and_fetch(). */
-#undef HAVE___SYNC_SUB_AND_FETCH
-
 /* Defined for --enable-debugging builds. */
 #undef LOG4CPLUS_DEBUGGING
 
@@ -251,27 +213,6 @@
 /* */
 #undef LOG4CPLUS_HAVE_ARPA_INET_H
 
-/* */
-#undef LOG4CPLUS_HAVE_ATOMIC_DEC_UINT_NV
-
-/* */
-#undef LOG4CPLUS_HAVE_ATOMIC_H
-
-/* */
-#undef LOG4CPLUS_HAVE_ATOMIC_INC_UINT
-
-/* */
-#undef LOG4CPLUS_HAVE_C99_VARIADIC_MACROS
-
-/* */
-#undef LOG4CPLUS_HAVE_CLOCK_GETTIME
-
-/* */
-#undef LOG4CPLUS_HAVE_CLOCK_NANOSLEEP
-
-/* */
-#undef LOG4CPLUS_HAVE_CXX11_ATOMICS
-
 /* */
 #undef LOG4CPLUS_HAVE_ENAMETOOLONG
 
@@ -314,15 +255,9 @@
 /* */
 #undef LOG4CPLUS_HAVE_GETTID
 
-/* */
-#undef LOG4CPLUS_HAVE_GETTIMEOFDAY
-
 /* */
 #undef LOG4CPLUS_HAVE_GMTIME_R
 
-/* */
-#undef LOG4CPLUS_HAVE_GNU_VARIADIC_MACROS
-
 /* */
 #undef LOG4CPLUS_HAVE_HTONL
 
@@ -356,9 +291,6 @@
 /* */
 #undef LOG4CPLUS_HAVE_MBSTOWCS
 
-/* */
-#undef LOG4CPLUS_HAVE_NANOSLEEP
-
 /* */
 #undef LOG4CPLUS_HAVE_NETDB_H
 
@@ -479,18 +411,6 @@
 /* */
 #undef LOG4CPLUS_HAVE__VSNWPRINTF_S
 
-/* */
-#undef LOG4CPLUS_HAVE___ATOMIC_ADD_FETCH
-
-/* */
-#undef LOG4CPLUS_HAVE___ATOMIC_SUB_FETCH
-
-/* */
-#undef LOG4CPLUS_HAVE___SYNC_ADD_AND_FETCH
-
-/* */
-#undef LOG4CPLUS_HAVE___SYNC_SUB_AND_FETCH
-
 /* Define if this is a single-threaded library. */
 #undef LOG4CPLUS_SINGLE_THREADED
 
@@ -500,13 +420,12 @@
 /* */
 #undef LOG4CPLUS_USE_PTHREADS
 
-/* Define so that log4cplus will use C++11 threads and synchronization
-   primitives. */
-#undef LOG4CPLUS_WITH_CXX11_THREADS
-
 /* Define when iconv() is available. */
 #undef LOG4CPLUS_WITH_ICONV
 
+/* Defined to enable unit tests. */
+#undef LOG4CPLUS_WITH_UNIT_TESTS
+
 /* Define for C99 compilers/standard libraries that support more than just the
    "C" locale. */
 #undef LOG4CPLUS_WORKING_C_LOCALE
@@ -515,8 +434,7 @@
    locale. */
 #undef LOG4CPLUS_WORKING_LOCALE
 
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
-   */
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
 #undef LT_OBJDIR
 
 /* Define to the address where bug reports for this package should be sent. */

+ 40 - 21
include/log4cplus/config.hxx

@@ -1,4 +1,4 @@
-//  Copyright (C) 2009-2015, Vaclav Haisman. All rights reserved.
+//  Copyright (C) 2009-2017, Vaclav Haisman. All rights reserved.
 //
 //  Redistribution and use in source and binary forms, with or without modifica-
 //  tion, are permitted provided that the following conditions are met:
@@ -32,14 +32,6 @@
 #  include <log4cplus/config/defines.hxx>
 #endif
 
-#if ! defined (UNICODE) && ! defined (LOG4CPLUS_HAVE_VSNPRINTF_S) \
-    && ! defined (LOG4CPLUS_HAVE__VSNPRINTF_S) \
-    && ! defined (LOG4CPLUS_HAVE_VSNPRINTF) \
-    && ! defined (LOG4CPLUS_HAVE__VSNPRINTF)
-#  undef LOG4CPLUS_USE_POOR_MANS_SNPRINTF
-#  define LOG4CPLUS_USE_POOR_MANS_SNPRINTF
-#endif
-
 # if ! defined (LOG4CPLUS_WORKING_LOCALE) \
   && ! defined (LOG4CPLUS_WORKING_C_LOCALE) \
   && ! defined (LOG4CPLUS_WITH_ICONV)
@@ -98,15 +90,16 @@
 #  define __has_feature(X) 0
 #endif
 
-#if (defined (_MSC_VER) && _MSC_VER >= 1600) \
-    || defined (__GXX_EXPERIMENTAL_CXX0X__) \
-    || __cplusplus >= 201103L
-#  define LOG4CPLUS_HAVE_CXX11_SUPPORT
-#endif
-
-#if defined (LOG4CPLUS_HAVE_CXX11_SUPPORT) \
-    || __has_feature (cxx_rvalue_references)
-#  define LOG4CPLUS_HAVE_RVALUE_REFS
+#if __has_feature (cxx_noexcept)                       \
+    || (defined (__GNUC__)                             \
+        && (__GNUC__ > 4                               \
+            || __GNUC__ == 4 && __GNUC_MINOR__ >= 6))  \
+    || (defined (_MSC_VER) && _MSC_VER >= 1900)
+#  define LOG4CPLUS_NOEXCEPT noexcept
+#  define LOG4CPLUS_NOEXCEPT_FALSE noexcept(false)
+#else
+#  define LOG4CPLUS_NOEXCEPT /* empty */
+#  define LOG4CPLUS_NOEXCEPT_FALSE /* empty */
 #endif
 
 #if ! defined (UNICODE) && defined (__GNUC__) && __GNUC__ >= 3
@@ -118,14 +111,16 @@
 #endif
 
 #if defined (__GNUC__) \
-    && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
+    && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) \
+    && ! defined (__INTEL_COMPILER) \
+    && ! defined (__CUDACC__)
 #  define LOG4CPLUS_CALLER_FILE() __builtin_FILE ()
 #  define LOG4CPLUS_CALLER_LINE() __builtin_LINE ()
 #  define LOG4CPLUS_CALLER_FUNCTION() __builtin_FUNCTION ()
 #else
-#  define LOG4CPLUS_CALLER_FILE() (NULL)
+#  define LOG4CPLUS_CALLER_FILE() (nullptr)
 #  define LOG4CPLUS_CALLER_LINE() (-1)
-#  define LOG4CPLUS_CALLER_FUNCTION() (NULL)
+#  define LOG4CPLUS_CALLER_FUNCTION() (nullptr)
 #endif
 
 #if defined (__GNUC__) && __GNUC__ >= 3
@@ -177,7 +172,15 @@
 
 #include <log4cplus/helpers/thread-config.h>
 
+#if defined (LOG4CPLUS_SINGLE_THREADED)
+#define LOG4CPLUS_THREADED(x)
+#else
+#define LOG4CPLUS_THREADED(x) x
+#endif
+
 #if defined(__cplusplus)
+#include <cstddef>
+
 namespace log4cplus
 {
 
@@ -189,8 +192,24 @@ namespace log4cplus
 LOG4CPLUS_EXPORT void threadCleanup ();
 
 //! Initializes log4cplus.
+//!
+//! \note using `log4cplus::Initializer` is preferred
 LOG4CPLUS_EXPORT void initialize ();
 
+//! Deinitializes log4cplus.
+//!
+//! \note using `log4cplus::Initializer` is preferred
+LOG4CPLUS_EXPORT void deinitialize ();
+
+//! Set thread pool size.
+LOG4CPLUS_EXPORT void setThreadPoolSize (std::size_t pool_size);
+
+//! Set behaviour on full thread pool queue. Default is to block.
+LOG4CPLUS_EXPORT void setThreadPoolBlockOnFull (bool block);
+
+//! Set thread pool queue size limit.
+LOG4CPLUS_EXPORT void setThreadPoolQueueSizeLimit (std::size_t queue_size_limit);
+
 } // namespace log4cplus
 
 #endif

+ 3 - 47
include/log4cplus/config/defines.hxx → include/log4cplus/config/defines.hxx.in

@@ -7,9 +7,6 @@
 /* */
 #undef LOG4CPLUS_HAVE_ARPA_INET_H
 
-/* */
-#undef LOG4CPLUS_HAVE_ATOMIC_H
-
 /* */
 #undef LOG4CPLUS_HAVE_NETINET_IN_H
 
@@ -82,18 +79,6 @@
 /* */
 #undef LOG4CPLUS_HAVE_GETPID
 
-/* */
-#undef LOG4CPLUS_HAVE_GETTIMEOFDAY
-
-/* Define to 1 if you have the `clock_gettime' function. */
-#undef LOG4CPLUS_HAVE_CLOCK_GETTIME
-
-/* Define to 1 if you have the `nanosleep' function. */
-#undef LOG4CPLUS_HAVE_NANOSLEEP
-
-/* Define to 1 if you have the `clock_nanosleep' function. */
-#undef LOG4CPLUS_HAVE_CLOCK_NANOSLEEP
-
 /* */
 #undef LOG4CPLUS_HAVE_GMTIME_R
 
@@ -156,10 +141,6 @@
    "C" locale. */
 #undef LOG4CPLUS_WORKING_C_LOCALE
 
-/* Define so that log4cplus will use C++11 threads and synchronization
-   primitives. */
-#undef LOG4CPLUS_WITH_CXX11_THREADS
-
 /* Define to int if undefined. */
 #undef socklen_t
 
@@ -187,34 +168,6 @@
 /* Defined if the host OS provides ENAMETOOLONG errno value. */
 #undef LOG4CPLUS_HAVE_ENAMETOOLONG
 
-/* Defined if the compiler provides __sync_add_and_fetch(). */
-#undef LOG4CPLUS_HAVE___SYNC_ADD_AND_FETCH
-
-/* Defined if the compiler provides __sync_sub_and_fetch(). */
-#undef LOG4CPLUS_HAVE___SYNC_SUB_AND_FETCH
-
-/* Defined if the compiler provides __atomic_add_fetch(). */
-#undef LOG4CPLUS_HAVE___ATOMIC_ADD_FETCH
-
-/* Defined if the compiler provides __atomic_sub_fetch(). */
-#undef LOG4CPLUS_HAVE___ATOMIC_SUB_FETCH
-
-/* Defined if atomic_inc_uint() is available. */
-#undef LOG4CPLUS_HAVE_ATOMIC_INC_UINT
-
-/* Defined if atomic_dec_uint_nv() is available.  */
-#undef LOG4CPLUS_HAVE_ATOMIC_DEC_UINT_NV
-
-/* Defined if the compiler provides C++11 <atomic> header and increment,
-   decrement operations. */
-#undef LOG4CPLUS_HAVE_CXX11_ATOMICS
-
-/* */
-#undef LOG4CPLUS_HAVE_C99_VARIADIC_MACROS
-
-/* */
-#undef LOG4CPLUS_HAVE_GNU_VARIADIC_MACROS
-
 /* */
 #undef LOG4CPLUS_HAVE_VSNPRINTF
 
@@ -288,4 +241,7 @@
 /* Define to 1 if the system has the `init_priority' variable attribute */
 #undef LOG4CPLUS_HAVE_VAR_ATTRIBUTE_INIT_PRIORITY
 
+/* Defined to enable unit tests. */
+#undef LOG4CPLUS_WITH_UNIT_TESTS
+
 #endif // LOG4CPLUS_CONFIG_DEFINES_HXX

+ 1 - 1
include/log4cplus/config/macosx.h

@@ -5,7 +5,7 @@
 // Author:  Christopher R. Bailey
 //
 //
-// Copyright 2003-2015 Christopher R. Bailey
+// Copyright 2003-2017 Christopher R. Bailey
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.

+ 8 - 28
include/log4cplus/config/win32.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2003-2015 Tad E. Smith
+// Copyright 2003-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -43,7 +43,7 @@
 #define LOG4CPLUS_HAVE_TIME_H
 #define LOG4CPLUS_HAVE_SYS_TIMEB_H
 #define LOG4CPLUS_HAVE_FTIME
-#if defined (_MSC_VER) || defined (__BORLANDC__) 
+#if defined (_MSC_VER) || defined (__BORLANDC__)
 #define LOG4CPLUS_HAVE_GMTIME_S
 #endif
 
@@ -104,6 +104,10 @@
 #  define LOG4CPLUS_HAVE__VSWPRINTF_P
 #endif
 
+#if defined (_MSC_VER)
+#  define LOG4CPLUS_HAVE_LOCALTIME_S
+#endif
+
 #define LOG4CPLUS_HAVE__TSOPEN
 
 #define LOG4CPLUS_DLLMAIN_HINSTANCE HINSTANCE
@@ -112,7 +116,7 @@
 // log4cplus_EXPORTS is used by the CMake build system.  DLL_EXPORT is
 // used by the autotools build system.
 #if (defined (log4cplus_EXPORTS) || defined (log4cplusU_EXPORTS) \
-     || defined (DLL_EXPORT))                                    \
+    || (defined (DLL_EXPORT) && defined (INSIDE_LOG4CPLUS)))     \
     && ! defined (LOG4CPLUS_STATIC)
 #  undef LOG4CPLUS_BUILD_DLL
 #  define LOG4CPLUS_BUILD_DLL
@@ -141,10 +145,6 @@
 #  define LOG4CPLUS_USE_WIN32_THREADS
 #endif
 
-#if defined (_WIN32_WINNT) && _WIN32_WINNT < 0x0600
-#  define LOG4CPLUS_POOR_MANS_SHAREDMUTEX
-#endif
-
 #if defined(_MSC_VER)
   // Warning about: identifier was truncated to '255' characters in the debug information
 #  pragma warning( disable : 4786 )
@@ -157,13 +157,8 @@
 #    define LOG4CPLUS_WORKING_LOCALE
 #    define LOG4CPLUS_HAVE_FUNCTION_MACRO
 #    define LOG4CPLUS_HAVE_FUNCSIG_MACRO
-#    define LOG4CPLUS_HAVE_C99_VARIADIC_MACROS
 #    define LOG4CPLUS_ATTRIBUTE_NORETURN __declspec(noreturn)
 #  endif
-#  if _MSC_VER >= 1700
-#    define LOG4CPLUS_HAVE_CXX11_ATOMICS
-#    define LOG4CPLUS_WITH_CXX11_THREADS
-#  endif
 #endif
 
 #if defined (__GNUC__)
@@ -172,26 +167,12 @@
 #    define LOG4CPLUS_HAVE_PRETTY_FUNCTION_MACRO
 #    define LOG4CPLUS_HAVE_FUNC_SYMBOL
 #  endif
-#  if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
-#    if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
-#      define LOG4CPLUS_HAVE___SYNC_SUB_AND_FETCH
-#      define LOG4CPLUS_HAVE___SYNC_ADD_AND_FETCH
-#    endif
-#  endif
-#  if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
-#    if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
-#      define LOG4CPLUS_HAVE___ATOMIC_ADD_FETCH
-#      define LOG4CPLUS_HAVE___ATOMIC_SUB_FETCH
-#    endif
 // This has worked for some versions of MinGW with GCC 4.7+ but it
 // appears to be broken again in 4.8.x. Thus, we disable this for GCC
 // completely forever.
 //
-//#    define LOG4CPLUS_INLINES_ARE_EXPORTED
-#  endif
+//#  define LOG4CPLUS_INLINES_ARE_EXPORTED
 #  define LOG4CPLUS_HAVE_FUNCTION_MACRO
-#  define LOG4CPLUS_HAVE_GNU_VARIADIC_MACROS
-#  define LOG4CPLUS_HAVE_C99_VARIADIC_MACROS
 #  if defined (__MINGW32__)
 #    define LOG4CPLUS_WORKING_C_LOCALE
 #  endif
@@ -199,7 +180,6 @@
 
 #if defined (__BORLANDC__) && __BORLANDC__ >= 0x0650
 #  define LOG4CPLUS_HAVE_FUNCTION_MACRO
-#  define LOG4CPLUS_HAVE_C99_VARIADIC_MACROS
 #endif // __BORLANDC__
 
 #if ! defined (LOG4CPLUS_DISABLE_DLL_RUNTIME_WARNING)

+ 42 - 0
include/log4cplus/config/windowsh-inc-full.h

@@ -0,0 +1,42 @@
+// -*- C++ -*-
+// Module:  Log4CPLUS
+// File:    windowsh-inc.h
+// Created: 9/2018
+// Author:  Vaclav Haisman
+//
+//
+//  Copyright (C) 2018, Vaclav Haisman. All rights reserved.
+//
+//  Redistribution and use in source and binary forms, with or without modifica-
+//  tion, are permitted provided that the following conditions are met:
+//
+//  1. Redistributions of  source code must  retain the above copyright  notice,
+//     this list of conditions and the following disclaimer.
+//
+//  2. Redistributions in binary form must reproduce the above copyright notice,
+//     this list of conditions and the following disclaimer in the documentation
+//     and/or other materials provided with the distribution.
+//
+//  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+//  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+//  FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
+//  APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
+//  INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
+//  DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
+//  OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
+//  ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
+//  (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
+//  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// NOTE: This file is a fragment intentionally left without include guards.
+
+#if defined (_WIN32)
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <windows.h>
+#if defined (LOG4CPLUS_HAVE_INTRIN_H)
+#include <intrin.h>
+#endif
+#endif
+
+// NOTE: This file is a fragment intentionally left without include guards.

+ 1 - 1
include/log4cplus/config/windowsh-inc.h

@@ -5,7 +5,7 @@
 // Author:  Vaclav Zeman
 //
 //
-//  Copyright (C) 2010-2015, Vaclav Zeman. All rights reserved.
+//  Copyright (C) 2010-2017, Vaclav Zeman. All rights reserved.
 //
 //  Redistribution and use in source and binary forms, with or without modifica-
 //  tion, are permitted provided that the following conditions are met:

+ 17 - 1
include/log4cplus/configurator.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2003-2015 Tad E. Smith
+// Copyright 2003-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -90,6 +90,7 @@ namespace log4cplus
 #if defined (LOG4CPLUS_HAVE_CODECVT_UTF32_FACET) && defined (UNICODE)
             , fUTF32              = (3 << fEncodingShift)
 #endif
+            , fThrow              = (1 << 5)
         };
 
         // ctor and dtor
@@ -197,6 +198,21 @@ namespace log4cplus
          * "log4cplus.disableOverride" to <code>true</code> or any value other
          * than false. As in <pre>log4cplus.disableOverride=true </pre>
          *
+         * <h3>Global configuration</h3>
+         *
+         * <ul>
+         * <li>Property <pre>log4cplus.threadPoolSize</pre> can be used to adjust
+         * size of log4cplus' internal thread pool.</li>
+         * <li>Property <pre>log4cplus.threadPoolBlockOnFull</pre> can be
+         * used to change behaviour of the thread pool when its queue is full.
+         * The default value is <pre>true</pre>, to block the thread until
+         * there is a space in the queue. Setting this property to
+         * <pre>false</pre> makes the thread pool not to block when it is full.
+         * The items that could not be inserted are dropped instead.</li>
+         * <li>Property <pre>log4cplus.threadPoolQueueSizeLimit</pre> can be used to
+         * set thread pool queue size limit.</li>
+         * </ul>
+         *
          * <h3>Example</h3>
          *
          * An example configuration is given below.

+ 21 - 1
include/log4cplus/consoleappender.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2001-2015 Tad E. Smith
+// Copyright 2001-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -31,6 +31,7 @@
 #endif
 
 #include <log4cplus/appender.h>
+#include <locale>
 
 namespace log4cplus {
     /**
@@ -48,6 +49,23 @@ namespace log4cplus {
      * <dd>When it is set true, output stream will be flushed after
      * each appended event.</dd>
      * 
+     * <dt><tt>Locale</tt></dt>
+     * <dd>This property specifies a locale name that will be imbued
+     * into output stream. Locale can be specified either by system
+     * specific locale name, e.g., <tt>en_US.UTF-8</tt>, or by one of
+     * four recognized keywords: <tt>GLOBAL</tt>, <tt>DEFAULT</tt>
+     * (which is an alias for <tt>GLOBAL</tt>), <tt>USER</tt> and
+     * <tt>CLASSIC</tt>. When specified locale is not available,
+     * <tt>GLOBAL</tt> is used instead. It is possible to register
+     * additional locale keywords by registering an instance of
+     * <code>spi::LocaleFactory</code> in
+     * <code>spi::LocaleFactoryRegistry</code>.
+     * \sa spi::getLocaleFactoryRegistry().
+     * 
+     * Note: if <tt>Locale</tt> is set, <tt>ImmediateFlush</tt> will
+     * be set to true automatically.
+     * </dd>
+     * 
      * </dl>
      * \sa Appender
      */
@@ -77,6 +95,8 @@ namespace log4cplus {
          * will be flushed at the end of each append operation.
          */
         bool immediateFlush;
+
+        std::unique_ptr<std::locale> locale;
     };
 
 } // end namespace log4cplus

+ 56 - 0
include/log4cplus/exception.h

@@ -0,0 +1,56 @@
+//  Copyright (C) 2023, Vaclav Haisman. All rights reserved.
+//
+//  Redistribution and use in source and binary forms, with or without modifica-
+//  tion, are permitted provided that the following conditions are met:
+//
+//  1. Redistributions of  source code must  retain the above copyright  notice,
+//     this list of conditions and the following disclaimer.
+//
+//  2. Redistributions in binary form must reproduce the above copyright notice,
+//     this list of conditions and the following disclaimer in the documentation
+//     and/or other materials provided with the distribution.
+//
+//  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+//  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+//  FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
+//  APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
+//  INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
+//  DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
+//  OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
+//  ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
+//  (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
+//  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef LOG4CPLUS_EXCEPTION_HXX
+#define LOG4CPLUS_EXCEPTION_HXX
+
+#include <log4cplus/config.hxx>
+
+#if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
+#pragma once
+#endif
+
+#include <log4cplus/tstring.h>
+#include <stdexcept>
+
+
+namespace log4cplus
+{
+
+/**
+ * \brief Exception class thrown by LogLog.
+ * \sa helpers::LogLog
+ *
+ */
+class LOG4CPLUS_EXPORT exception : public std::runtime_error
+{
+public:
+    exception (tstring const &);
+    exception (exception const &);
+    exception & operator=(exception const &);
+    virtual ~exception ();
+};
+
+} // namespace log4cplus
+
+#endif // LOG4CPLUS_EXCEPTION_HXX

+ 11 - 5
include/log4cplus/fileappender.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2001-2015 Tad E. Smith
+// Copyright 2001-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -106,6 +106,12 @@ namespace log4cplus
      * <dd>Set this property to <tt>true</tt> if you want to create
      * missing directories in path leading to log file and lock file.
      * </dd>
+     *
+     * <dt><tt>TextMode</tt></dt>
+     * <dd>Set this property to <tt>Binary</tt> if the underlying stream should
+     * not translate EOLs to OS specific character sequence. The default value
+     * is <tt>Text</tt> and the underlying stream will be opened in text
+     * mode.</dd>
      * </dl>
      */
     class LOG4CPLUS_EXPORT FileAppenderBase : public Appender {
@@ -169,7 +175,7 @@ namespace log4cplus
         int reopenDelay;
 
         unsigned long bufferSize;
-        log4cplus::tchar * buffer;
+        std::unique_ptr<log4cplus::tchar[]> buffer;
 
         log4cplus::tofstream out;
         log4cplus::tstring filename;
@@ -397,7 +403,7 @@ namespace log4cplus
         void close();
         void rollover(bool alreadyLocked = false);
         void clean(helpers::Time time);
-        int getRolloverPeriodDuration() const;
+        helpers::Time::duration getRolloverPeriodDuration() const;
         helpers::Time calculateNextRolloverTime(const helpers::Time& t) const;
 
       // Data
@@ -406,8 +412,8 @@ namespace log4cplus
         tstring scheduledFilename;
         int maxHistory;
         bool cleanHistoryOnStart;
-        helpers::Time lastHeartBeat;
-        helpers::Time nextRolloverTime;
+        log4cplus::helpers::Time lastHeartBeat;
+        log4cplus::helpers::Time nextRolloverTime;
         bool rollOnClose;
 
     private:

+ 1 - 1
include/log4cplus/fstreams.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2003-2015 Tad E. Smith
+// Copyright 2003-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.

+ 1 - 1
include/log4cplus/helpers/appenderattachableimpl.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2001-2015 Tad E. Smith
+// Copyright 2001-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.

+ 1 - 1
include/log4cplus/helpers/connectorthread.h

@@ -1,5 +1,5 @@
 // -*- C++ -*-
-//  Copyright (C) 2013-2015, Vaclav Zeman. All rights reserved.
+//  Copyright (C) 2013-2017, Vaclav Zeman. All rights reserved.
 //  
 //  Redistribution and use in source and binary forms, with or without modifica-
 //  tion, are permitted provided that the following conditions are met:

+ 91 - 0
include/log4cplus/helpers/eventcounter.h

@@ -0,0 +1,91 @@
+// -*- C++ -*-
+//
+//  Copyright (C) 2024, Vaclav Haisman. All rights reserved.
+//
+//  Redistribution and use in source and binary forms, with or without modifica-
+//  tion, are permitted provided that the following conditions are met:
+//
+//  1. Redistributions of  source code must  retain the above copyright  notice,
+//     this list of conditions and the following disclaimer.
+//
+//  2. Redistributions in binary form must reproduce the above copyright notice,
+//     this list of conditions and the following disclaimer in the documentation
+//     and/or other materials provided with the distribution.
+//
+//  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+//  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+//  FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
+//  APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
+//  INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
+//  DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
+//  OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
+//  ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
+//  (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
+//  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef LOG4CPLUS_HELPERS_EVENTCOUNTER_H
+#define LOG4CPLUS_HELPERS_EVENTCOUNTER_H
+
+#include <log4cplus/config.hxx>
+
+#if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
+#pragma once
+#endif
+
+#include <log4cplus/thread/syncprims.h>
+#include <cstddef>
+#include <atomic>
+#include <chrono>
+
+
+namespace log4cplus {
+
+namespace helpers {
+
+class LOG4CPLUS_EXPORT BaseEventCounter
+{
+public:
+    BaseEventCounter ();
+    virtual ~BaseEventCounter ();
+
+    virtual std::size_t record_event ();
+
+protected:
+    std::atomic<std::size_t> event_count {0};
+};
+
+
+class LOG4CPLUS_EXPORT SteadyClockGate
+    : public BaseEventCounter
+{
+public:
+    using Clock = std::chrono::steady_clock;
+    using Duration = Clock::duration;
+    using TimePoint = std::chrono::time_point<Clock>;
+
+    struct LOG4CPLUS_EXPORT Info
+    {
+        ~Info ();
+
+        std::size_t count;
+        Duration time_span;
+    };
+
+    SteadyClockGate (SteadyClockGate::Duration pause_duraiton);
+    virtual ~SteadyClockGate ();
+
+    bool latch_open (Info &);
+
+private:
+    log4cplus::thread::SimpleMutex mtx;
+    Duration const pause_duration;
+    TimePoint timeout_point;
+    TimePoint prev_timeout_point;
+};
+
+
+} // namespace helpers
+
+} // namespace log4cplus
+
+#endif // LOG4CPLUS_HELPERS_EVENTCOUNTER_H

+ 1 - 1
include/log4cplus/helpers/fileinfo.h

@@ -1,6 +1,6 @@
 // -*- C++ -*-
 //
-//  Copyright (C) 2012-2015, Vaclav Zeman. All rights reserved.
+//  Copyright (C) 2012-2017, Vaclav Zeman. All rights reserved.
 //
 //  Redistribution and use in source and binary forms, with or without modifica-
 //  tion, are permitted provided that the following conditions are met:

+ 1 - 1
include/log4cplus/helpers/lockfile.h

@@ -1,6 +1,6 @@
 // -*- C++ -*-
 //
-//  Copyright (C) 2012-2015, Vaclav Zeman. All rights reserved.
+//  Copyright (C) 2012-2017, Vaclav Zeman. All rights reserved.
 //
 //  Redistribution and use in source and binary forms, with or without modifica-
 //  tion, are permitted provided that the following conditions are met:

+ 1 - 1
include/log4cplus/helpers/loglog.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2001-2015 Tad E. Smith
+// Copyright 2001-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.

+ 0 - 64
include/log4cplus/helpers/logloguser.h

@@ -1,64 +0,0 @@
-// -*- C++ -*-
-// Module:  Log4CPLUS
-// File:    logloguser.h
-// Created: 6/2003
-// Author:  Tad E. Smith
-//
-//
-// Copyright 2003-2015 Tad E. Smith
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/** @file */
-
-#ifndef LOG4CPLUS_HELPERS_LOGLOG_USER
-#define LOG4CPLUS_HELPERS_LOGLOG_USER
-
-#include <log4cplus/config.hxx>
-
-#if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
-#pragma once
-#endif
-
-
-namespace log4cplus {
-    namespace helpers {
-        // forward declarations
-        class LogLog;
-
-        /**
-         * This class used to simplify the use of the LogLog class.  Any class
-         * that uses the LogLog class should extend this class and retrieve
-         * their reference to LogLog using the method provided.
-         */
-        class LOG4CPLUS_EXPORT LogLogUser
-        {
-        public:
-          // ctor and dtor
-            LogLogUser();
-            LogLogUser(const LogLogUser&);
-            virtual ~LogLogUser();
-
-          // public methods
-            LogLog& getLogLog() const;
-            
-          // operators
-            LogLogUser& operator=(const LogLogUser& rhs);
-        };
-
-    } // end namespace helpers
-} // end namespace log4cplus
-
-
-#endif // LOG4CPLUS_HELPERS_LOGLOG_USER
-

+ 24 - 23
include/log4cplus/helpers/pointer.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2001-2015 Tad E. Smith
+// Copyright 2001-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -38,8 +38,7 @@
 #include <log4cplus/thread/syncprims.h>
 #include <algorithm>
 #include <cassert>
-#if ! defined (LOG4CPLUS_SINGLE_THREADED) \
-    && defined (LOG4CPLUS_HAVE_CXX11_ATOMICS)
+#if ! defined (LOG4CPLUS_SINGLE_THREADED)
 #include <atomic>
 #endif
 
@@ -54,26 +53,32 @@ namespace log4cplus {
         class LOG4CPLUS_EXPORT SharedObject
         {
         public:
-            void addReference() const;
+            void addReference() const LOG4CPLUS_NOEXCEPT;
             void removeReference() const;
 
         protected:
           // Ctor
             SharedObject()
                 : access_mutex()
-                , count(0)
+                , count__(0)
             { }
 
             SharedObject(const SharedObject&)
                 : access_mutex()
-                , count(0)
+                , count__(0)
+            { }
+
+            SharedObject(SharedObject &&)
+                : access_mutex()
+                , count__(0)
             { }
 
           // Dtor
             virtual ~SharedObject();
 
           // Operators
-            SharedObject& operator=(const SharedObject&) { return *this; }
+            SharedObject& operator=(const SharedObject&) LOG4CPLUS_NOEXCEPT { return *this; }
+            SharedObject& operator=(SharedObject &&) LOG4CPLUS_NOEXCEPT { return *this; }
 
         public:
             thread::Mutex access_mutex;
@@ -81,14 +86,10 @@ namespace log4cplus {
         private:
 #if defined (LOG4CPLUS_SINGLE_THREADED)
             typedef unsigned count_type;
-#elif defined (LOG4CPLUS_HAVE_CXX11_ATOMICS)
-            typedef std::atomic<unsigned> count_type;
-#elif defined (_WIN32) || defined (__CYGWIN__)
-            typedef long count_type;
 #else
-            typedef unsigned count_type;
+            typedef std::atomic<unsigned> count_type;
 #endif
-            mutable count_type count;
+            mutable count_type count__;
         };
 
 
@@ -101,31 +102,29 @@ namespace log4cplus {
         public:
             // Ctor
             explicit
-            SharedObjectPtr(T* realPtr = 0)
+            SharedObjectPtr(T* realPtr = 0) LOG4CPLUS_NOEXCEPT
                 : pointee(realPtr)
             {
                 addref ();
             }
 
-            SharedObjectPtr(const SharedObjectPtr& rhs)
+            SharedObjectPtr(const SharedObjectPtr& rhs) LOG4CPLUS_NOEXCEPT
                 : pointee(rhs.pointee)
             {
                 addref ();
             }
 
-#if defined (LOG4CPLUS_HAVE_RVALUE_REFS)
-            SharedObjectPtr(SharedObjectPtr && rhs)
+            SharedObjectPtr(SharedObjectPtr && rhs) LOG4CPLUS_NOEXCEPT
                 : pointee (std::move (rhs.pointee))
             {
                 rhs.pointee = 0;
             }
 
-            SharedObjectPtr & operator = (SharedObjectPtr && rhs)
+            SharedObjectPtr & operator = (SharedObjectPtr && rhs) LOG4CPLUS_NOEXCEPT
             {
                 rhs.swap (*this);
                 return *this;
             }
-#endif
 
             // Dtor
             ~SharedObjectPtr()
@@ -135,8 +134,10 @@ namespace log4cplus {
             }
 
             // Operators
-            bool operator==(const SharedObjectPtr& rhs) const { return (pointee == rhs.pointee); }
-            bool operator!=(const SharedObjectPtr& rhs) const { return (pointee != rhs.pointee); }
+            bool operator==(const SharedObjectPtr& rhs) const
+            { return (pointee == rhs.pointee); }
+            bool operator!=(const SharedObjectPtr& rhs) const
+            { return (pointee != rhs.pointee); }
             bool operator==(const T* rhs) const { return (pointee == rhs); }
             bool operator!=(const T* rhs) const { return (pointee != rhs); }
             T* operator->() const {assert (pointee); return pointee; }
@@ -156,7 +157,7 @@ namespace log4cplus {
           // Methods
             T* get() const { return pointee; }
 
-            void swap (SharedObjectPtr & other) throw ()
+            void swap (SharedObjectPtr & other) LOG4CPLUS_NOEXCEPT
             {
                 std::swap (pointee, other.pointee);
             }
@@ -174,7 +175,7 @@ namespace log4cplus {
 
         private:
           // Methods
-            void addref() const
+            void addref() const LOG4CPLUS_NOEXCEPT
             {
                 if (pointee)
                     pointee->addReference();

+ 11 - 1
include/log4cplus/helpers/property.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2002-2015 Tad E. Smith
+// Copyright 2002-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -61,6 +61,7 @@ namespace log4cplus {
 #if defined (LOG4CPLUS_HAVE_CODECVT_UTF32_FACET) && defined (UNICODE)
                 , fUTF32            = (3 << fEncodingShift)
 #endif
+                , fThrow            = (1 << 5)
             };
 
             Properties();
@@ -154,6 +155,15 @@ namespace log4cplus {
             bool get_type_val_worker (ValType & val,
                 log4cplus::tstring const & key) const;
         };
+
+
+        class LogLog;
+
+
+        bool
+        substVars (tstring & dest, const tstring & val,
+            Properties const & props, LogLog& loglog,
+            unsigned flags);
     } // end namespace helpers
 
 }

+ 7 - 7
include/log4cplus/helpers/queue.h

@@ -1,16 +1,16 @@
 // -*- C++ -*-
-//  Copyright (C) 2009-2015, Vaclav Haisman. All rights reserved.
-//  
+//  Copyright (C) 2009-2017, Vaclav Haisman. All rights reserved.
+//
 //  Redistribution and use in source and binary forms, with or without modifica-
 //  tion, are permitted provided that the following conditions are met:
-//  
+//
 //  1. Redistributions of  source code must  retain the above copyright  notice,
 //     this list of conditions and the following disclaimer.
-//  
+//
 //  2. Redistributions in binary form must reproduce the above copyright notice,
 //     this list of conditions and the following disclaimer in the documentation
 //     and/or other materials provided with the distribution.
-//  
+//
 //  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 //  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 //  FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
@@ -53,7 +53,7 @@ public:
     //! Queue storage type.
     typedef std::deque<spi::InternalLoggingEvent> queue_storage_type;
 
-    Queue (unsigned len = 100);
+    explicit Queue (unsigned len = 100);
     virtual ~Queue ();
 
     // Producers' methods.
@@ -120,7 +120,7 @@ public:
         //! ERROR_BIT signals error.
         ERROR_BIT   = 0x0010,
 
-        //! ERROR_AFTER signals error that has occured after queue has
+        //! ERROR_AFTER signals error that has occurred after queue has
         //! already been touched.
         ERROR_AFTER = 0x0020
     };

+ 0 - 43
include/log4cplus/helpers/sleep.h

@@ -1,43 +0,0 @@
-// -*- C++ -*-
-// Module:  Log4CPLUS
-// File:    sleep.h
-// Created: 5/2003
-// Author:  Tad E. Smith
-//
-//
-// Copyright 2003-2015 Tad E. Smith
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/** @file */
-
-#ifndef LOG4CPLUS_HELPERS_SLEEP_HEADER_
-#define LOG4CPLUS_HELPERS_SLEEP_HEADER_
-
-#include <log4cplus/config.hxx>
-
-#if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
-#pragma once
-#endif
-
-
-namespace log4cplus {
-    namespace helpers {
-        LOG4CPLUS_EXPORT void sleep(unsigned long secs, 
-                                    unsigned long nanosecs = 0);
-        LOG4CPLUS_EXPORT void sleepmillis(unsigned long millis);
-    } // end namespace helpers
-} // end namespace log4cplus
-
-#endif // LOG4CPLUS_HELPERS_SLEEP_HEADER_
-

+ 1 - 1
include/log4cplus/helpers/snprintf.h

@@ -1,5 +1,5 @@
 // -*- C++ -*-
-//  Copyright (C) 2010-2015, Vaclav Zeman. All rights reserved.
+//  Copyright (C) 2010-2017, Vaclav Zeman. All rights reserved.
 //  
 //  Redistribution and use in source and binary forms, with or without modifica-
 //  tion, are permitted provided that the following conditions are met:

+ 38 - 16
include/log4cplus/helpers/socket.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2003-2015 Tad E. Smith
+// Copyright 2003-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -30,6 +30,8 @@
 #pragma once
 #endif
 
+#include <array>
+
 #include <log4cplus/tstring.h>
 #include <log4cplus/helpers/socketbuffer.h>
 
@@ -53,24 +55,21 @@ namespace log4cplus {
 
         class LOG4CPLUS_EXPORT AbstractSocket {
         public:
-          // ctor and dtor
             AbstractSocket();
             AbstractSocket(SOCKET_TYPE sock, SocketState state, int err);
-            AbstractSocket(const AbstractSocket&);
+            AbstractSocket(AbstractSocket const &) = delete;
+            AbstractSocket(AbstractSocket &&) LOG4CPLUS_NOEXCEPT;
             virtual ~AbstractSocket() = 0;
 
-          // methods
             /// Close socket
             virtual void close();
             virtual bool isOpen() const;
             virtual void shutdown();
-            AbstractSocket& operator=(const AbstractSocket& rhs);
+            AbstractSocket & operator = (AbstractSocket && rhs) LOG4CPLUS_NOEXCEPT;
 
-        protected:
-          // Methods
-            virtual void copy(const AbstractSocket& rhs);
+            void swap (AbstractSocket &);
 
-          // Data
+        protected:
             SOCKET_TYPE sock;
             SocketState state;
             int err;
@@ -87,13 +86,27 @@ namespace log4cplus {
           // ctor and dtor
             Socket();
             Socket(SOCKET_TYPE sock, SocketState state, int err);
-            Socket(const tstring& address, unsigned short port, bool udp = false);
+            Socket(const tstring& address, unsigned short port,
+                bool udp = false, bool ipv6 = false);
+            Socket(Socket &&) LOG4CPLUS_NOEXCEPT;
             virtual ~Socket();
 
+            Socket & operator = (Socket &&) LOG4CPLUS_NOEXCEPT;
+
           // methods
             virtual bool read(SocketBuffer& buffer);
             virtual bool write(const SocketBuffer& buffer);
             virtual bool write(const std::string & buffer);
+            virtual bool write(std::size_t bufferCount,
+                SocketBuffer const * const * buffers);
+
+            template <typename... Args>
+            static bool write(Socket & socket, Args &&... args)
+            {
+                SocketBuffer const * const buffers[sizeof... (args)] {
+                    (&args)... };
+                return socket.write (sizeof... (args), buffers);
+            }
         };
 
 
@@ -106,22 +119,29 @@ namespace log4cplus {
          */
         class LOG4CPLUS_EXPORT ServerSocket : public AbstractSocket {
         public:
-          // ctor and dtor
-            ServerSocket(unsigned short port);
+            ServerSocket(unsigned short port, bool udp = false,
+                bool ipv6 = false, tstring const & host = tstring ());
+            ServerSocket(ServerSocket &&) LOG4CPLUS_NOEXCEPT;
             virtual ~ServerSocket();
 
+            ServerSocket & operator = (ServerSocket &&) LOG4CPLUS_NOEXCEPT;
+
             Socket accept();
             void interruptAccept ();
+            void swap (ServerSocket &);
 
         protected:
-            std::ptrdiff_t interruptHandles[2];
+            std::array<std::ptrdiff_t, 2> interruptHandles;
         };
 
 
-        LOG4CPLUS_EXPORT SOCKET_TYPE openSocket(unsigned short port, SocketState& state);
+        LOG4CPLUS_EXPORT SOCKET_TYPE openSocket(unsigned short port, bool udp,
+            bool ipv6, SocketState& state);
+        LOG4CPLUS_EXPORT SOCKET_TYPE openSocket(tstring const & host,
+            unsigned short port, bool udp, bool ipv6, SocketState& state);
+
         LOG4CPLUS_EXPORT SOCKET_TYPE connectSocket(const log4cplus::tstring& hostn,
-                                                   unsigned short port, bool udp,
-                                                   SocketState& state);
+            unsigned short port, bool udp, bool ipv6, SocketState& state);
         LOG4CPLUS_EXPORT SOCKET_TYPE acceptSocket(SOCKET_TYPE sock, SocketState& state);
         LOG4CPLUS_EXPORT int closeSocket(SOCKET_TYPE sock);
         LOG4CPLUS_EXPORT int shutdownSocket(SOCKET_TYPE sock);
@@ -129,6 +149,8 @@ namespace log4cplus {
         LOG4CPLUS_EXPORT long read(SOCKET_TYPE sock, SocketBuffer& buffer);
         LOG4CPLUS_EXPORT long write(SOCKET_TYPE sock,
             const SocketBuffer& buffer);
+        LOG4CPLUS_EXPORT long write(SOCKET_TYPE sock, std::size_t bufferCount,
+            SocketBuffer const * const * buffers);
         LOG4CPLUS_EXPORT long write(SOCKET_TYPE sock,
             const std::string & buffer);
 

+ 1 - 1
include/log4cplus/helpers/socketbuffer.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2003-2015 Tad E. Smith
+// Copyright 2003-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.

+ 29 - 8
include/log4cplus/helpers/stringhelper.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2003-2015 Tad E. Smith
+// Copyright 2003-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -90,6 +90,8 @@ namespace log4cplus {
             }
             if (first != i)
                 *result = StringType (s, first, i - first);
+            else if (! collapseTokens && first == i)
+                *result = StringType ();
         }
 
 
@@ -127,7 +129,7 @@ namespace log4cplus {
                     value = -value;
             }
 
-            static inline
+            static
             bool
             is_negative (intType val)
             {
@@ -146,7 +148,7 @@ namespace log4cplus {
                 // This will never be called for unsigned types.
             }
 
-            static inline
+            static
             bool
             is_negative (intType)
             {
@@ -164,10 +166,8 @@ namespace log4cplus {
             typedef typename stringType::value_type charType;
             typedef ConvertIntegerToStringHelper<intType, charType,
                 intTypeLimits::is_signed> HelperType;
-            
+
             charType buffer[intTypeLimits::digits10 + 2];
-            // We define buffer_size from buffer using sizeof operator
-            // to apease HP aCC compiler.
             const std::size_t buffer_size
                 = sizeof (buffer) / sizeof (charType);
 
@@ -227,10 +227,11 @@ namespace log4cplus {
 
 
         //! Join a list of items into a string.
-        template <typename Iterator>
+        template <typename Iterator, typename Separator>
         inline
         void
-        join (tstring & result, Iterator start, Iterator last, tstring const & sep)
+        join_worker (tstring & result, Iterator & start, Iterator & last,
+            Separator const & sep)
         {
             if (start != last)
                 result = *start++;
@@ -242,6 +243,26 @@ namespace log4cplus {
             }
         }
 
+        //! Join a list of items into a string.
+        template <typename Iterator>
+        inline
+        void
+        join (tstring & result, Iterator start, Iterator last,
+            tstring const & sep)
+        {
+            join_worker (result, start, last, sep);
+        }
+
+        //! Join a list of items into a string.
+        template <typename Iterator>
+        inline
+        void
+        join (tstring & result, Iterator start, Iterator last,
+            tstring::value_type sep)
+        {
+            join_worker (result, start, last, sep);
+        }
+
 
     } // namespace helpers
 

+ 4 - 7
include/log4cplus/helpers/thread-config.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2003-2015 Tad E. Smith
+// Copyright 2003-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -33,14 +33,11 @@
 #   endif
 
 #elif defined(LOG4CPLUS_USE_WIN32_THREADS)
-#   if defined (_WIN32_WINNT) && _WIN32_WINNT >= 0x0600
-#     define LOG4CPLUS_USE_SRW_LOCK
-#   else
-#     define LOG4CPLUS_POOR_MANS_SHAREDMUTEX
-#   endif
+#   define LOG4CPLUS_USE_SRW_LOCK
+//#   define LOG4CPLUS_POOR_MANS_SHAREDMUTEX
 #   undef LOG4CPLUS_HAVE_TLS_SUPPORT
 #   undef LOG4CPLUS_THREAD_LOCAL_VAR
-#   if defined (_MSC_VER) && _WIN32_WINNT >= 0x0600
+#   if defined (_MSC_VER)
 // The __declspec(thread) functionality is not compatible with LoadLibrary().
 // For more information why see and "Windows and TLS" note in README.
 // <http://msdn.microsoft.com/en-us/library/2s9wt68x(v=vs.100).aspx>.

+ 111 - 121
include/log4cplus/helpers/timehelper.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2003-2015 Tad E. Smith
+// Copyright 2003-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -37,6 +37,7 @@
 #endif
 
 #include <ctime>
+#include <chrono>
 
 
 namespace log4cplus {
@@ -46,129 +47,119 @@ namespace helpers {
 
 using std::time_t;
 using std::tm;
+namespace chrono = std::chrono;
+
+typedef chrono::system_clock Clock;
+typedef chrono::duration<long long, std::micro> Duration;
+typedef chrono::time_point<Clock, Duration> Time;
+
+
+template <typename FromDuration>
+inline
+Time
+time_cast (chrono::time_point<Clock, FromDuration> const & tp)
+{
+    return chrono::time_point_cast<Duration, Clock> (tp);
+}
+
+
+inline
+Time
+now ()
+{
+    return time_cast (Clock::now ());
+}
+
+
+inline
+Time
+from_time_t (time_t t_time)
+{
+    return time_cast (Clock::from_time_t (t_time));
+}
+
+
+inline
+time_t
+to_time_t (Time const & the_time)
+{
+    // This is based on <http://stackoverflow.com/a/17395137/341065>. It is
+    // possible that to_time_t() returns rounded time and we want truncation.
+
+    time_t time = Clock::to_time_t (the_time);
+    auto const rounded_time = from_time_t (time);
+    if (rounded_time > the_time)
+        --time;
+
+    return time;
+}
+
+
+LOG4CPLUS_EXPORT Time from_struct_tm (tm * t);
+
+
+inline
+Time
+truncate_fractions (Time const & the_time)
+{
+    return from_time_t (to_time_t (the_time));
+}
+
+
+inline
+long
+microseconds_part (Time const & the_time)
+{
+    static_assert ((std::ratio_equal<Duration::period, std::micro>::value),
+        "microseconds");
+
+    // This is based on <http://stackoverflow.com/a/17395137/341065>
+    return static_cast<long>(
+        (the_time - from_time_t (to_time_t (the_time))).count ());
+}
+
+
+inline
+Time
+time_from_parts (time_t tv_sec, long tv_usec)
+{
+    return from_time_t (tv_sec) + chrono::microseconds (tv_usec);
+}
 
 
 /**
- * This class represents a Epoch time with microsecond accuracy.
+ * Populates <code>tm</code> using the <code>gmtime()</code>
+ * function.
  */
-class LOG4CPLUS_EXPORT Time {
-public:
-    Time();
-    Time(time_t tv_sec, long tv_usec);
-    explicit Time(time_t time);
-
-    /**
-     * Returns the current time using the <code>gettimeofday()</code>
-     * method if it is available on the current platform.  (Not on 
-     * WIN32.)
-     */
-    static Time gettimeofday();
-
-  // Methods
-    /**
-     * Returns <i>seconds</i> value.
-     */
-    time_t sec() const { return tv_sec; }
-
-    /**
-     * Returns <i>microseconds</i> value.
-     */
-    long usec() const { return tv_usec; }
-
-    /**
-     * Sets the <i>seconds</i> value.
-     */
-    void sec(time_t s) { tv_sec = s; }
-
-    /**
-     * Sets the <i>microseconds</i> value.
-     */
-    void usec(long us) { tv_usec = us; }
-
-    /**
-     * Sets this Time using the <code>mktime</code> function.
-     */
-    time_t setTime(tm* t);
-
-    /**
-     * Returns this Time as a <code>time_t</code> value.
-     */
-    time_t getTime() const LOG4CPLUS_ATTRIBUTE_PURE;
-
-    /**
-     * Populates <code>tm</code> using the <code>gmtime()</code>
-     * function.
-     */
-    void gmtime(tm* t) const;
-
-    /**
-     * Populates <code>tm</code> using the <code>localtime()</code>
-     * function.
-     */
-    void localtime(tm* t) const;
-
-    /**
-     * Returns a string with a "formatted time" specified by
-     * <code>fmt</code>.  It used the <code>strftime()</code>
-     * function to do this.  
-     * 
-     * Look at your platform's <code>strftime()</code> documentation
-     * for the formatting options available.
-     * 
-     * The following additional options are provided:<br>
-     * <code>%q</code> - 3 character field that provides milliseconds
-     * <code>%Q</code> - 7 character field that provides fractional 
-     * milliseconds.
-     */
-    log4cplus::tstring getFormattedTime(const log4cplus::tstring& fmt,
-                                        bool use_gmtime = false) const;
-
-  // Operators
-    Time& operator+=(const Time& rhs);
-    Time& operator-=(const Time& rhs);
-    Time& operator/=(long rhs);
-    Time& operator*=(long rhs);
-
-private:
-  // Data
-    time_t tv_sec;  /* seconds */
-    long tv_usec;  /* microseconds */
-};
-
-
-LOG4CPLUS_EXPORT const log4cplus::helpers::Time operator+
-                                   (const log4cplus::helpers::Time& lhs,
-                                    const log4cplus::helpers::Time& rhs);
-LOG4CPLUS_EXPORT const log4cplus::helpers::Time operator-
-                                   (const log4cplus::helpers::Time& lhs,
-                                    const log4cplus::helpers::Time& rhs);
-LOG4CPLUS_EXPORT const log4cplus::helpers::Time operator/
-                                   (const log4cplus::helpers::Time& lhs,
-                                    long rhs);
-LOG4CPLUS_EXPORT const log4cplus::helpers::Time operator*
-                                   (const log4cplus::helpers::Time& lhs,
-                                    long rhs);
-
-LOG4CPLUS_EXPORT bool operator<(const log4cplus::helpers::Time& lhs,
-                                const log4cplus::helpers::Time& rhs)
-    LOG4CPLUS_ATTRIBUTE_PURE;
-LOG4CPLUS_EXPORT bool operator<=(const log4cplus::helpers::Time& lhs,
-                                 const log4cplus::helpers::Time& rhs)
-    LOG4CPLUS_ATTRIBUTE_PURE;
-
-LOG4CPLUS_EXPORT bool operator>(const log4cplus::helpers::Time& lhs,
-                                const log4cplus::helpers::Time& rhs)
-    LOG4CPLUS_ATTRIBUTE_PURE;
-LOG4CPLUS_EXPORT bool operator>=(const log4cplus::helpers::Time& lhs,
-                                 const log4cplus::helpers::Time& rhs)
-    LOG4CPLUS_ATTRIBUTE_PURE;
-
-LOG4CPLUS_EXPORT bool operator==(const log4cplus::helpers::Time& lhs,
-                                 const log4cplus::helpers::Time& rhs)
-    LOG4CPLUS_ATTRIBUTE_PURE;
-LOG4CPLUS_EXPORT bool operator!=(const log4cplus::helpers::Time& lhs,
-                                 const log4cplus::helpers::Time& rhs)
-    LOG4CPLUS_ATTRIBUTE_PURE;
+
+LOG4CPLUS_EXPORT
+void gmTime (tm* t, Time const &);
+
+/**
+ * Populates <code>tm</code> using the <code>localtime()</code>
+ * function.
+ */
+
+LOG4CPLUS_EXPORT
+void localTime (tm* t, Time const &);
+
+/**
+ * Returns a string with a "formatted time" specified by
+ * <code>fmt</code>.  It used the <code>strftime()</code>
+ * function to do this.
+ *
+ * Look at your platform's <code>strftime()</code> documentation
+ * for the formatting options available.
+ *
+ * The following additional options are provided:<br>
+ * <code>%q</code> - 3 character field that provides milliseconds
+ * <code>%Q</code> - 7 character field that provides fractional
+ * milliseconds.
+ */
+LOG4CPLUS_EXPORT
+log4cplus::tstring getFormattedTime (log4cplus::tstring const & fmt,
+    Time const & the_time, bool use_gmtime = false);
+
 
 } // namespace helpers
 
@@ -176,4 +167,3 @@ LOG4CPLUS_EXPORT bool operator!=(const log4cplus::helpers::Time& lhs,
 
 
 #endif // LOG4CPLUS_HELPERS_TIME_HELPER_HEADER_
-

+ 22 - 23
include/log4cplus/hierarchy.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2001-2015 Tad E. Smith
+// Copyright 2001-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -82,23 +82,23 @@ namespace log4cplus {
          * This call will clear all logger definitions from the internal
          * hashtable. Invoking this method will irrevocably mess up the
          * logger hierarchy.
-         *                     
+         *
          * You should <em>really</em> know what you are doing before
          * invoking this method.
          */
         virtual void clear();
 
         /**
-         * Returns <code>true </code>if the named logger exists 
+         * Returns <code>true </code>if the named logger exists
          * (in the default hierarchy).
-         *                
+         *
          * @param name The name of the logger to search for.
          */
         virtual bool exists(const log4cplus::tstring& name);
 
         /**
          * Similar to {@link #disable(LogLevel)} except that the LogLevel
-         * argument is given as a log4cplus::tstring.  
+         * argument is given as a log4cplus::tstring.
          */
         virtual void disable(const log4cplus::tstring& loglevelStr);
 
@@ -153,12 +153,12 @@ namespace log4cplus {
 
         /**
          * Return a new logger instance named as the first parameter using
-         * the default factory. 
-         *                
+         * the default factory.
+         *
          * If a logger of that name already exists, then it will be
          * returned.  Otherwise, a new logger will be instantiated and
          * then linked with its existing ancestors as well as children.
-         *                                    
+         *
          * @param name The name of the logger to retrieve.
          */
         virtual Logger getInstance(const log4cplus::tstring& name);
@@ -166,12 +166,12 @@ namespace log4cplus {
         /**
          * Return a new logger instance named as the first parameter using
          * <code>factory</code>.
-         *                
+         *
          * If a logger of that name already exists, then it will be
          * returned.  Otherwise, a new logger will be instantiated by the
          * <code>factory</code> parameter and linked with its existing
          * ancestors as well as children.
-         *                                         
+         *
          * @param name The name of the logger to retrieve.
          * @param factory The factory that will make the new logger instance.
          */
@@ -180,12 +180,12 @@ namespace log4cplus {
         /**
          * Returns all the currently defined loggers in this hierarchy.
          *
-         * The root logger is <em>not</em> included in the returned list. 
+         * The root logger is <em>not</em> included in the returned list.
          */
         virtual LoggerList getCurrentLoggers();
 
-        /** 
-         * Is the LogLevel specified by <code>level</code> enabled? 
+        /**
+         * Is the LogLevel specified by <code>level</code> enabled?
          */
         virtual bool isDisabled(LogLevel level);
 
@@ -207,13 +207,13 @@ namespace log4cplus {
          * This method should be used sparingly and with care as it will
          * block all logging until it is completed.</p>
          */
-        virtual void resetConfiguration(); 
+        virtual void resetConfiguration();
 
         /**
          * Set the default LoggerFactory instance.
          */
-        virtual void setLoggerFactory(std::auto_ptr<spi::LoggerFactory> factory);
-        
+        virtual void setLoggerFactory(std::unique_ptr<spi::LoggerFactory> factory);
+
         /**
          * Returns the default LoggerFactory instance.
          */
@@ -222,7 +222,7 @@ namespace log4cplus {
         /**
          * Shutting down a hierarchy will <em>safely</em> close and remove
          * all appenders in all loggers including the root logger.
-         *                
+         *
          * Some appenders such as SocketAppender need to be closed before the
          * application exits. Otherwise, pending logging events might be
          * lost.
@@ -246,16 +246,16 @@ namespace log4cplus {
          * NOTE: This method does not lock the <code>hashtable_mutex</code>.
          */
         LOG4CPLUS_PRIVATE
-        virtual Logger getInstanceImpl(const log4cplus::tstring& name, 
+        Logger getInstanceImpl(const log4cplus::tstring& name,
             spi::LoggerFactory& factory);
-        
+
         /**
          * This is the implementation of the <code>getCurrentLoggers()</code>.
          * NOTE: This method does not lock the <code>hashtable_mutex</code>.
          */
         LOG4CPLUS_PRIVATE
-        virtual void initializeLoggerList(LoggerList& list) const;
-        
+        void initializeLoggerList(LoggerList& list) const;
+
         /**
          * This method loops through all the *potential* parents of
          * logger'. There 3 possible cases:
@@ -297,7 +297,7 @@ namespace log4cplus {
 
      // Data
         thread::Mutex hashtable_mutex;
-        std::auto_ptr<spi::LoggerFactory> defaultFactory;
+        std::unique_ptr<spi::LoggerFactory> defaultFactory;
         ProvisionNodeMap provisionNodes;
         LoggerMap loggerPtrs;
         Logger root;
@@ -322,4 +322,3 @@ namespace log4cplus {
 } // end namespace log4cplus
 
 #endif // LOG4CPLUS_HIERARCHY_HEADER_
-

+ 8 - 9
include/log4cplus/hierarchylocker.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2003-2015 Tad E. Smith
+// Copyright 2003-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -48,25 +48,25 @@ namespace log4cplus
     public:
       // ctor & dtor
         HierarchyLocker(Hierarchy& h);
-        ~HierarchyLocker();
-        
+        ~HierarchyLocker() LOG4CPLUS_NOEXCEPT_FALSE;
+
         /**
          * Calls the <code>resetConfiguration()</code> method on the locked Hierarchy.
          */
-        void resetConfiguration(); 
-        
+        void resetConfiguration();
+
         /**
          * Calls the <code>getInstance()</code> method on the locked Hierarchy.
          */
         Logger getInstance(const log4cplus::tstring& name);
-        
+
         /**
          * Calls the <code>getInstance()</code> method on the locked Hierarchy.
          */
         Logger getInstance(const log4cplus::tstring& name, spi::LoggerFactory& factory);
-        
+
         void addAppender(Logger &logger, log4cplus::SharedAppenderPtr& appender);
-        
+
     private:
       // Data
         Hierarchy& h;
@@ -77,4 +77,3 @@ namespace log4cplus
 } // end namespace log4cplus
 
 #endif // LOG4CPLUS_HIERARCHY_LOCKER_HEADER_
-

+ 62 - 0
include/log4cplus/initializer.h

@@ -0,0 +1,62 @@
+//  Copyright (C) 2015-2017, Vaclav Haisman. All rights reserved.
+//
+//  Redistribution and use in source and binary forms, with or without modifica-
+//  tion, are permitted provided that the following conditions are met:
+//
+//  1. Redistributions of  source code must  retain the above copyright  notice,
+//     this list of conditions and the following disclaimer.
+//
+//  2. Redistributions in binary form must reproduce the above copyright notice,
+//     this list of conditions and the following disclaimer in the documentation
+//     and/or other materials provided with the distribution.
+//
+//  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+//  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+//  FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
+//  APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
+//  INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
+//  DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
+//  OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
+//  ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
+//  (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
+//  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef LOG4CPLUS_INITIALIZER_HXX
+#define LOG4CPLUS_INITIALIZER_HXX
+
+#include <log4cplus/config.hxx>
+
+#if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
+#pragma once
+#endif
+
+#include <memory>
+
+
+namespace log4cplus
+{
+
+/**
+   This class helps with initialization and shutdown of log4cplus. Its
+   constructor calls `log4cplus::initialize()` and its destructor calls
+   `log4cplus::Logger::shutdown()`. Use this class as the first thing in your
+   `main()`. It will ensure shutdown of log4cplus at the end of
+   `main()`. This is particularly important on Windows, where shutdown of
+   standard threads outside `main()` is impossible.
+ */
+class LOG4CPLUS_EXPORT Initializer
+{
+public:
+    Initializer ();
+    ~Initializer ();
+
+    Initializer (Initializer const &) = delete;
+    Initializer (Initializer &&) = delete;
+    Initializer & operator = (Initializer const &) = delete;
+    Initializer & operator = (Initializer &&) = delete;
+};
+
+} // namespace log4cplus
+
+
+#endif // LOG4CPLUS_INITIALIZER_HXX

+ 151 - 0
include/log4cplus/internal/customloglevelmanager.h

@@ -0,0 +1,151 @@
+// -*- C++ -*-
+// Module:  Log4CPLUS
+// File:    customloglevelmanager.h
+// Created: 12/2018
+// Author:  Jens Rehsack
+// Author:  Václav Haisman
+//
+//
+//  Copyright (C) 2018, Jens Rehsack. All rights reserved.
+//
+//  Redistribution and use in source and binary forms, with or without modifica-
+//  tion, are permitted provided that the following conditions are met:
+//
+//  1. Redistributions of  source code must  retain the above copyright  notice,
+//     this list of conditions and the following disclaimer.
+//
+//  2. Redistributions in binary form must reproduce the above copyright notice,
+//     this list of conditions and the following disclaimer in the documentation
+//     and/or other materials provided with the distribution.
+//
+//  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+//  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+//  FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
+//  APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
+//  INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
+//  DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
+//  OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
+//  ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
+//  (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
+//  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/** @file
+ * This header contains declaration internal to log4cplus. They must never be
+ * visible from user accesible headers or exported in DLL/shared library.
+ */
+
+
+#ifndef LOG4CPLUS_INTERNAL_CUSTOMLOGLEVELMANAGER_HEADER_
+#define LOG4CPLUS_INTERNAL_CUSTOMLOGLEVELMANAGER_HEADER_
+
+#include <log4cplus/config.hxx>
+
+#if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
+#pragma once
+#endif
+
+#if ! defined (INSIDE_LOG4CPLUS)
+#  error "This header must not be be used outside log4cplus' implementation files."
+#endif
+
+#include <map>
+#include <log4cplus/thread/syncprims.h>
+#include <log4cplus/internal/internal.h>
+
+
+namespace log4cplus {
+
+namespace internal {
+
+
+/**
+ * Custom log level manager used by C API.
+ */
+class CustomLogLevelManager {
+protected:
+    log4cplus::thread::Mutex mtx;
+    bool pushed_methods;
+    std::map<LogLevel,tstring> ll2nm;
+    std::map<tstring,LogLevel> nm2ll;
+
+public:
+    CustomLogLevelManager()
+        : pushed_methods (false)
+    { }
+
+    bool add(LogLevel ll, tstring const &nm)
+    {
+        log4cplus::thread::MutexGuard guard (mtx);
+
+        if (! pushed_methods)
+        {
+            pushed_methods = true;
+            getLogLevelManager().pushToStringMethod(customToStringMethod);
+            getLogLevelManager().pushFromStringMethod(customFromStringMethod);
+        }
+
+        auto i = ll2nm.lower_bound(ll);
+        if( ( i != ll2nm.end() ) && ( i->first == ll ) && ( i->second != nm ) )
+            return false;
+
+        auto j = nm2ll.lower_bound(nm);
+        if( ( j != nm2ll.end() ) && ( j->first == nm ) && ( j->second != ll ) )
+            return false;
+
+        // there is no else after return
+        ll2nm.insert( i, std::make_pair(ll, nm) );
+        nm2ll.insert( j, std::make_pair(nm, ll) );
+        return true;
+    }
+
+    bool remove(LogLevel ll, tstring const &nm)
+    {
+        log4cplus::thread::MutexGuard guard (mtx);
+
+        auto i = ll2nm.find(ll);
+        auto j = nm2ll.find(nm);
+        if( ( i != ll2nm.end() ) && ( j != nm2ll.end() ) &&
+            ( i->first == j->second ) && ( i->second == j->first ) ) {
+            ll2nm.erase(i);
+            nm2ll.erase(j);
+
+            return true;
+        }
+
+        // there is no else after return
+        return false;
+    }
+
+protected:
+    tstring const & customToStringMethodWorker(LogLevel ll)
+    {
+        log4cplus::thread::MutexGuard guard (mtx);
+        auto i = ll2nm.find(ll);
+        if( i != ll2nm.end() )
+            return i->second;
+
+        return internal::empty_str;
+    }
+
+    LogLevel customFromStringMethodWorker(const tstring& nm)
+    {
+        log4cplus::thread::MutexGuard guard (mtx);
+        auto i = nm2ll.find(nm);
+        if( i != nm2ll.end() )
+            return i->second;
+
+        return NOT_SET_LOG_LEVEL;
+    }
+
+    LOG4CPLUS_PRIVATE static tstring const & customToStringMethod(LogLevel ll);
+    LOG4CPLUS_PRIVATE static LogLevel customFromStringMethod(const tstring& nm);
+};
+
+LOG4CPLUS_PRIVATE CustomLogLevelManager & getCustomLogLevelManager ();
+
+} // namespace internal
+
+} // namespace log4cplus
+
+
+#endif // LOG4CPLUS_INTERNAL_CUSTOMLOGLEVELMANAGER_HEADER

+ 1 - 1
include/log4cplus/internal/cygwin-win32.h

@@ -4,7 +4,7 @@
 // Created: 7/2011
 // Author:  Vaclav Zeman
 //
-//  Copyright (C) 2011-2015, Vaclav Zeman. All rights reserved.
+//  Copyright (C) 2011-2017, Vaclav Zeman. All rights reserved.
 //  
 //  Redistribution and use in source and binary forms, with or without modifica-
 //  tion, are permitted provided that the following conditions are met:

+ 5 - 1
include/log4cplus/internal/env.h

@@ -5,7 +5,7 @@
 // Author:  Vaclav Haisman
 //
 //
-//  Copyright (C) 2010-2015, Vaclav Haisman. All rights reserved.
+//  Copyright (C) 2010-2017, Vaclav Haisman. All rights reserved.
 //
 //  Redistribution and use in source and binary forms, with or without modifica-
 //  tion, are permitted provided that the following conditions are met:
@@ -39,6 +39,7 @@
 
 #include <vector>
 #include <log4cplus/tstring.h>
+#include <locale>
 
 #if defined (_WIN32)
 #include <log4cplus/config/windowsh-inc.h>
@@ -57,6 +58,9 @@ namespace log4cplus { namespace internal {
 //! Get environment variable value.
 bool get_env_var (tstring & value, tstring const & name);
 
+//! Get locale.
+std::locale get_locale_by_name(tstring const& locale_name);
+
 //! Parse a string as a boolean value.
 bool parse_bool (bool & val, tstring const & str);
 

+ 1 - 1
include/log4cplus/internal/internal.h

@@ -5,7 +5,7 @@
 // Author:  Vaclav Haisman
 //
 //
-//  Copyright (C) 2009-2015, Vaclav Haisman. All rights reserved.
+//  Copyright (C) 2009-2017, Vaclav Haisman. All rights reserved.
 //  
 //  Redistribution and use in source and binary forms, with or without modifica-
 //  tion, are permitted provided that the following conditions are met:

+ 5 - 8
include/log4cplus/internal/socket.h

@@ -5,7 +5,7 @@
 // Author:  Vaclav Haisman
 //
 //
-//  Copyright (C) 2010-2015, Vaclav Haisman. All rights reserved.
+//  Copyright (C) 2010-2017, Vaclav Haisman. All rights reserved.
 //
 //  Redistribution and use in source and binary forms, with or without modifica-
 //  tion, are permitted provided that the following conditions are met:
@@ -171,14 +171,11 @@ struct socket_holder
         return s;
     }
 
-private:
-    socket_holder (socket_holder const &);
-    socket_holder operator = (socket_holder const &);
+    socket_holder(socket_holder &&) = delete;
+    socket_holder(socket_holder const &) = delete;
 
-#if defined (LOG4CPLUS_HAVE_CXX11_SUPPORT)
-    socket_holder (socket_holder &&);
-    socket_holder operator = (socket_holder &&);
-#endif
+    socket_holder operator = (socket_holder &&) = delete;
+    socket_holder operator = (socket_holder const &) = delete;
 };
 
 

+ 8 - 7
include/log4cplus/layout.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2001-2015 Tad E. Smith
+// Copyright 2001-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -33,8 +33,10 @@
 #include <log4cplus/loglevel.h>
 #include <log4cplus/streams.h>
 #include <log4cplus/tstring.h>
+#include <log4cplus/helpers/timehelper.h>
 
 #include <vector>
+#include <memory>
 
 
 namespace log4cplus {
@@ -52,7 +54,6 @@ namespace log4cplus {
     {
 
         class Properties;
-        class Time;
 
     }
 
@@ -184,10 +185,10 @@ namespace log4cplus {
 
     protected:
        log4cplus::tstring dateFormat;
-       bool use_gmtime;
-       bool thread_printing;
-       bool category_prefixing;
-       bool context_printing;
+       bool use_gmtime = false;
+       bool thread_printing = true;
+       bool category_prefixing = true;
+       bool context_printing = true;
 
     private:
       // Disallow copying of instances of this class
@@ -629,7 +630,7 @@ namespace log4cplus {
 
       // Data
         log4cplus::tstring pattern;
-        std::vector<pattern::PatternConverter*> parsedPattern;
+        std::vector<std::unique_ptr<pattern::PatternConverter> > parsedPattern;
 
     private:
       // Disallow copying of instances of this class

+ 66 - 0
include/log4cplus/log4cplus.h

@@ -0,0 +1,66 @@
+//  Copyright (C) 2015-2017, Vaclav Haisman. All rights reserved.
+//
+//  Redistribution and use in source and binary forms, with or without modifica-
+//  tion, are permitted provided that the following conditions are met:
+//
+//  1. Redistributions of  source code must  retain the above copyright  notice,
+//     this list of conditions and the following disclaimer.
+//
+//  2. Redistributions in binary form must reproduce the above copyright notice,
+//     this list of conditions and the following disclaimer in the documentation
+//     and/or other materials provided with the distribution.
+//
+//  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+//  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+//  FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
+//  APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
+//  INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
+//  DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
+//  OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
+//  ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
+//  (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
+//  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef LOG4CPLUS_LOG4CPLUS_HXX
+#define LOG4CPLUS_LOG4CPLUS_HXX
+
+#include <log4cplus/config.hxx>
+
+#if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
+#pragma once
+#endif
+
+#include <log4cplus/version.h>
+#include <log4cplus/loglevel.h>
+#include <log4cplus/logger.h>
+#include <log4cplus/layout.h>
+#include <log4cplus/hierarchy.h>
+#include <log4cplus/loggingmacros.h>
+#include <log4cplus/tracelogger.h>
+#include <log4cplus/configurator.h>
+#include <log4cplus/appender.h>
+#include <log4cplus/mdc.h>
+#include <log4cplus/ndc.h>
+#include <log4cplus/initializer.h>
+#include <log4cplus/helpers/property.h>
+#include <log4cplus/spi/factory.h>
+#include <log4cplus/spi/filter.h>
+#include <log4cplus/spi/loggingevent.h>
+
+#include <log4cplus/asyncappender.h>
+#include <log4cplus/consoleappender.h>
+#include <log4cplus/fileappender.h>
+#include <log4cplus/socketappender.h>
+#include <log4cplus/syslogappender.h>
+#include <log4cplus/nullappender.h>
+
+#if defined (LOG4CPLUS_WITH_UNIT_TESTS)
+namespace log4cplus
+{
+
+LOG4CPLUS_EXPORT int unit_tests_main (int argc, char* argv[]);
+
+} // namespace log4cplus
+#endif
+
+#endif // LOG4CPLUS_LOG4CPLUS_HXX

+ 9 - 4
include/log4cplus/log4judpappender.h

@@ -5,7 +5,7 @@
 // Author:  Siva Chandran P
 //
 //
-// Copyright 2012-2015 Siva Chandran P
+// Copyright 2012-2017 Siva Chandran P
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -50,14 +50,19 @@ namespace log4cplus {
      * <dd>Remote host name to connect and send events to.</dd>
      *
      * <dt><tt>port</tt></dt>
-     * <dd>Port on remote host to send events to.</dd>
+     * <dd>Port on remote host to send events to. Default is 5000.</dd>
+     *
+     * <dt><tt>IPv6</tt></dt>
+     * <dd>Boolean value specifying whether to use IPv6 (true) or IPv4
+     * (false). Default value is false.</dd>
      *
      * </dl>
      */
     class LOG4CPLUS_EXPORT Log4jUdpAppender : public Appender {
     public:
       // Ctors
-        Log4jUdpAppender(const log4cplus::tstring& host, int port);
+        Log4jUdpAppender(const log4cplus::tstring& host, int port,
+            bool ipv6 = false);
         Log4jUdpAppender(const log4cplus::helpers::Properties & properties);
 
       // Dtor
@@ -74,6 +79,7 @@ namespace log4cplus {
         log4cplus::helpers::Socket socket;
         log4cplus::tstring host;
         int port;
+        bool ipv6 = false;
 
     private:
       // Disallow copying of instances of this class
@@ -83,4 +89,3 @@ namespace log4cplus {
 } // end namespace log4cplus
 
 #endif // LOG4CPLUS_LOG4J_UDP_APPENDER_HEADER_
-

+ 48 - 48
include/log4cplus/logger.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2001-2015 Tad E. Smith
+// Copyright 2001-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -19,7 +19,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-/** @file 
+/** @file
  * This header defines the Logger class and the logging macros. */
 
 #ifndef LOG4CPLUS_LOGGERHEADER_
@@ -65,9 +65,6 @@ namespace log4cplus
      * This is the central class in the log4cplus package. One of the
      * distintive features of log4cplus are hierarchical loggers and their
      * evaluation.
-     * 
-     * See the <a href="../../../../manual.html">user manual</a> for an
-     * introduction on this class.
      */
     class LOG4CPLUS_EXPORT Logger
         : public log4cplus::spi::AppenderAttachable
@@ -75,9 +72,9 @@ namespace log4cplus
     public:
       // Static Methods
         /**
-         * Returns <code>true </code>if the named logger exists 
+         * Returns <code>true </code>if the named logger exists
          * (in the default hierarchy).
-         *                
+         *
          * @param name The name of the logger to search for.
          */
         static bool exists(const log4cplus::tstring& name);
@@ -85,27 +82,27 @@ namespace log4cplus
         /*
          * Returns all the currently defined loggers in the default
          * hierarchy.
-         * 
+         *
          * The root logger is <em>not</em> included in the returned
-         * list.      
+         * list.
         */
         static LoggerList getCurrentLoggers();
-     
+
         /**
          * Return the default Hierarchy instance.
          */
         static Hierarchy& getDefaultHierarchy();
 
         /**
-         * Retrieve a logger with name <code>name</code>.  If the named 
-         * logger already exists, then the existing instance will be returned. 
-         * Otherwise, a new instance is created. 
-         * 
+         * Retrieve a logger with name <code>name</code>.  If the named
+         * logger already exists, then the existing instance will be returned.
+         * Otherwise, a new instance is created.
+         *
          * By default, loggers do not have a set LogLevel but inherit
          * it from the hierarchy. This is one of the central features of
          * log4cplus.
-         * 
-         * @param name The name of the logger to retrieve.  
+         *
+         * @param name The name of the logger to retrieve.
          */
         static Logger getInstance(const log4cplus::tstring& name);
 
@@ -114,23 +111,24 @@ namespace log4cplus
          * instantiated depends on the type returned by the {@link
          * spi::LoggerFactory#makeNewLoggerInstance} method of the
          * <code>factory</code> parameter.
-         *                          
+         *
          * This method is intended to be used by sub-classes.
-         *                                   
+         *
          * @param name The name of the logger to retrieve.
          * @param factory A {@link spi::LoggerFactory} implementation that will
          * actually create a new Instance.
          */
-        static Logger getInstance(const log4cplus::tstring& name, spi::LoggerFactory& factory);
+        static Logger getInstance(const log4cplus::tstring& name,
+            spi::LoggerFactory& factory);
 
         /**
          * Return the root of the default logger hierrachy.
-         * 
+         *
          * The root logger is always instantiated and available. It's
          * name is "root".
-         * 
+         *
          * Nevertheless, calling {@link #getInstance
-         * Logger.getInstance("root")} does not retrieve the root logger 
+         * Logger.getInstance("root")} does not retrieve the root logger
          * but a logger just under root named "root".
          */
         static Logger getRoot();
@@ -139,15 +137,15 @@ namespace log4cplus
          * Calling this method will <em>safely</em> close and remove all
          * appenders in all the loggers including root contained in the
          * default hierachy.
-         *                     
+         *
          * Some appenders such as SocketAppender need to be closed before the
          * application exits. Otherwise, pending logging events might be
          * lost.
-         * 
+         *
          * The <code>shutdown</code> method is careful to close nested
          * appenders before closing regular appenders. This is allows
          * configurations where a regular appender is attached to a logger
-         * and again to a nested appender.  
+         * and again to a nested appender.
          */
         static void shutdown();
 
@@ -164,7 +162,7 @@ namespace log4cplus
 
         /**
          * Close all attached appenders implementing the AppenderAttachable
-         * interface.  
+         * interface.
          */
         void closeNestedAppenders() const;
 
@@ -177,7 +175,7 @@ namespace log4cplus
         bool isEnabledFor(LogLevel ll) const;
 
         /**
-         * This generic form is intended to be used by wrappers. 
+         * This generic form is intended to be used by wrappers.
          */
         void log(LogLevel ll, const log4cplus::tstring& message,
             const char* file = LOG4CPLUS_CALLER_FILE (),
@@ -188,7 +186,7 @@ namespace log4cplus
 
         /**
          * This method creates a new logging event and logs the event
-         * without further checks.  
+         * without further checks.
          */
         void forcedLog(LogLevel ll, const log4cplus::tstring& message,
             const char* file = LOG4CPLUS_CALLER_FILE (),
@@ -201,7 +199,7 @@ namespace log4cplus
          * Call the appenders in the hierrachy starting at
          * <code>this</code>.  If no appenders could be found, emit a
          * warning.
-         * 
+         *
          * This method calls all the appenders inherited from the
          * hierarchy circumventing any evaluation of whether to log or not
          * to log the particular log request.
@@ -214,15 +212,15 @@ namespace log4cplus
          * Starting from this logger, search the logger hierarchy for a
          * "set" LogLevel and return it. Otherwise, return the LogLevel of the
          * root logger.
-         * 
+         *
          * The Logger class is designed so that this method executes as
          * quickly as possible.
          */
         LogLevel getChainedLogLevel() const;
 
         /**
-         * Returns the assigned LogLevel, if any, for this Logger.  
-         *           
+         * Returns the assigned LogLevel, if any, for this Logger.
+         *
          * @return LogLevel - the assigned LogLevel, can be <code>NOT_SET_LOG_LEVEL</code>.
          */
         LogLevel getLogLevel() const;
@@ -239,12 +237,12 @@ namespace log4cplus
         Hierarchy& getHierarchy() const;
 
         /**
-         * Return the logger name.  
+         * Return the logger name.
          */
         log4cplus::tstring const & getName() const;
 
         /**
-         * Get the additivity flag for this Logger instance.  
+         * Get the additivity flag for this Logger instance.
          */
         bool getAdditivity() const;
 
@@ -266,16 +264,14 @@ namespace log4cplus
 
         virtual void removeAppender(const log4cplus::tstring& name);
 
-        Logger ();
-        Logger(const Logger& rhs);
-        Logger& operator=(const Logger& rhs);
-#if defined (LOG4CPLUS_HAVE_RVALUE_REFS)
-        Logger (Logger && rhs);
-        Logger & operator = (Logger && rhs);
-#endif
+        Logger () LOG4CPLUS_NOEXCEPT;
+        Logger(const Logger& rhs) LOG4CPLUS_NOEXCEPT;
+        Logger& operator=(const Logger& rhs) LOG4CPLUS_NOEXCEPT;
+        Logger (Logger && rhs) LOG4CPLUS_NOEXCEPT;
+        Logger & operator = (Logger && rhs) LOG4CPLUS_NOEXCEPT;
         virtual ~Logger();
 
-        void swap (Logger &);
+        void swap (Logger &) LOG4CPLUS_NOEXCEPT;
 
         /**
          * Used to retrieve the parent of this Logger in the
@@ -286,20 +282,20 @@ namespace log4cplus
     protected:
       // Data
         /** This is a pointer to the implementation class. */
-        spi::LoggerImpl * value;
+        spi::LoggerImpl * value = nullptr;
 
     private:
       // Ctors
         /**
-         * This constructor created a new <code>Logger</code> instance 
+         * This constructor created a new <code>Logger</code> instance
          * with a pointer to a Logger implementation.
-         * 
+         *
          * You should not create loggers directly.
          *
          * @param ptr A pointer to the Logger implementation.  This value
-         *            cannot be NULL.  
+         *            cannot be NULL.
          */
-        LOG4CPLUS_PRIVATE Logger(spi::LoggerImpl * ptr);
+        Logger(spi::LoggerImpl * ptr) LOG4CPLUS_NOEXCEPT;
 
       // Friends
         friend class log4cplus::spi::LoggerImpl;
@@ -311,11 +307,15 @@ namespace log4cplus
 
     /**
      * This class is used to create the default implementation of
-     * the Logger class
+     * the Logger class.
      */
     class LOG4CPLUS_EXPORT DefaultLoggerFactory : public spi::LoggerFactory {
     public:
         Logger makeNewLoggerInstance(const log4cplus::tstring& name, Hierarchy& h);
+
+    protected:
+        virtual spi::LoggerImpl * makeNewLoggerImplInstance(
+            const log4cplus::tstring& name, Hierarchy& h);
     };
 
 

+ 31 - 96
include/log4cplus/loggingmacros.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2003-2015 Tad E. Smith
+// Copyright 2003-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -42,7 +42,7 @@
 #if defined(_MSC_VER)
 #define LOG4CPLUS_SUPPRESS_DOWHILE_WARNING()  \
     __pragma (warning (push))                 \
-    __pragma (warning (disable:4127))           
+    __pragma (warning (disable:4127))
 
 #define LOG4CPLUS_RESTORE_DOWHILE_WARNING()   \
     __pragma (warning (pop))
@@ -98,7 +98,6 @@ macros_get_logger (Logger & logger)
 }
 
 
-#if defined (LOG4CPLUS_HAVE_RVALUE_REFS)
 inline
 Logger
 macros_get_logger (Logger && logger)
@@ -106,9 +105,6 @@ macros_get_logger (Logger && logger)
     return std::move (logger);
 }
 
-#endif
-
-
 inline
 Logger
 macros_get_logger (tstring const & logger)
@@ -145,7 +141,7 @@ LOG4CPLUS_EXPORT void macro_forced_log (log4cplus::Logger const &,
 
 
 #undef LOG4CPLUS_MACRO_FUNCTION
-#define LOG4CPLUS_MACRO_FUNCTION() 0
+#define LOG4CPLUS_MACRO_FUNCTION() nullptr
 #if ! defined (LOG4CPLUS_DISABLE_FUNCTION_MACRO)
 #  if defined (LOG4CPLUS_HAVE_FUNCSIG_MACRO)
 #    undef LOG4CPLUS_MACRO_FUNCTION
@@ -162,6 +158,13 @@ LOG4CPLUS_EXPORT void macro_forced_log (log4cplus::Logger const &,
 #  endif
 #endif
 
+#undef LOG4CPLUS_MACRO_FILE
+#define LOG4CPLUS_MACRO_FILE() nullptr
+#if ! defined (LOG4CPLUS_DISABLE_FILE_MACRO)
+#  undef LOG4CPLUS_MACRO_FILE
+#  define LOG4CPLUS_MACRO_FILE() __FILE__
+#endif
+
 
 // Make TRACE and DEBUG log level unlikely and INFO, WARN, ERROR and
 // FATAL log level likely.
@@ -216,7 +219,8 @@ LOG4CPLUS_EXPORT void macro_forced_log (log4cplus::Logger const &,
             _log4cplus_buf << logEvent;                                 \
             log4cplus::detail::macro_forced_log (_l,                    \
                 log4cplus::logLevel, _log4cplus_buf.str(),              \
-                __FILE__, __LINE__, LOG4CPLUS_MACRO_FUNCTION ());       \
+                LOG4CPLUS_MACRO_FILE (), __LINE__,                      \
+                LOG4CPLUS_MACRO_FUNCTION ());                           \
         }                                                               \
     } while (0)                                                         \
     LOG4CPLUS_RESTORE_DOWHILE_WARNING()
@@ -231,12 +235,12 @@ LOG4CPLUS_EXPORT void macro_forced_log (log4cplus::Logger const &,
                 _l.isEnabledFor (log4cplus::logLevel), logLevel)) {     \
             log4cplus::detail::macro_forced_log (_l,                    \
                 log4cplus::logLevel, logEvent,                          \
-                __FILE__, __LINE__, LOG4CPLUS_MACRO_FUNCTION ());       \
+                LOG4CPLUS_MACRO_FILE (), __LINE__,                      \
+                LOG4CPLUS_MACRO_FUNCTION ());                           \
         }                                                               \
     } while(0)                                                          \
     LOG4CPLUS_RESTORE_DOWHILE_WARNING()
 
-#if defined (LOG4CPLUS_HAVE_C99_VARIADIC_MACROS)
 #define LOG4CPLUS_MACRO_FMT_BODY(logger, logLevel, ...)                 \
     LOG4CPLUS_SUPPRESS_DOWHILE_WARNING()                                \
     do {                                                                \
@@ -249,32 +253,12 @@ LOG4CPLUS_EXPORT void macro_forced_log (log4cplus::Logger const &,
                 = _snpbuf.print (__VA_ARGS__);                          \
             log4cplus::detail::macro_forced_log (_l,                    \
                 log4cplus::logLevel, _logEvent,                         \
-                __FILE__, __LINE__, LOG4CPLUS_MACRO_FUNCTION ());       \
-        }                                                               \
-    } while(0)                                                          \
-    LOG4CPLUS_RESTORE_DOWHILE_WARNING()
-
-#elif defined (LOG4CPLUS_HAVE_GNU_VARIADIC_MACROS)
-#define LOG4CPLUS_MACRO_FMT_BODY(logger, logLevel, logArgs...)          \
-    LOG4CPLUS_SUPPRESS_DOWHILE_WARNING()                                \
-    do {                                                                \
-        log4cplus::Logger const & _l                                    \
-            = log4cplus::detail::macros_get_logger (logger);            \
-        if (LOG4CPLUS_MACRO_LOGLEVEL_PRED (                             \
-                _l.isEnabledFor (log4cplus::logLevel), logLevel)) {     \
-            LOG4CPLUS_MACRO_INSTANTIATE_SNPRINTF_BUF (_snpbuf);         \
-            log4cplus::tchar const * _logEvent                          \
-                = _snpbuf.print (logArgs);                              \
-            log4cplus::detail::macro_forced_log (_l,                    \
-                log4cplus::logLevel, _logEvent,                         \
-                __FILE__, __LINE__, LOG4CPLUS_MACRO_FUNCTION ());       \
+                LOG4CPLUS_MACRO_FILE (), __LINE__,                      \
+                LOG4CPLUS_MACRO_FUNCTION ());                           \
         }                                                               \
     } while(0)                                                          \
     LOG4CPLUS_RESTORE_DOWHILE_WARNING()
 
-#endif
-
-
 /**
  * @def LOG4CPLUS_TRACE(logger, logEvent) This macro creates a
  * TraceLogger to log a TRACE_LOG_LEVEL message to <code>logger</code>
@@ -284,29 +268,20 @@ LOG4CPLUS_EXPORT void macro_forced_log (log4cplus::Logger const &,
 #if !defined(LOG4CPLUS_DISABLE_TRACE)
 #define LOG4CPLUS_TRACE_METHOD(logger, logEvent)                        \
     log4cplus::TraceLogger _log4cplus_trace_logger(logger, logEvent,    \
-        __FILE__, __LINE__, LOG4CPLUS_MACRO_FUNCTION ());
+        LOG4CPLUS_MACRO_FILE (), __LINE__,                              \
+        LOG4CPLUS_MACRO_FUNCTION ());
 #define LOG4CPLUS_TRACE(logger, logEvent)                               \
     LOG4CPLUS_MACRO_BODY (logger, logEvent, TRACE_LOG_LEVEL)
 #define LOG4CPLUS_TRACE_STR(logger, logEvent)                           \
     LOG4CPLUS_MACRO_STR_BODY (logger, logEvent, TRACE_LOG_LEVEL)
-
-#if defined (LOG4CPLUS_HAVE_C99_VARIADIC_MACROS)
 #define LOG4CPLUS_TRACE_FMT(logger, ...)                                \
     LOG4CPLUS_MACRO_FMT_BODY (logger, TRACE_LOG_LEVEL, __VA_ARGS__)
-#elif defined (LOG4CPLUS_HAVE_GNU_VARIADIC_MACROS)
-#define LOG4CPLUS_TRACE_FMT(logger, logArgs...)                         \
-    LOG4CPLUS_MACRO_FMT_BODY(logger, TRACE_LOG_LEVEL, logArgs)
-#endif
 
 #else
 #define LOG4CPLUS_TRACE_METHOD(logger, logEvent) LOG4CPLUS_DOWHILE_NOTHING()
 #define LOG4CPLUS_TRACE(logger, logEvent) LOG4CPLUS_DOWHILE_NOTHING()
 #define LOG4CPLUS_TRACE_STR(logger, logEvent) LOG4CPLUS_DOWHILE_NOTHING()
-#if defined (LOG4CPLUS_HAVE_C99_VARIADIC_MACROS)
 #define LOG4CPLUS_TRACE_FMT(logger, logFmt, ...) LOG4CPLUS_DOWHILE_NOTHING()
-#elif defined (LOG4CPLUS_HAVE_GNU_VARIADIC_MACROS)
-#define LOG4CPLUS_TRACE_FMT(logger, logFmt, logArgs...) LOG4CPLUS_DOWHILE_NOTHING()
-#endif
 
 #endif
 
@@ -320,23 +295,13 @@ LOG4CPLUS_EXPORT void macro_forced_log (log4cplus::Logger const &,
     LOG4CPLUS_MACRO_BODY (logger, logEvent, DEBUG_LOG_LEVEL)
 #define LOG4CPLUS_DEBUG_STR(logger, logEvent)                           \
     LOG4CPLUS_MACRO_STR_BODY (logger, logEvent, DEBUG_LOG_LEVEL)
-
-#if defined (LOG4CPLUS_HAVE_C99_VARIADIC_MACROS)
 #define LOG4CPLUS_DEBUG_FMT(logger, ...)                                \
     LOG4CPLUS_MACRO_FMT_BODY (logger, DEBUG_LOG_LEVEL, __VA_ARGS__)
-#elif defined (LOG4CPLUS_HAVE_GNU_VARIADIC_MACROS)
-#define LOG4CPLUS_DEBUG_FMT(logger, logArgs...)                         \
-    LOG4CPLUS_MACRO_FMT_BODY(logger, DEBUG_LOG_LEVEL, logArgs)
-#endif
 
 #else
 #define LOG4CPLUS_DEBUG(logger, logEvent) LOG4CPLUS_DOWHILE_NOTHING()
 #define LOG4CPLUS_DEBUG_STR(logger, logEvent) LOG4CPLUS_DOWHILE_NOTHING()
-#if defined (LOG4CPLUS_HAVE_C99_VARIADIC_MACROS)
 #define LOG4CPLUS_DEBUG_FMT(logger, ...) LOG4CPLUS_DOWHILE_NOTHING()
-#elif defined (LOG4CPLUS_HAVE_GNU_VARIADIC_MACROS)
-#define LOG4CPLUS_DEBUG_FMT(logger, logArgs...) LOG4CPLUS_DOWHILE_NOTHING()
-#endif
 
 #endif
 
@@ -350,23 +315,13 @@ LOG4CPLUS_EXPORT void macro_forced_log (log4cplus::Logger const &,
     LOG4CPLUS_MACRO_BODY (logger, logEvent, INFO_LOG_LEVEL)
 #define LOG4CPLUS_INFO_STR(logger, logEvent)                            \
     LOG4CPLUS_MACRO_STR_BODY (logger, logEvent, INFO_LOG_LEVEL)
-
-#if defined (LOG4CPLUS_HAVE_C99_VARIADIC_MACROS)
 #define LOG4CPLUS_INFO_FMT(logger, ...)                                 \
     LOG4CPLUS_MACRO_FMT_BODY (logger, INFO_LOG_LEVEL, __VA_ARGS__)
-#elif defined (LOG4CPLUS_HAVE_GNU_VARIADIC_MACROS)
-#define LOG4CPLUS_INFO_FMT(logger, logArgs...)                          \
-    LOG4CPLUS_MACRO_FMT_BODY(logger, INFO_LOG_LEVEL, logArgs)
-#endif
 
 #else
 #define LOG4CPLUS_INFO(logger, logEvent) LOG4CPLUS_DOWHILE_NOTHING()
 #define LOG4CPLUS_INFO_STR(logger, logEvent) LOG4CPLUS_DOWHILE_NOTHING()
-#if defined (LOG4CPLUS_HAVE_C99_VARIADIC_MACROS)
 #define LOG4CPLUS_INFO_FMT(logger, ...) LOG4CPLUS_DOWHILE_NOTHING()
-#elif defined (LOG4CPLUS_HAVE_GNU_VARIADIC_MACROS)
-#define LOG4CPLUS_INFO_FMT(logger, logArgs...) LOG4CPLUS_DOWHILE_NOTHING()
-#endif
 
 #endif
 
@@ -380,23 +335,13 @@ LOG4CPLUS_EXPORT void macro_forced_log (log4cplus::Logger const &,
     LOG4CPLUS_MACRO_BODY (logger, logEvent, WARN_LOG_LEVEL)
 #define LOG4CPLUS_WARN_STR(logger, logEvent)                            \
     LOG4CPLUS_MACRO_STR_BODY (logger, logEvent, WARN_LOG_LEVEL)
-
-#if defined (LOG4CPLUS_HAVE_C99_VARIADIC_MACROS)
 #define LOG4CPLUS_WARN_FMT(logger, ...)                                 \
     LOG4CPLUS_MACRO_FMT_BODY (logger, WARN_LOG_LEVEL, __VA_ARGS__)
-#elif defined (LOG4CPLUS_HAVE_GNU_VARIADIC_MACROS)
-#define LOG4CPLUS_WARN_FMT(logger, logArgs...)                          \
-    LOG4CPLUS_MACRO_FMT_BODY(logger, WARN_LOG_LEVEL, logArgs)
-#endif
 
 #else
 #define LOG4CPLUS_WARN(logger, logEvent) LOG4CPLUS_DOWHILE_NOTHING()
 #define LOG4CPLUS_WARN_STR(logger, logEvent) LOG4CPLUS_DOWHILE_NOTHING()
-#if defined (LOG4CPLUS_HAVE_C99_VARIADIC_MACROS)
 #define LOG4CPLUS_WARN_FMT(logger, ...) LOG4CPLUS_DOWHILE_NOTHING()
-#elif defined (LOG4CPLUS_HAVE_GNU_VARIADIC_MACROS)
-#define LOG4CPLUS_WARN_FMT(logger, logArgs...) LOG4CPLUS_DOWHILE_NOTHING()
-#endif
 
 #endif
 
@@ -410,23 +355,13 @@ LOG4CPLUS_EXPORT void macro_forced_log (log4cplus::Logger const &,
     LOG4CPLUS_MACRO_BODY (logger, logEvent, ERROR_LOG_LEVEL)
 #define LOG4CPLUS_ERROR_STR(logger, logEvent)                           \
     LOG4CPLUS_MACRO_STR_BODY (logger, logEvent, ERROR_LOG_LEVEL)
-
-#if defined (LOG4CPLUS_HAVE_C99_VARIADIC_MACROS)
 #define LOG4CPLUS_ERROR_FMT(logger, ...)                                \
     LOG4CPLUS_MACRO_FMT_BODY (logger, ERROR_LOG_LEVEL, __VA_ARGS__)
-#elif defined (LOG4CPLUS_HAVE_GNU_VARIADIC_MACROS)
-#define LOG4CPLUS_ERROR_FMT(logger, logArgs...)                         \
-    LOG4CPLUS_MACRO_FMT_BODY(logger, ERROR_LOG_LEVEL, logArgs)
-#endif
 
 #else
 #define LOG4CPLUS_ERROR(logger, logEvent) LOG4CPLUS_DOWHILE_NOTHING()
 #define LOG4CPLUS_ERROR_STR(logger, logEvent) LOG4CPLUS_DOWHILE_NOTHING()
-#if defined (LOG4CPLUS_HAVE_C99_VARIADIC_MACROS)
 #define LOG4CPLUS_ERROR_FMT(logger, ...) LOG4CPLUS_DOWHILE_NOTHING()
-#elif defined (LOG4CPLUS_HAVE_GNU_VARIADIC_MACROS)
-#define LOG4CPLUS_ERROR_FMT(logger, logArgs...) LOG4CPLUS_DOWHILE_NOTHING()
-#endif
 
 #endif
 
@@ -440,32 +375,21 @@ LOG4CPLUS_EXPORT void macro_forced_log (log4cplus::Logger const &,
     LOG4CPLUS_MACRO_BODY (logger, logEvent, FATAL_LOG_LEVEL)
 #define LOG4CPLUS_FATAL_STR(logger, logEvent)                           \
     LOG4CPLUS_MACRO_STR_BODY (logger, logEvent, FATAL_LOG_LEVEL)
-
-#if defined (LOG4CPLUS_HAVE_C99_VARIADIC_MACROS)
 #define LOG4CPLUS_FATAL_FMT(logger, ...)                                \
     LOG4CPLUS_MACRO_FMT_BODY (logger, FATAL_LOG_LEVEL, __VA_ARGS__)
-#elif defined (LOG4CPLUS_HAVE_GNU_VARIADIC_MACROS)
-#define LOG4CPLUS_FATAL_FMT(logger, logArgs...)                         \
-    LOG4CPLUS_MACRO_FMT_BODY(logger, FATAL_LOG_LEVEL, logArgs)
-#endif
 
 #else
 #define LOG4CPLUS_FATAL(logger, logEvent) LOG4CPLUS_DOWHILE_NOTHING()
 #define LOG4CPLUS_FATAL_STR(logger, logEvent) LOG4CPLUS_DOWHILE_NOTHING()
-#if defined (LOG4CPLUS_HAVE_C99_VARIADIC_MACROS)
 #define LOG4CPLUS_FATAL_FMT(logger, ...) LOG4CPLUS_DOWHILE_NOTHING()
-#elif defined (LOG4CPLUS_HAVE_GNU_VARIADIC_MACROS)
-#define LOG4CPLUS_FATAL_FMT(logger, logArgs...) LOG4CPLUS_DOWHILE_NOTHING()
-#endif
 
 #endif
 
 //! Helper macro for LOG4CPLUS_ASSERT() macro.
 #define LOG4CPLUS_ASSERT_STRINGIFY(X) #X
 
-//! If the condition given in second parameter evaluates false, this
-//! macro logs it using FATAL log level, including the condition's
-//! source text.
+//! If the `condition` evaluates false, this macro logs it using FATAL
+//! log level, including the `condition`'s source text.
 #define LOG4CPLUS_ASSERT(logger, condition)                             \
     LOG4CPLUS_SUPPRESS_DOWHILE_WARNING()                                \
     do {                                                                \
@@ -476,5 +400,16 @@ LOG4CPLUS_EXPORT void macro_forced_log (log4cplus::Logger const &,
     } while (0)                                                         \
     LOG4CPLUS_RESTORE_DOWHILE_WARNING()
 
+//! If the `condition` evaluates false, this macro logs a message
+//! formatted from `printf` format string passed in 3rd and remaining
+//! arguments.
+#define LOG4CPLUS_ASSERT_FMT(logger, condition, ...)                    \
+    LOG4CPLUS_SUPPRESS_DOWHILE_WARNING()                                \
+    do {                                                                \
+        if (! (condition)) [[unlikely]] {                               \
+            LOG4CPLUS_FATAL_FMT ((logger), __VA_ARGS__);                \
+        }                                                               \
+    } while (false)                                                     \
+    LOG4CPLUS_RESTORE_DOWHILE_WARNING()
 
 #endif /* LOG4CPLUS_LOGGING_MACROS_HEADER_ */

+ 25 - 34
include/log4cplus/loglevel.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2001-2015 Tad E. Smith
+// Copyright 2001-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -19,7 +19,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-/** @file 
+/** @file
  * This header defines the LogLevel type.
  */
 
@@ -38,11 +38,11 @@
 
 namespace log4cplus {
 
-    /** 
+    /**
      * \typedef int LogLevel
      * Defines the minimum set of priorities recognized by the system,
      * that is {@link #FATAL_LOG_LEVEL}, {@link #ERROR_LOG_LEVEL}, {@link
-     * #WARN_LOG_LEVEL}, {@link #INFO_LOG_LEVEL}, {@link #DEBUG_LOG_LEVEL}, 
+     * #WARN_LOG_LEVEL}, {@link #INFO_LOG_LEVEL}, {@link #DEBUG_LOG_LEVEL},
      * and {@link #TRACE_LOG_LEVEL}.
      */
     typedef int LogLevel;
@@ -63,13 +63,13 @@ namespace log4cplus {
     const LogLevel ERROR_LOG_LEVEL   = 40000;
 
     /** \var const LogLevel WARN_LOG_LEVEL
-     * The <code>WARN_LOG_LEVEL</code> LogLevel designates potentially harmful 
+     * The <code>WARN_LOG_LEVEL</code> LogLevel designates potentially harmful
      * situations. */
     const LogLevel WARN_LOG_LEVEL    = 30000;
 
     /** \var const LogLevel INFO_LOG_LEVEL
-     * The <code>INFO_LOG_LEVEL</code> LogLevel designates informational 
-     * messages  that highlight the progress of the application at 
+     * The <code>INFO_LOG_LEVEL</code> LogLevel designates informational
+     * messages  that highlight the progress of the application at
      * coarse-grained  level. */
     const LogLevel INFO_LOG_LEVEL    = 20000;
 
@@ -82,7 +82,7 @@ namespace log4cplus {
      * The <code>TRACE_LOG_LEVEL</code> LogLevel is used to "trace" entry
      * and exiting of methods. */
     const LogLevel TRACE_LOG_LEVEL   = 0;
-    
+
     /** \var const LogLevel ALL_LOG_LEVEL
      * The <code>ALL_LOG_LEVEL</code> LogLevel is used during configuration to
      * turn on all logging. */
@@ -95,27 +95,24 @@ namespace log4cplus {
     const LogLevel NOT_SET_LOG_LEVEL = -1;
 
 
-    /** 
+    /**
      * This method type defined the signature of methods that convert LogLevels
-     * into strings. 
-     * 
+     * into strings.
+     *
      * <b>Note:</b> Must return an empty <code>tstring</code> for unrecognized values.
      */
     typedef log4cplus::tstring const & (*LogLevelToStringMethod)(LogLevel);
 
-    //! This function type is for log4cplus 1.0.x callbacks.
-    typedef log4cplus::tstring (*LogLevelToStringMethod_1_0) (LogLevel);
 
-
-    /** 
+    /**
      * This method type defined the signature of methods that convert strings
-     * into LogLevels. 
-     * 
+     * into LogLevels.
+     *
      * <b>Note:</b> Must return <code>NOT_SET_LOG_LEVEL</code> for unrecognized values.
      */
     typedef LogLevel (*StringToLogLevelMethod)(const log4cplus::tstring&);
 
-    
+
 
     /**
      * This class is used to "manage" LogLevel definitions.  This class is also
@@ -138,38 +135,35 @@ namespace log4cplus {
         /**
          * This method is called by all Layout classes to convert a LogLevel
          * into a string.
-         * 
+         *
          * Note: It traverses the list of <code>LogLevelToStringMethod</code>
          *       to do this, so all "derived" LogLevels are recognized as well.
          */
         log4cplus::tstring const & toString(LogLevel ll) const;
-        
+
         /**
          * This method is called by all classes internally to log4cplus to
          * convert a string into a LogLevel.
-         * 
+         *
          * Note: It traverses the list of <code>StringToLogLevelMethod</code>
          *       to do this, so all "derived" LogLevels are recognized as well.
          */
-        LogLevel fromString(const log4cplus::tstring& s) const;
+        LogLevel fromString(const log4cplus::tstring& arg) const;
 
         /**
          * When creating a "derived" LogLevel, a <code>LogLevelToStringMethod</code>
          * should be defined and registered with the LogLevelManager by calling
          * this method.
-         * 
+         *
          * @see pushFromStringMethod
          */
         void pushToStringMethod(LogLevelToStringMethod newToString);
 
-        //! For compatibility with log4cplus 1.0.x.
-        void pushToStringMethod(LogLevelToStringMethod_1_0 newToString);
-
         /**
          * When creating a "derived" LogLevel, a <code>StringToLogLevelMethod</code>
          * should be defined and registered with the LogLevelManager by calling
          * this method.
-         * 
+         *
          * @see pushToStringMethod
          */
         void pushFromStringMethod(StringToLogLevelMethod newFromString);
@@ -178,12 +172,10 @@ namespace log4cplus {
       // Data
         struct LogLevelToStringMethodRec
         {
-            union
-            {
-                LogLevelToStringMethod func;
-                LogLevelToStringMethod_1_0 func_1_0;
-            };
-            bool use_1_0;
+            LogLevelToStringMethodRec ();
+            LogLevelToStringMethodRec (LogLevelToStringMethod);
+
+            LogLevelToStringMethod func;
         };
 
         typedef std::vector<LogLevelToStringMethodRec> LogLevelToStringMethodList;
@@ -206,4 +198,3 @@ namespace log4cplus {
 
 
 #endif // LOG4CPLUS_LOGLEVEL_HEADER_
-

+ 1 - 1
include/log4cplus/mdc.h

@@ -1,5 +1,5 @@
 // -*- C++ -*-
-//  Copyright (C) 2010-2015, Vaclav Haisman. All rights reserved.
+//  Copyright (C) 2010-2017, Vaclav Haisman. All rights reserved.
 //  
 //  Redistribution and use in source and binary forms, with or without modifica-
 //  tion, are permitted provided that the following conditions are met:

+ 8 - 8
include/log4cplus/msttsappender.h

@@ -5,18 +5,18 @@
 // Author:  Vaclav Zeman
 //
 //
-//  Copyright (C) 2012-2015, Vaclav Zeman. All rights reserved.
-//  
+//  Copyright (C) 2012-2017, Vaclav Zeman. All rights reserved.
+//
 //  Redistribution and use in source and binary forms, with or without modifica-
 //  tion, are permitted provided that the following conditions are met:
-//  
+//
 //  1. Redistributions of  source code must  retain the above copyright  notice,
 //     this list of conditions and the following disclaimer.
-//  
+//
 //  2. Redistributions in binary form must reproduce the above copyright notice,
 //     this list of conditions and the following disclaimer in the documentation
 //     and/or other materials provided with the distribution.
-//  
+//
 //  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 //  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 //  FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
@@ -27,8 +27,8 @@
 //  ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
 //  (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
 //  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-   
- 
+
+
 //
 
 /** @file */
@@ -48,7 +48,7 @@
 #if defined (_WIN32)
   #if defined (log4cplusqt4debugappender_EXPORTS) \
       || defined (log4cplusqt4debugappenderU_EXPORTS) \
-      || defined (DLL_EXPORT)
+      || (defined (DLL_EXPORT) && defined (INSIDE_LOG4CPLUS_MSTTSAPPENDER))
     #undef LOG4CPLUS_MSTTSAPPENDER_BUILD_DLL
     #define LOG4CPLUS_MSTTSAPPENDER_BUILD_DLL
   #endif

+ 14 - 11
include/log4cplus/ndc.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2001-2015 Tad E. Smith
+// Copyright 2001-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -19,7 +19,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-/** @file 
+/** @file
  * This header defined the NDC class.
  */
 
@@ -76,7 +76,7 @@ namespace log4cplus {
      *   this method will create it.
      * - When leaving a context, call `pop()`.
      * - When exiting a thread make sure to call `remove()`.
-     *                                          
+     *
      * There is no penalty for forgetting to match each push()
      * operation with a corresponding pop(), except the obvious
      * mismatch between the real application context and the context
@@ -125,7 +125,7 @@ namespace log4cplus {
          *
          * The child thread uses the {@link #inherit inherit} method to
          * inherit the parent's diagnostic context.
-         *                                        
+         *
          * @return Stack A clone of the current thread's  diagnostic context.
          */
         DiagnosticContextStack cloneStack() const;
@@ -187,7 +187,7 @@ namespace log4cplus {
          *
          * The returned value is the value that was pushed last. If no
          * context is available, then the empty string is returned.
-         *                          
+         *
          * @return String The innermost diagnostic context.
          */
         log4cplus::tstring const & peek() const;
@@ -244,7 +244,7 @@ namespace log4cplus {
          *
          * ensures that between the entry and exit of foo the depth of the
          * diagnostic stack is conserved.
-         * 
+         *
          * \note Use of the NDCContextCreator class will solve this
          * particular problem.
          *
@@ -292,11 +292,8 @@ namespace log4cplus {
         DiagnosticContext(tchar const * message);
         DiagnosticContext(DiagnosticContext const &);
         DiagnosticContext & operator = (DiagnosticContext const &);
-
-#if defined (LOG4CPLUS_HAVE_RVALUE_REFS)
         DiagnosticContext(DiagnosticContext &&);
         DiagnosticContext & operator = (DiagnosticContext &&);
-#endif
 
         void swap (DiagnosticContext &);
 
@@ -313,8 +310,14 @@ namespace log4cplus {
     class LOG4CPLUS_EXPORT NDCContextCreator {
     public:
         /** Pushes <code>msg</code> onto the NDC stack. */
-        NDCContextCreator(const log4cplus::tstring& msg);
-        NDCContextCreator(tchar const * msg);
+        explicit NDCContextCreator(const log4cplus::tstring& msg);
+        explicit NDCContextCreator(tchar const * msg);
+
+        NDCContextCreator() = delete;
+        NDCContextCreator(NDCContextCreator const &) = delete;
+        NDCContextCreator(NDCContextCreator &&) = delete;
+        NDCContextCreator & operator= (NDCContextCreator const &) = delete;
+        NDCContextCreator & operator= (NDCContextCreator &&) = delete;
 
         /** Pops the NDC stack. */
         ~NDCContextCreator();

+ 1 - 1
include/log4cplus/nteventlogappender.h

@@ -4,7 +4,7 @@
 // Created: 4/2003
 // Author:  Michael CATANZARITI
 //
-// Copyright 2003-2015 Michael CATANZARITI
+// Copyright 2003-2017 Michael CATANZARITI
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.

+ 1 - 1
include/log4cplus/nullappender.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2003-2015 Tad E. Smith
+// Copyright 2003-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.

+ 8 - 8
include/log4cplus/qt4debugappender.h

@@ -5,18 +5,18 @@
 // Author:  Vaclav Zeman
 //
 //
-//  Copyright (C) 2012-2015, Vaclav Zeman. All rights reserved.
-//  
+//  Copyright (C) 2012-2017, Vaclav Zeman. All rights reserved.
+//
 //  Redistribution and use in source and binary forms, with or without modifica-
 //  tion, are permitted provided that the following conditions are met:
-//  
+//
 //  1. Redistributions of  source code must  retain the above copyright  notice,
 //     this list of conditions and the following disclaimer.
-//  
+//
 //  2. Redistributions in binary form must reproduce the above copyright notice,
 //     this list of conditions and the following disclaimer in the documentation
 //     and/or other materials provided with the distribution.
-//  
+//
 //  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 //  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 //  FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
@@ -27,8 +27,8 @@
 //  ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
 //  (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
 //  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-   
- 
+
+
 //
 
 /** @file */
@@ -47,7 +47,7 @@
 #if defined (_WIN32)
   #if defined (log4cplusqt4debugappender_EXPORTS) \
       || defined (log4cplusqt4debugappenderU_EXPORTS) \
-      || defined (DLL_EXPORT)
+      || (defined (DLL_EXPORT) && defined (INSIDE_LOG4CPLUS_QT4DEBUGAPPENDER))
     #undef LOG4CPLUS_QT4DEBUGAPPENDER_BUILD_DLL
     #define LOG4CPLUS_QT4DEBUGAPPENDER_BUILD_DLL
   #endif

+ 8 - 8
include/log4cplus/qt5debugappender.h

@@ -5,18 +5,18 @@
 // Author:  Vaclav Zeman
 //
 //
-//  Copyright (C) 2013-2015, Vaclav Zeman. All rights reserved.
-//  
+//  Copyright (C) 2013-2017, Vaclav Zeman. All rights reserved.
+//
 //  Redistribution and use in source and binary forms, with or without modifica-
 //  tion, are permitted provided that the following conditions are met:
-//  
+//
 //  1. Redistributions of  source code must  retain the above copyright  notice,
 //     this list of conditions and the following disclaimer.
-//  
+//
 //  2. Redistributions in binary form must reproduce the above copyright notice,
 //     this list of conditions and the following disclaimer in the documentation
 //     and/or other materials provided with the distribution.
-//  
+//
 //  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 //  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 //  FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
@@ -27,8 +27,8 @@
 //  ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
 //  (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
 //  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-   
- 
+
+
 //
 
 /** @file */
@@ -47,7 +47,7 @@
 #if defined (_WIN32)
   #if defined (log4cplusqt5debugappender_EXPORTS) \
       || defined (log4cplusqt5debugappenderU_EXPORTS) \
-      || defined (DLL_EXPORT)
+      || (defined (DLL_EXPORT) && defined (INSIDE_LOG4CPLUS_QT5DEBUGAPPENDER))
     #undef LOG4CPLUS_QT5DEBUGAPPENDER_BUILD_DLL
     #define LOG4CPLUS_QT5DEBUGAPPENDER_BUILD_DLL
   #endif

+ 11 - 6
include/log4cplus/socketappender.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2003-2015 Tad E. Smith
+// Copyright 2003-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -79,7 +79,7 @@ namespace log4cplus
      *   then the rate of event production, then the client can only
      *   progress at the network rate. In particular, if the network link
      *   to the the server is down, the client will be blocked.
-     * 
+     *
      *   <li>On the other hand, if the network link is up, but the server
      *   is down, the client will not be blocked when making log requests
      *   but the log events will be lost due to server unavailability.
@@ -96,18 +96,23 @@ namespace log4cplus
      * <dt><tt>ServerName</tt></dt>
      * <dd>Host name of event's origin prepended to each event.</dd>
      *
+     * <dt><tt>IPv6</tt></dt>
+     * <dd>Boolean value specifying whether to use IPv6 (true) or IPv4
+     * (false). Default value is false.</dd>
+     *
      * </dl>
      */
     class LOG4CPLUS_EXPORT SocketAppender
-        : public Appender 
+        : public Appender
 #if ! defined (LOG4CPLUS_SINGLE_THREADED)
         , protected virtual helpers::IConnectorThreadClient
 #endif
     {
     public:
       // Ctors
-        SocketAppender(const log4cplus::tstring& host, unsigned short port, 
-                       const log4cplus::tstring& serverName = tstring());
+        SocketAppender(const log4cplus::tstring& host, unsigned short port,
+            const log4cplus::tstring& serverName = tstring(),
+            bool ipv6 = false);
         SocketAppender(const log4cplus::helpers::Properties & properties);
 
       // Dtor
@@ -126,6 +131,7 @@ namespace log4cplus
         log4cplus::tstring host;
         unsigned int port;
         log4cplus::tstring serverName;
+        bool ipv6 = false;
 
 #if ! defined (LOG4CPLUS_SINGLE_THREADED)
         virtual thread::Mutex const & ctcGetAccessMutex () const;
@@ -156,4 +162,3 @@ namespace log4cplus
 } // end namespace log4cplus
 
 #endif // LOG4CPLUS_SOCKET_APPENDER_HEADER_
-

+ 3 - 5
include/log4cplus/spi/appenderattachable.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2001-2015 Tad E. Smith
+// Copyright 2001-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -37,7 +37,6 @@
 
 namespace log4cplus {
     // Forward Declarations
-    typedef helpers::SharedObjectPtr<Appender> SharedAppenderPtr;
     typedef std::vector<log4cplus::SharedAppenderPtr> SharedAppenderPtrList;
 
     namespace spi {
@@ -54,7 +53,7 @@ namespace log4cplus {
             virtual void addAppender(SharedAppenderPtr newAppender) = 0;
 
             /**
-             * Get all previously added appenders as an Enumeration.  
+             * Get all previously added appenders as an Enumeration.
              */
             virtual SharedAppenderPtrList getAllAppenders() = 0;
 
@@ -75,7 +74,7 @@ namespace log4cplus {
 
             /**
              * Remove the appender with the name passed as parameter from the
-             * list of appenders.  
+             * list of appenders.
              */
             virtual void removeAppender(const log4cplus::tstring& name) = 0;
 
@@ -87,4 +86,3 @@ namespace log4cplus {
 } // end namespace log4cplus
 
 #endif // LOG4CPLUS_SPI_APPENDER_ATTACHABLE_HEADER_
-

+ 12 - 12
include/log4cplus/spi/factory.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2002-2015 Tad E. Smith
+// Copyright 2002-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -84,7 +84,7 @@ namespace log4cplus {
         class LOG4CPLUS_EXPORT LayoutFactory : public BaseFactory {
         public:
             typedef Layout ProductType;
-            typedef std::auto_ptr<Layout> ProductPtr;
+            typedef std::unique_ptr<Layout> ProductPtr;
 
             LayoutFactory();
             virtual ~LayoutFactory() = 0;
@@ -92,7 +92,7 @@ namespace log4cplus {
             /**
              * Create a "Layout" object.
              */
-            virtual std::auto_ptr<Layout> createObject(const log4cplus::helpers::Properties& props) = 0;
+            virtual std::unique_ptr<Layout> createObject(const log4cplus::helpers::Properties& props) = 0;
         };
 
 
@@ -138,11 +138,11 @@ namespace log4cplus {
 
         /**
          * This template class is used as a "Factory Registry".  Objects are
-         * "entered" into the registry with a "name" using the 
-         * <code>put()</code> method.  (The registry then owns the object.)  
-         * These object can then be retrieved using the <code>get()</code> 
+         * "entered" into the registry with a "name" using the
+         * <code>put()</code> method.  (The registry then owns the object.)
+         * These object can then be retrieved using the <code>get()</code>
          * method.
-         * 
+         *
          * <b>Note:</b>  This class is Thread-safe.
          */
         template<class T>
@@ -161,10 +161,10 @@ namespace log4cplus {
              * Used to enter an object into the registry.  (The registry now
              *  owns <code>object</code>.)
              */
-            bool put(std::auto_ptr<T> object) {
+            bool put(std::unique_ptr<T> object) {
                  bool putValResult = putVal(object->getTypeName(), object.get());
                  object.release();
-                 return putValResult; 
+                 return putValResult;
             }
 
             /**
@@ -248,14 +248,14 @@ namespace log4cplus {
 
         #define LOG4CPLUS_REG_PRODUCT(reg, productprefix, productname, productns, productfact) \
         reg.put (																               \
-            std::auto_ptr<productfact> (                                                       \
+            std::unique_ptr<productfact> (                                                     \
                     new log4cplus::spi::FactoryTempl<productns productname, productfact> (     \
                     LOG4CPLUS_TEXT(productprefix)                                              \
                     LOG4CPLUS_TEXT(#productname))))
 
         #define LOG4CPLUS_REG_APPENDER(reg, appendername)                             \
         LOG4CPLUS_REG_PRODUCT (reg, "log4cplus::", appendername, log4cplus::,         \
-            log4cplus::spi::AppenderFactory) 
+            log4cplus::spi::AppenderFactory)
 
         #define LOG4CPLUS_REG_LAYOUT(reg, layoutname)                                 \
         LOG4CPLUS_REG_PRODUCT (reg, "log4cplus::", layoutname, log4cplus::,           \
@@ -266,7 +266,7 @@ namespace log4cplus {
             log4cplus::spi::FilterFactory)
 
         #define LOG4CPLUS_REG_LOCALE(reg, name, factory)            \
-            reg.put (std::auto_ptr<log4cplus::spi::LocaleFactory> ( \
+            reg.put (std::unique_ptr<log4cplus::spi::LocaleFactory> ( \
                     new factory (name)))
     } // namespace spi
 }

+ 141 - 24
include/log4cplus/spi/filter.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 1999-2015 Tad E. Smith
+// Copyright 1999-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -19,7 +19,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-/** @file 
+/** @file
  * This header defines Filter and all of it's subclasses. */
 
 #ifndef LOG4CPLUS_SPI_FILTER_HEADER_
@@ -31,6 +31,8 @@
 #pragma once
 #endif
 
+#include <functional>
+
 #include <log4cplus/helpers/pointer.h>
 #include <log4cplus/loglevel.h>
 
@@ -47,15 +49,15 @@ namespace log4cplus {
     namespace spi {
 
 
-        enum FilterResult { DENY, /**< The log event must be dropped immediately 
-                                   *  without consulting with the remaining 
+        enum FilterResult { DENY, /**< The log event must be dropped immediately
+                                   *  without consulting with the remaining
                                    *  filters, if any, in the chain. */
                             NEUTRAL, /**< This filter is neutral with respect to
-                                      *  the log event; the remaining filters, if 
-                                      *  if any, should be consulted for a final 
+                                      *  the log event; the remaining filters, if
+                                      *  if any, should be consulted for a final
                                       *  decision. */
-                            ACCEPT /**< The log event must be logged immediately 
-                                    *  without consulting with the remaining 
+                            ACCEPT /**< The log event must be logged immediately
+                                    *  without consulting with the remaining
                                     *  filters, if any, in the chain. */
                           };
 
@@ -69,7 +71,7 @@ namespace log4cplus {
          *
          * Note: <code>filter</code> can be NULL.
          */
-        LOG4CPLUS_EXPORT FilterResult checkFilter(const Filter* filter, 
+        LOG4CPLUS_EXPORT FilterResult checkFilter(const Filter* filter,
                                                   const InternalLoggingEvent& event);
 
         typedef helpers::SharedObjectPtr<Filter> FilterPtr;
@@ -78,7 +80,7 @@ namespace log4cplus {
         /**
          * Users should extend this class to implement customized logging
          * event filtering. Note that the {@link Logger} and {@link
-         * Appender} classes have built-in filtering rules. It is suggested 
+         * Appender} classes have built-in filtering rules. It is suggested
          * that you first use and understand the built-in rules before rushing
          * to write your own custom filters.
          *
@@ -89,7 +91,7 @@ namespace log4cplus {
          *
          * If the value {@link #DENY} is returned, then the log event is
          * dropped immediately without consulting with the remaining
-         * filters. 
+         * filters.
          *
          * If the value {@link #NEUTRAL} is returned, then the next filter
          * in the chain is consulted. If there are no more filters in the
@@ -97,13 +99,13 @@ namespace log4cplus {
          * filters, the default behaviour is to log all logging events.
          *
          * If the value {@link #ACCEPT} is returned, then the log
-         * event is logged without consulting the remaining filters. 
+         * event is logged without consulting the remaining filters.
          *
          * The philosophy of log4cplus filters is largely inspired from the
-         * Linux ipchains. 
+         * Linux ipchains.
          */
-        class LOG4CPLUS_EXPORT Filter 
-            : public virtual log4cplus::helpers::SharedObject 
+        class LOG4CPLUS_EXPORT Filter
+            : public virtual log4cplus::helpers::SharedObject
         {
         public:
           // ctor and dtor
@@ -116,7 +118,7 @@ namespace log4cplus {
              */
             void appendFilter(FilterPtr filter);
 
-            /**     
+            /**
              * If the decision is <code>DENY</code>, then the event will be
              * dropped. If the decision is <code>NEUTRAL</code>, then the next
              * filter, if any, will be invoked. If the decision is ACCEPT then
@@ -124,7 +126,7 @@ namespace log4cplus {
              * the chain.
              *
              * @param event The LoggingEvent to decide upon.
-             * @return The decision of the filter.  
+             * @return The decision of the filter.
              */
             virtual FilterResult decide(const InternalLoggingEvent& event) const = 0;
 
@@ -134,7 +136,7 @@ namespace log4cplus {
              */
             FilterPtr next;
         };
-  
+
 
 
         /**
@@ -151,7 +153,7 @@ namespace log4cplus {
             DenyAllFilter (const log4cplus::helpers::Properties&);
 
             /**
-             * Always returns the {@link #DENY} regardless of the 
+             * Always returns the {@link #DENY} regardless of the
              * {@link InternalLoggingEvent} parameter.
              */
             virtual FilterResult decide(const InternalLoggingEvent& event) const;
@@ -164,7 +166,7 @@ namespace log4cplus {
          * The filter admits two options <b>LogLevelToMatch</b> and
          * <b>AcceptOnMatch</b>. If there is an exact match between the value
          * of the LogLevelToMatch option and the LogLevel of the {@link
-         * spi::InternalLoggingEvent}, then the {@link #decide} method returns 
+         * spi::InternalLoggingEvent}, then the {@link #decide} method returns
          * {@link #ACCEPT} in case the <b>AcceptOnMatch</b> option value is set
          * to <code>true</code>, if it is <code>false</code> then {@link #DENY}
          * is returned. If there is no match, {@link #NEUTRAL} is returned.
@@ -180,7 +182,7 @@ namespace log4cplus {
              * Returns {@link #NEUTRAL} if the <b>LogLevelToMatch</b>
              * option is not set or if there is no match.  Otherwise, if
              * there is a match, then the returned decision is {@link #ACCEPT}
-             * if the <b>AcceptOnMatch</b> property is set to <code>true</code>. 
+             * if the <b>AcceptOnMatch</b> property is set to <code>true</code>.
              * The returned decision is {@link #DENY} if the <b>AcceptOnMatch</b>
              * property is set to <code>false</code>.
              */
@@ -255,7 +257,7 @@ namespace log4cplus {
          * StringToMatch option and the message of the Logging event,
          * then the {@link #decide} method returns {@link #ACCEPT} if
          * the <b>AcceptOnMatch</b> option value is true, if it is false then
-         * {@link #DENY} is returned. If there is no match, {@link #NEUTRAL} 
+         * {@link #DENY} is returned. If there is no match, {@link #NEUTRAL}
          * is returned.
          */
         class LOG4CPLUS_EXPORT StringMatchFilter : public Filter {
@@ -279,9 +281,124 @@ namespace log4cplus {
             log4cplus::tstring stringToMatch;
         };
 
+        /**
+         * This filter allows using `std::function<FilterResult(const
+         * InternalLoggingEvent &)>`.
+         */
+        class LOG4CPLUS_EXPORT FunctionFilter
+            : public Filter
+        {
+        public:
+            typedef std::function<FilterResult (const InternalLoggingEvent &)>
+                Function;
+
+            FunctionFilter (Function);
+
+            /**
+             * Returns result returned by `function`.
+             */
+            virtual FilterResult decide(const InternalLoggingEvent&) const;
+
+        private:
+            Function function;
+        };
+
+        /**
+         * This is a simple filter based on the string returned by event.getNDC().
+         *
+         * The filter admits three options <b>NeutralOnEmpty</b>, <b>NDCToMatch</b>
+         * and <b>AcceptOnMatch</b>.
+         *
+         * If <code>NeutralOnEmpty</code> is true and <code>NDCToMatch</code> is empty
+         * then {@link #NEUTRAL} is returned.
+         *
+         * If <code>NeutralOnEmpty</code> is true and the value returned by event.getNDC() is empty
+         * then {@link #NEUTRAL} is returned.
+         *
+         * If the string returned by event.getNDC() matches <code>NDCToMatch</code>, then if
+         * <b>AcceptOnMatch</b> is true, {@link #ACCEPT} is returned, and if
+         * <b>AcceptOnMatch</b> is false, {@link #DENY} is returned.
+         *
+         * If the string returned by event.getNDC() does not match <code>NDCToMatch</code>, then if
+         * <b>AcceptOnMatch</b> is true, {@link #DENY} is returned, and if
+         * <b>AcceptOnMatch</b> is false, {@link #ACCEPT} is returned.
+         *
+         */
+
+        class LOG4CPLUS_EXPORT NDCMatchFilter : public Filter
+        {
+            public:
+              // ctors
+                NDCMatchFilter();
+                NDCMatchFilter(const log4cplus::helpers::Properties& p);
+
+                /**
+                 * Returns {@link #NEUTRAL} is there is no string match.
+                 */
+                virtual FilterResult decide(const InternalLoggingEvent& event) const;
+
+            private:
+              // Methods
+                LOG4CPLUS_PRIVATE void init();
+
+              // Data
+                /** Do we return ACCEPT when a match occurs. Default is <code>true</code>. */
+                bool acceptOnMatch;
+                /** return NEUTRAL if event.getNDC() is empty or ndcToMatch is empty. Default is <code>true</code>. */
+                bool neutralOnEmpty;
+                log4cplus::tstring ndcToMatch;
+        };
+
+        /**
+         * This is a simple filter based on the key/value pair stored in MDC.
+         *
+         * The filter admits four options <b>NeutralOnEmpty</b>, <b>MDCKeyToMatch</b>
+         * <b>MDCValueToMatch</b> and <b>AcceptOnMatch</b>.
+         *
+         * If <code>NeutralOnEmpty</code> is true and <code>MDCKeyToMatch</code> or <code>MDCValueToMatch</code>
+         * is empty then {@link #NEUTRAL} is returned.
+         *
+         * If <code>NeutralOnEmpty</code> is true and the string returned by event.getMDC(MDCKeyToMatch) is empty
+         * then {@link #NEUTRAL} is returned.
+         *
+         * If the string returned by event.getMDC(MDCKeyToMatch) matches <code>MDCValueToMatch</code>, then if
+         * <b>AcceptOnMatch</b> is true, {@link #ACCEPT} is returned, and if
+         * <b>AcceptOnMatch</b> is false, {@link #DENY} is returned.
+         *
+         * If the string returned by event.getMDC(MDCKeyToMatch) does not match <code>MDCValueToMatch</code>, then if
+         * <b>AcceptOnMatch</b> is true, {@link #DENY} is returned, and if
+         * <b>AcceptOnMatch</b> is false, {@link #ACCEPT} is returned.
+         *
+         */
+
+        class LOG4CPLUS_EXPORT MDCMatchFilter : public Filter
+        {
+            public:
+              // ctors
+                MDCMatchFilter();
+                MDCMatchFilter(const log4cplus::helpers::Properties& p);
+
+                /**
+                 * Returns {@link #NEUTRAL} is there is no string match.
+                 */
+                virtual FilterResult decide(const InternalLoggingEvent& event) const;
+
+            private:
+              // Methods
+                LOG4CPLUS_PRIVATE void init();
+
+              // Data
+                /** Do we return ACCEPT when a match occurs. Default is <code>true</code>. */
+                bool acceptOnMatch;
+                /** return NEUTRAL if mdcKeyToMatch is empty or event::getMDC(mdcKeyValue) is empty or mdcValueToMatch is empty. Default is <code>true</code>. */
+                bool neutralOnEmpty;
+                /** The MDC key to retrieve **/
+                log4cplus::tstring mdcKeyToMatch;
+                /** the MDC value to match **/
+                log4cplus::tstring mdcValueToMatch;
+        };
+
     } // end namespace spi
 } // end namespace log4cplus
 
 #endif /* LOG4CPLUS_SPI_FILTER_HEADER_ */
-
-

+ 8 - 3
include/log4cplus/spi/loggerfactory.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2001-2015 Tad E. Smith
+// Copyright 2001-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -39,6 +39,8 @@ namespace log4cplus {
     class Hierarchy;
 
     namespace spi {
+        class LoggerImpl;
+
         /**
          * Implement this interface to create new instances of Logger or
          * a sub-class of Logger.
@@ -49,12 +51,15 @@ namespace log4cplus {
              * Creates a new <code>Logger</code> object.
              */
             virtual Logger makeNewLoggerInstance(const log4cplus::tstring& name,
-                                                 Hierarchy& h) = 0; 
+                                                 Hierarchy& h) = 0;
             virtual ~LoggerFactory() = 0;
+
+        protected:
+            virtual LoggerImpl * makeNewLoggerImplInstance(
+                const log4cplus::tstring& name, Hierarchy& h) = 0;
         };
 
     } // end namespace spi
 } // end namespace log4cplus
 
 #endif // LOG4CPLUS_SPI_LOGGER_FACTORY_HEADER
-

+ 21 - 26
include/log4cplus/spi/loggerimpl.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2001-2015 Tad E. Smith
+// Copyright 2001-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -47,9 +47,6 @@ namespace log4cplus {
          * This is the central class in the log4cplus package. One of the
          * distintive features of log4cplus are hierarchical loggers and their
          * evaluation.
-         *
-         * See the <a href="../../../../manual.html">user manual</a> for an
-         * introduction on this class. 
          */
         class LOG4CPLUS_EXPORT LoggerImpl
             : public virtual log4cplus::helpers::SharedObject,
@@ -64,23 +61,23 @@ namespace log4cplus {
              * Call the appenders in the hierrachy starting at
              * <code>this</code>.  If no appenders could be found, emit a
              * warning.
-             * 
+             *
              * This method calls all the appenders inherited from the
              * hierarchy circumventing any evaluation of whether to log or not
              * to log the particular log request.
-             *                                   
-             * @param event The event to log. 
+             *
+             * @param event The event to log.
              */
             virtual void callAppenders(const InternalLoggingEvent& event);
 
             /**
              * Close all attached appenders implementing the AppenderAttachable
-             * interface.  
+             * interface.
              */
             virtual void closeNestedAppenders();
 
             /**
-             * Check whether this logger is enabled for a given LogLevel passed 
+             * Check whether this logger is enabled for a given LogLevel passed
              * as parameter.
              *
              * @return boolean True if this logger is enabled for <code>ll</code>.
@@ -88,11 +85,11 @@ namespace log4cplus {
             virtual bool isEnabledFor(LogLevel ll) const;
 
             /**
-             * This generic form is intended to be used by wrappers. 
+             * This generic form is intended to be used by wrappers.
              */
             virtual void log(LogLevel ll, const log4cplus::tstring& message,
-                             const char* file=NULL, int line=-1,
-                             const char* function=NULL);
+                             const char* file=nullptr, int line=-1,
+                             const char* function=nullptr);
 
             virtual void log(spi::InternalLoggingEvent const &);
 
@@ -100,15 +97,15 @@ namespace log4cplus {
              * Starting from this logger, search the logger hierarchy for a
              * "set" LogLevel and return it. Otherwise, return the LogLevel of the
              * root logger.
-             *                     
+             *
              * The Logger class is designed so that this method executes as
              * quickly as possible.
              */
             virtual LogLevel getChainedLogLevel() const;
 
             /**
-             * Returns the assigned LogLevel, if any, for this Logger.  
-             *           
+             * Returns the assigned LogLevel, if any, for this Logger.
+             *
              * @return LogLevel - the assigned LogLevel.
              */
             LogLevel getLogLevel() const { return this->ll; }
@@ -125,7 +122,7 @@ namespace log4cplus {
             virtual Hierarchy& getHierarchy() const;
 
             /**
-             * Return the logger name.  
+             * Return the logger name.
              */
             log4cplus::tstring const & getName() const { return name; }
 
@@ -150,7 +147,7 @@ namespace log4cplus {
              * It is intended to be used by sub-classes only. You should not
              * create loggers directly.
              *
-             * @param name The name of the logger.  
+             * @param name The name of the logger.
              * @param h Hierarchy
              */
             LoggerImpl(const log4cplus::tstring& name, Hierarchy& h);
@@ -159,11 +156,11 @@ namespace log4cplus {
           // Methods
             /**
              * This method creates a new logging event and logs the event
-             * without further checks.  
+             * without further checks.
              */
             virtual void forcedLog(LogLevel ll,
                                    const log4cplus::tstring& message,
-                                   const char* file, 
+                                   const char* file,
                                    int line,
                                    const char* function);
 
@@ -181,18 +178,18 @@ namespace log4cplus {
 
             /**
              * The parent of this logger. All loggers have at least one
-             * ancestor which is the root logger. 
+             * ancestor which is the root logger.
              */
             SharedLoggerImplPtr parent;
 
-            /** 
+            /**
              * Additivity is set to true by default, that is children inherit
              * the appenders of their ancestors by default. If this variable is
              * set to <code>false</code> then the appenders found in the
              * ancestors of this logger are not used. However, the children
              * of this logger will inherit its appenders, unless the children
              * have their additivity flag set to <code>false</code> too. See
-             * the user manual for more details. 
+             * the user manual for more details.
              */
             bool additive;
 
@@ -202,8 +199,8 @@ namespace log4cplus {
             Hierarchy& hierarchy;
 
           // Disallow copying of instances of this class
-            LoggerImpl(const LoggerImpl&);
-            LoggerImpl& operator=(const LoggerImpl&);
+            LoggerImpl(const LoggerImpl&) = delete;
+            LoggerImpl& operator=(const LoggerImpl&) = delete;
 
           // Friends
             friend class log4cplus::Logger;
@@ -217,5 +214,3 @@ namespace log4cplus {
 } // end namespace log4cplus
 
 #endif // LOG4CPLUS_SPI_LOGGER_HEADER_
-
-

+ 5 - 7
include/log4cplus/spi/loggingevent.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2001-2015 Tad E. Smith
+// Copyright 2001-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -65,7 +65,7 @@ namespace log4cplus {
               */
             InternalLoggingEvent(const log4cplus::tstring& logger,
                 LogLevel loglevel, const log4cplus::tstring& message,
-                const char* filename, int line, const char * function = NULL);
+                const char* filename, int line, const char * function = nullptr);
 
             InternalLoggingEvent(const log4cplus::tstring& logger,
                 LogLevel loglevel, const log4cplus::tstring& ndc,
@@ -96,7 +96,7 @@ namespace log4cplus {
             void setLoggingEvent (const log4cplus::tstring & logger,
                 LogLevel ll, const log4cplus::tstring & message,
                 const char * filename, int line,
-                const char * function = NULL);
+                const char * function = nullptr);
 
             void setFunction (char const * func);
             void setFunction (log4cplus::tstring const &);
@@ -115,8 +115,7 @@ namespace log4cplus {
            /** Returns a copy of this object.  Derived classes
              *  should override this method.
              */
-            virtual std::auto_ptr<InternalLoggingEvent> clone() const;
-
+            virtual std::unique_ptr<InternalLoggingEvent> clone() const;
 
 
           // public methods
@@ -181,8 +180,7 @@ namespace log4cplus {
             }
 
 
-            /** The number of milliseconds elapsed from 1/1/1970 until
-             *  logging event was created. */
+            /** Time stamp when the event was created. */
             const log4cplus::helpers::Time& getTimestamp() const
             {
                 return timestamp;

+ 1 - 1
include/log4cplus/spi/objectregistry.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2003-2015 Tad E. Smith
+// Copyright 2003-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.

+ 2 - 2
include/log4cplus/spi/rootlogger.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2001-2015 Tad E. Smith
+// Copyright 2001-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -64,7 +64,7 @@ namespace log4cplus {
              * Setting a NOT_SET_LOG_LEVEL value to the LogLevel of the root logger 
              * may have catastrophic results. We prevent this here.
              */
-            void setLogLevel(LogLevel ll);
+            void setLogLevel(LogLevel);
 
         };
 

+ 1 - 1
include/log4cplus/streams.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2003-2015 Tad E. Smith
+// Copyright 2003-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.

+ 18 - 5
include/log4cplus/syslogappender.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2001-2015 Tad E. Smith
+// Copyright 2001-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -61,12 +61,21 @@ namespace log4cplus
      * <dt><tt>port</tt></dt>
      * <dd>Destination port of syslog service on host specified by the
      * <tt>host</tt> property. The default value is port 514.</dd>
-     * </dl>
      *
      * <dt><tt>udp</tt></dt> <dd>When the syslog is remote, this
      * property picks the IP protocol. When the value is true, UDP is
      * used. When the value is false, TCP is used. The default value
-     * is true.</dd> </dl>
+     * is true.</dd>
+     *
+     * <dt><tt>IPv6</tt></dt>
+     * <dd>Boolean value specifying whether to use IPv6 (true) or IPv4
+     * (false). Default value is false.</dd>
+     *
+     * <dt><tt>fqdn</tt></dt>
+     * <dd>Boolean value specifying whether to use FQDN for hostname field.
+     * Default value is true.</dd>
+     *
+     * </dl>
      *
      * \note Messages sent to remote syslog using UDP are conforming
      * to RFC5424. Messages sent to remote syslog using TCP are
@@ -85,14 +94,17 @@ namespace log4cplus
             RSTUdp,
             RSTTcp
         };
-      
+
       // Ctors
 #if defined (LOG4CPLUS_HAVE_SYSLOG_H)
         SysLogAppender(const tstring& ident);
 #endif
         SysLogAppender(const tstring& ident, const tstring & host,
             int port = 514, const tstring & facility = tstring (),
-            RemoteSyslogType remoteSyslogType = RSTUdp);
+            RemoteSyslogType remoteSyslogType = RSTUdp, bool ipv6 = false);
+        SysLogAppender(const tstring& ident, const tstring & host,
+            int port, const tstring & facility,
+            RemoteSyslogType remoteSyslogType, bool ipv6, bool fqdn);
         SysLogAppender(const log4cplus::helpers::Properties & properties);
 
       // Dtor
@@ -124,6 +136,7 @@ namespace log4cplus
         RemoteSyslogType remoteSyslogType;
         helpers::Socket syslogSocket;
         bool connected;
+        bool ipv6 = false;
 
         static tstring const remoteTimeFormat;
 

+ 1 - 1
include/log4cplus/tchar.h

@@ -1,5 +1,5 @@
 // -*- C++ -*-
-//  Copyright (C) 2010-2015, Vaclav Haisman. All rights reserved.
+//  Copyright (C) 2010-2017, Vaclav Haisman. All rights reserved.
 //  
 //  Redistribution and use in source and binary forms, with or without modifica-
 //  tion, are permitted provided that the following conditions are met:

+ 6 - 221
include/log4cplus/thread/impl/syncprims-cxx11.h

@@ -1,16 +1,16 @@
 // -*- C++ -*-
-//  Copyright (C) 2013-2015, Vaclav Zeman. All rights reserved.
-//  
+//  Copyright (C) 2013-2017, Vaclav Zeman. All rights reserved.
+//
 //  Redistribution and use in source and binary forms, with or without modifica-
 //  tion, are permitted provided that the following conditions are met:
-//  
+//
 //  1. Redistributions of  source code must  retain the above copyright  notice,
 //     this list of conditions and the following disclaimer.
-//  
+//
 //  2. Redistributions in binary form must reproduce the above copyright notice,
 //     this list of conditions and the following disclaimer in the documentation
 //     and/or other materials provided with the distribution.
-//  
+//
 //  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 //  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 //  FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
@@ -24,227 +24,12 @@
 
 //! @file
 //! This file contains implementations of synchronization
-//! primitives using the Win32 API. It does not contain any include
+//! primitives using the C++11 API. It does not contain any include
 //! guards because it is only a fragment to be included by
 //! syncprims.h.
 
-#include <stdexcept>
-#include <chrono>
-#include <algorithm>
-
-
 namespace log4cplus { namespace thread { namespace impl {
 
-
-//
-//
-//
-
-
-inline
-Mutex::Mutex (log4cplus::thread::Mutex::Type)
-{ }
-
-
-inline
-Mutex::~Mutex ()
-{ }
-
-
-inline
-void
-Mutex::lock () const
-{
-    mtx.lock ();
-}
-
-
-inline
-void
-Mutex::unlock () const
-{
-    mtx.unlock ();
-}
-
-
-//
-//
-//
-
-inline
-Semaphore::Semaphore (unsigned max_, unsigned initial)
-    : max (max_)
-    , val ((std::min) (max, initial))
-{ }
-
-
-inline
-Semaphore::~Semaphore ()
-{ }
-
-
-inline
-void
-Semaphore::unlock () const
-{
-    std::lock_guard<std::mutex> guard (mtx);
-
-    if (val >= max)
-        LOG4CPLUS_THROW_RTE ("Semaphore::unlock(): val >= max");
-
-    ++val;
-    cv.notify_all ();
-}
-
-
-inline
-void
-Semaphore::lock () const
-{
-    std::unique_lock<std::mutex> guard (mtx);
-
-    while (val == 0)        
-        cv.wait (guard);
-
-    --val;
-
-    if (LOG4CPLUS_UNLIKELY(val >= max))
-        LOG4CPLUS_THROW_RTE ("Semaphore::unlock(): val >= max");
-}
-
-
-//
-//
-//
-
-
-inline
-FairMutex::FairMutex ()
-    : sem (1, 1)
-{ }
-
-
-inline
-FairMutex::~FairMutex ()
-{ }
-
-
-inline
-void
-FairMutex::lock () const
-{
-    sem.lock ();
-}
-
-
-inline
-void
-FairMutex::unlock () const
-{
-    sem.unlock ();
-}
-
-
-//
-//
-//
-
-inline
-ManualResetEvent::ManualResetEvent (bool sig)
-    : sigcount (0)
-    , signaled (sig)
-{ }
-
-
-inline
-ManualResetEvent::~ManualResetEvent ()
-{ }
-
-
-inline
-void
-ManualResetEvent::signal () const
-{
-    std::unique_lock<std::mutex> guard (mtx);
-
-    signaled = true;
-    sigcount += 1;
-    cv.notify_all ();
-}
-
-
-inline
-void
-ManualResetEvent::wait () const
-{
-    std::unique_lock<std::mutex> guard (mtx);
-
-    if (! signaled)
-    {
-        unsigned prev_count = sigcount;
-        do
-        {
-            cv.wait (guard);
-        }
-        while (prev_count == sigcount);
-    }
-}
-
-
-inline
-bool
-ManualResetEvent::timed_wait (unsigned long msec) const
-{
-    std::unique_lock<std::mutex> guard (mtx);
-
-    if (! signaled)
-    {
-        unsigned prev_count = sigcount;
-
-        std::chrono::steady_clock::time_point const wait_until_time
-            = std::chrono::steady_clock::now ()
-            + std::chrono::milliseconds (msec);
-
-        do
-        {
-            int ret = static_cast<int>(
-                cv.wait_until (guard, wait_until_time));
-            switch (ret)
-            {
-            case static_cast<int>(std::cv_status::no_timeout):
-                break;
-
-            case static_cast<int>(std::cv_status::timeout):
-                return false;
-
-            default:
-                guard.unlock ();
-                guard.release ();
-                LOG4CPLUS_THROW_RTE ("ManualResetEvent::timed_wait");
-            }
-        }
-        while (prev_count == sigcount);
-    }
-
-    return true;
-}
-
-
-inline
-void
-ManualResetEvent::reset () const
-{
-    std::lock_guard<std::mutex> guard (mtx);
-
-    signaled = false;
-}
-
-
-//
-//
-//
-
 #include "log4cplus/thread/impl/syncprims-pmsm.h"
 
-
 } } } // namespace log4cplus { namespace thread { namespace impl {

+ 9 - 181
include/log4cplus/thread/impl/syncprims-impl.h

@@ -1,16 +1,16 @@
 // -*- C++ -*-
-//  Copyright (C) 2009-2015, Vaclav Haisman. All rights reserved.
-//  
+//  Copyright (C) 2009-2017, Vaclav Haisman. All rights reserved.
+//
 //  Redistribution and use in source and binary forms, with or without modifica-
 //  tion, are permitted provided that the following conditions are met:
-//  
+//
 //  1. Redistributions of  source code must  retain the above copyright  notice,
 //     this list of conditions and the following disclaimer.
-//  
+//
 //  2. Redistributions in binary form must reproduce the above copyright notice,
 //     this list of conditions and the following disclaimer in the documentation
 //     and/or other materials provided with the distribution.
-//  
+//
 //  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 //  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 //  FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
@@ -37,34 +37,9 @@
 
 #include <stdexcept>
 #include <log4cplus/thread/syncprims.h>
-#if defined (LOG4CPLUS_WITH_CXX11_THREADS)
-#  include <mutex>
-#  include <thread>
-#  include <condition_variable>
-
-#elif defined (_WIN32)
-#  include <log4cplus/config/windowsh-inc.h>
-
-#elif defined (LOG4CPLUS_USE_PTHREADS)
-#  include <errno.h>
-#  include <pthread.h>
-#  include <semaphore.h>
-#  if defined (LOG4CPLUS_USE_NAMED_POSIX_SEMAPHORE)
-#    include <sstream>
-#    include <string>
-#    if defined (LOG4CPLUS_HAVE_SYS_TYPES_H)
-#      include <sys/types.h>
-#    endif
-#    if defined (LOG4CPLUS_HAVE_UNISTD_H)
-#      include <unistd.h>
-#    endif
-#  endif
-#  if defined (LOG4CPLUS_HAVE_FCNTL_H)
-#    include <fcntl.h>
-#  endif
-#  include <log4cplus/helpers/timehelper.h>
-
-#endif
+#include <mutex>
+#include <thread>
+#include <condition_variable>
 
 
 namespace log4cplus { namespace thread { namespace impl {
@@ -75,134 +50,6 @@ LOG4CPLUS_EXPORT void LOG4CPLUS_ATTRIBUTE_NORETURN
     char const * const file, int line);
 
 
-#define LOG4CPLUS_THROW_RTE(msg) \
-    do { syncprims_throw_exception (msg, __FILE__, __LINE__); } while (0)
-
-
-class ManualResetEvent;
-
-
-class Mutex
-    : public MutexImplBase
-{
-public:
-    explicit Mutex (log4cplus::thread::Mutex::Type);
-    ~Mutex ();
-
-    void lock () const;
-    void unlock () const;
-
-private:
-#if defined (LOG4CPLUS_WITH_CXX11_THREADS)
-    mutable std::recursive_mutex mtx;
-#elif defined (LOG4CPLUS_USE_PTHREADS)
-    mutable pthread_mutex_t mtx;
-    friend class ManualResetEvent;
-#elif defined (LOG4CPLUS_USE_WIN32_THREADS)
-    mutable CRITICAL_SECTION cs;
-#endif
-    
-    Mutex (Mutex const &);
-    Mutex & operator = (Mutex &);
-};
-
-
-typedef SyncGuard<Mutex> MutexGuard;
-
-
-class Semaphore
-    : public SemaphoreImplBase
-{
-public:
-    Semaphore (unsigned max, unsigned initial);
-    ~Semaphore ();
-
-    void lock () const;
-    void unlock () const;
-
-private:
-#if defined (LOG4CPLUS_WITH_CXX11_THREADS)
-    mutable std::mutex mtx;
-    mutable std::condition_variable cv;
-    mutable unsigned max;
-    mutable unsigned val;
-
-#elif defined (LOG4CPLUS_USE_PTHREADS)
-#  if defined (LOG4CPLUS_USE_NAMED_POSIX_SEMAPHORE)
-    sem_t * sem;
-#  else
-    mutable sem_t sem;
-#  endif
-#elif defined (LOG4CPLUS_USE_WIN32_THREADS)
-    HANDLE sem;
-#endif
-
-    Semaphore (Semaphore const &);
-    Semaphore & operator = (Semaphore const &);
-};
-
-
-typedef SyncGuard<Semaphore> SemaphoreGuard;
-
-
-class FairMutex
-    : public FairMutexImplBase
-{
-public:
-    FairMutex ();
-    ~FairMutex ();
-
-    void lock () const;
-    void unlock () const;
-
-private:
-#if defined (LOG4CPLUS_USE_PTHREADS) \
-    || defined (LOG4CPLUS_WITH_CXX11_THREADS)
-    Semaphore sem;
-#elif defined (LOG4CPLUS_USE_WIN32_THREADS)
-    HANDLE mtx;
-#endif
-
-    FairMutex (FairMutex const &);
-    FairMutex & operator = (FairMutex &);
-};
-
-
-typedef SyncGuard<FairMutex> FairMutexGuard;
-
-
-class ManualResetEvent
-    : public ManualResetEventImplBase
-{
-public:
-    ManualResetEvent (bool = false);
-    ~ManualResetEvent ();
-
-    void signal () const;
-    void wait () const;
-    bool timed_wait (unsigned long msec) const;
-    void reset () const;
-
-private:
-#if defined (LOG4CPLUS_WITH_CXX11_THREADS)
-    mutable std::mutex mtx;
-    mutable std::condition_variable cv;
-    mutable unsigned sigcount;
-    mutable bool signaled;
-#elif defined (LOG4CPLUS_USE_PTHREADS)
-    mutable pthread_cond_t cv;
-    mutable Mutex mtx;
-    mutable volatile unsigned sigcount;
-    mutable volatile bool signaled;
-#elif defined (LOG4CPLUS_USE_WIN32_THREADS)
-    HANDLE ev;
-#endif
-
-    ManualResetEvent (ManualResetEvent const &);
-    ManualResetEvent & operator = (ManualResetEvent const &);
-};
-
-
 class SharedMutex
     : public SharedMutexImplBase
 {
@@ -216,8 +63,6 @@ public:
     void wrunlock () const;
 
 private:
-#if defined (LOG4CPLUS_POOR_MANS_SHAREDMUTEX) \
-    || defined (LOG4CPLUS_WITH_CXX11_THREADS)
     Mutex m1;
     Mutex m2;
     Mutex m3;
@@ -226,16 +71,6 @@ private:
     Semaphore r;
     mutable unsigned reader_count;
 
-#elif defined (LOG4CPLUS_USE_PTHREADS)
-    void unlock () const;
-
-    mutable pthread_rwlock_t rwl;
-
-#elif defined (LOG4CPLUS_USE_SRW_LOCK)
-    mutable SRWLOCK srwl;
-
-#endif
-
     SharedMutex (SharedMutex const &);
     SharedMutex & operator = (SharedMutex const &);
 };
@@ -247,14 +82,7 @@ private:
 // Include the appropriate implementations of the classes declared
 // above.
 
-#if defined (LOG4CPLUS_WITH_CXX11_THREADS)
-#  include <log4cplus/thread/impl/syncprims-cxx11.h>
-#elif defined (LOG4CPLUS_USE_PTHREADS)
-#  include <log4cplus/thread/impl/syncprims-pthreads.h>
-#elif defined (LOG4CPLUS_USE_WIN32_THREADS)
-#  include <log4cplus/thread/impl/syncprims-win32.h>
-#endif
-
+#include <log4cplus/thread/impl/syncprims-cxx11.h>
 
 #undef LOG4CPLUS_THROW_RTE
 

+ 8 - 8
include/log4cplus/thread/impl/syncprims-pmsm.h

@@ -1,16 +1,16 @@
 // -*- C++ -*-
-//  Copyright (C) 2010-2015, Vaclav Haisman. All rights reserved.
-//  
+//  Copyright (C) 2010-2017, Vaclav Haisman. All rights reserved.
+//
 //  Redistribution and use in source and binary forms, with or without modifica-
 //  tion, are permitted provided that the following conditions are met:
-//  
+//
 //  1. Redistributions of  source code must  retain the above copyright  notice,
 //     this list of conditions and the following disclaimer.
-//  
+//
 //  2. Redistributions in binary form must reproduce the above copyright notice,
 //     this list of conditions and the following disclaimer in the documentation
 //     and/or other materials provided with the distribution.
-//  
+//
 //  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 //  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 //  FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
@@ -41,9 +41,9 @@
 
 inline
 SharedMutex::SharedMutex ()
-    : m1 (log4cplus::thread::Mutex::DEFAULT)
-    , m2 (log4cplus::thread::Mutex::DEFAULT)
-    , m3 (log4cplus::thread::Mutex::DEFAULT)
+    : m1 ()
+    , m2 ()
+    , m3 ()
     , w (1, 1)
     , writer_count (0)
     , r (1, 1)

+ 0 - 507
include/log4cplus/thread/impl/syncprims-pthreads.h

@@ -1,507 +0,0 @@
-// -*- C++ -*-
-//  Copyright (C) 2009-2015, Vaclav Haisman. All rights reserved.
-//
-//  Redistribution and use in source and binary forms, with or without modifica-
-//  tion, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of  source code must  retain the above copyright  notice,
-//     this list of conditions and the following disclaimer.
-//
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//
-//  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
-//  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-//  FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
-//  APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
-//  INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
-//  DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
-//  OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
-//  ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
-//  (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
-//  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-//! @file
-//! This file contains implementations of synchronization
-//! primitives using the POSIX threads. It does not contain any
-//! include guards because it is only a fragment to be included by
-//! syncprims.h.
-
-#include "log4cplus/thread/threads.h"
-#include <limits>
-#include <algorithm>
-
-
-namespace log4cplus { namespace thread { namespace impl {
-
-
-struct PthreadMutexAttr
-{
-    PthreadMutexAttr ()
-    {
-        int ret = pthread_mutexattr_init (&attr);
-        if (LOG4CPLUS_UNLIKELY (ret != 0))
-            LOG4CPLUS_THROW_RTE ("PthreadMutexAttr::PthreadMutexAttr");
-    }
-
-
-    ~PthreadMutexAttr ()
-    {
-        try
-        {
-            int ret = pthread_mutexattr_destroy (&attr);
-            if (LOG4CPLUS_UNLIKELY (ret != 0))
-                LOG4CPLUS_THROW_RTE ("PthreadMutexAttr::~PthreadMutexAttr");
-        }
-        catch (...)
-        { }
-    }
-
-
-    void
-    set_type (log4cplus::thread::Mutex::Type t)
-    {
-        int mutex_type;
-        switch (t)
-        {
-        case log4cplus::thread::Mutex::RECURSIVE:
-            mutex_type = PTHREAD_MUTEX_RECURSIVE;
-            break;
-
-        default:
-            mutex_type = PTHREAD_MUTEX_DEFAULT;
-        }
-
-        int ret = pthread_mutexattr_settype (&attr, mutex_type);
-        if (LOG4CPLUS_UNLIKELY (ret != 0))
-            LOG4CPLUS_THROW_RTE ("PthreadMutexAttr::set_type");
-    }
-
-
-    pthread_mutexattr_t attr;
-};
-
-
-//
-//
-//
-
-inline
-Mutex::Mutex (log4cplus::thread::Mutex::Type t)
-{
-    PthreadMutexAttr attr;
-    attr.set_type (t);
-
-    int ret = pthread_mutex_init (&mtx, &attr.attr);
-    if (LOG4CPLUS_UNLIKELY (ret != 0))
-        LOG4CPLUS_THROW_RTE ("Mutex::Mutex");
-}
-
-
-inline
-Mutex::~Mutex ()
-{
-    try
-    {
-        int ret = pthread_mutex_destroy (&mtx);
-        if (LOG4CPLUS_UNLIKELY (ret != 0))
-            LOG4CPLUS_THROW_RTE ("Mutex::~Mutex");
-    }
-    catch (...)
-    { }
-}
-
-
-inline
-void
-Mutex::lock () const
-{
-    int ret = pthread_mutex_lock (&mtx);
-    if (LOG4CPLUS_UNLIKELY (ret != 0))
-        LOG4CPLUS_THROW_RTE ("Mutex::lock");
-}
-
-
-inline
-void
-Mutex::unlock () const
-{
-    int ret = pthread_mutex_unlock (&mtx);
-    if (LOG4CPLUS_UNLIKELY (ret != 0))
-        LOG4CPLUS_THROW_RTE ("Mutex::unlock");
-}
-
-
-//
-//
-//
-
-inline
-Semaphore::Semaphore (unsigned max, unsigned initial)
-{
-    unsigned const sem_value_max =
-#if defined (SEM_VALUE_MAX)
-        SEM_VALUE_MAX
-#else
-        (std::numeric_limits<int>::max) ()
-#endif
-        ;
-
-    unsigned const limited_max = (std::min) (max, sem_value_max);
-    unsigned const limited_initial = (std::min) (initial, limited_max);
-    int ret = 0;
-
-#if defined (LOG4CPLUS_USE_NAMED_POSIX_SEMAPHORE)
-    std::ostringstream oss;
-    char size_check[2 * (static_cast<int>(sizeof (std::ptrdiff_t))
-                         - static_cast<int>(sizeof (this))) + 1];
-    (void)size_check;
-    oss << getpid () << "-" << reinterpret_cast<std::ptrdiff_t>(this);
-    std::string name (oss.str ());
-
-    sem = sem_open (name.c_str (), O_CREAT, S_IRWXU | S_IRWXG, limited_max);
-    ret = sem == SEM_FAILED;
-    if (LOG4CPLUS_UNLIKELY (ret != 0))
-        LOG4CPLUS_THROW_RTE ("Semaphore::Semaphore");
-
-    try
-    {
-        // Unlink the semaphore early to simulate anonymous semaphore.
-        ret = sem_unlink (name.c_str ());
-        if (LOG4CPLUS_UNLIKELY (ret != 0))
-            LOG4CPLUS_THROW_RTE ("Semaphore::Semaphore");
-    }
-    catch (std::runtime_error const &)
-    {
-        ret = sem_close (sem);
-        if (LOG4CPLUS_UNLIKELY (ret != 0))
-            LOG4CPLUS_THROW_RTE ("Semaphore::~Semaphore");
-
-        throw;
-    }
-
-#else
-    ret = sem_init (&sem, 0, limited_max);
-    if (LOG4CPLUS_UNLIKELY (ret != 0))
-        LOG4CPLUS_THROW_RTE ("Semaphore::Semaphore");
-
-#endif
-
-    try
-    {
-        for (unsigned i = limited_initial; i < limited_max; ++i)
-            lock ();
-    }
-    catch (std::runtime_error const &)
-    {
-#if defined (LOG4CPLUS_USE_NAMED_POSIX_SEMAPHORE)
-        ret = sem_close (sem);
-#else
-        ret = sem_destroy (&sem);
-#endif
-        if (LOG4CPLUS_UNLIKELY (ret != 0))
-            LOG4CPLUS_THROW_RTE ("Semaphore::~Semaphore");
-
-        throw;
-    }
-}
-
-
-inline
-Semaphore::~Semaphore ()
-{
-    try
-    {
-        int ret = 0;
-#if defined (LOG4CPLUS_USE_NAMED_POSIX_SEMAPHORE)
-        ret = sem_close (sem);
-#else
-        ret = sem_destroy (&sem);
-#endif
-        if (LOG4CPLUS_UNLIKELY (ret != 0))
-            LOG4CPLUS_THROW_RTE ("Semaphore::~Semaphore");
-    }
-    catch (...)
-    { }
-}
-
-
-inline
-void
-Semaphore::unlock () const
-{
-#if defined (LOG4CPLUS_USE_NAMED_POSIX_SEMAPHORE)
-    int ret = sem_post (sem);
-#else
-    int ret = sem_post (&sem);
-#endif
-    if (LOG4CPLUS_UNLIKELY (ret != 0))
-        LOG4CPLUS_THROW_RTE ("Semaphore::unlock");
-}
-
-
-inline
-void
-Semaphore::lock () const
-{
-#if defined (LOG4CPLUS_USE_NAMED_POSIX_SEMAPHORE)
-    int ret = sem_wait (sem);
-#else
-    int ret = sem_wait (&sem);
-#endif
-    if (LOG4CPLUS_UNLIKELY (ret != 0))
-        LOG4CPLUS_THROW_RTE ("Semaphore::lock");
-}
-
-
-//
-//
-//
-
-
-inline
-FairMutex::FairMutex ()
-    : sem (1, 1)
-{ }
-
-
-inline
-FairMutex::~FairMutex ()
-{ }
-
-
-inline
-void
-FairMutex::lock () const
-{
-    sem.lock ();
-}
-
-
-inline
-void
-FairMutex::unlock () const
-{
-    sem.unlock ();
-}
-
-
-//
-//
-//
-
-inline
-ManualResetEvent::ManualResetEvent (bool sig)
-    : mtx (log4cplus::thread::Mutex::DEFAULT)
-    , sigcount (0)
-    , signaled (sig)
-{
-    int ret = pthread_cond_init (&cv, 0);
-    if (LOG4CPLUS_UNLIKELY (ret != 0))
-        LOG4CPLUS_THROW_RTE ("ManualResetEvent::ManualResetEvent");
-}
-
-
-inline
-ManualResetEvent::~ManualResetEvent ()
-{
-    try
-    {
-        int ret = pthread_cond_destroy (&cv);
-        if (LOG4CPLUS_UNLIKELY (ret != 0))
-            LOG4CPLUS_THROW_RTE ("ManualResetEvent::~ManualResetEvent");
-    }
-    catch (...)
-    { }
-}
-
-
-inline
-void
-ManualResetEvent::signal () const
-{
-    MutexGuard mguard (mtx);
-
-    signaled = true;
-    sigcount += 1;
-    int ret = pthread_cond_broadcast (&cv);
-    if (LOG4CPLUS_UNLIKELY (ret != 0))
-        LOG4CPLUS_THROW_RTE ("ManualResetEvent::signal");
-
-}
-
-
-inline
-void
-ManualResetEvent::wait () const
-{
-    MutexGuard mguard (mtx);
-
-    if (! signaled)
-    {
-        unsigned prev_count = sigcount;
-        do
-        {
-            int ret = pthread_cond_wait (&cv, &mtx.mtx);
-            if (LOG4CPLUS_UNLIKELY (ret != 0))
-            {
-                mguard.unlock ();
-                mguard.detach ();
-                LOG4CPLUS_THROW_RTE ("ManualResetEvent::wait");
-            }
-        }
-        while (prev_count == sigcount);
-    }
-}
-
-
-inline
-bool
-ManualResetEvent::timed_wait (unsigned long msec) const
-{
-    MutexGuard mguard (mtx);
-
-    if (! signaled)
-    {
-        helpers::Time const wakeup_time (helpers::Time::gettimeofday ()
-            + helpers::Time (msec / 1000, (msec % 1000) * 1000));
-        struct timespec const ts = {wakeup_time.sec (),
-            wakeup_time.usec () * 1000};
-        unsigned prev_count = sigcount;
-        do
-        {
-            int ret = pthread_cond_timedwait (&cv, &mtx.mtx, &ts);
-            switch (ret)
-            {
-            case 0:
-                break;
-
-            case ETIMEDOUT:
-                return false;
-
-            default:
-                mguard.unlock ();
-                mguard.detach ();
-                LOG4CPLUS_THROW_RTE ("ManualResetEvent::timed_wait");
-            }
-        }
-        while (prev_count == sigcount);
-    }
-
-    return true;
-}
-
-
-inline
-void
-ManualResetEvent::reset () const
-{
-    MutexGuard mguard (mtx);
-
-    signaled = false;
-}
-
-
-//
-//
-//
-
-#if defined (LOG4CPLUS_POOR_MANS_SHAREDMUTEX)
-#include "log4cplus/thread/impl/syncprims-pmsm.h"
-
-#else
-inline
-SharedMutex::SharedMutex ()
-{
-    int ret = pthread_rwlock_init (&rwl, 0);
-    if (LOG4CPLUS_UNLIKELY (ret != 0))
-        LOG4CPLUS_THROW_RTE ("SharedMutex::SharedMutex");
-}
-
-
-inline
-SharedMutex::~SharedMutex ()
-{
-    try
-    {
-        int ret = pthread_rwlock_destroy (&rwl);
-        if (LOG4CPLUS_UNLIKELY (ret != 0))
-            LOG4CPLUS_THROW_RTE ("SharedMutex::~SharedMutex");
-    }
-    catch (...)
-    { }
-}
-
-
-inline
-void
-SharedMutex::rdlock () const
-{
-    int ret;
-
-    do
-    {
-        ret = pthread_rwlock_rdlock (&rwl);
-        switch (ret)
-        {
-        case EAGAIN:
-            // The read lock could not be acquired because the maximum
-            // number of read locks for rwlock has been exceeded.
-
-            log4cplus::thread::yield ();
-            // Fall through.
-
-        case 0:
-            break;
-
-        default:
-            LOG4CPLUS_THROW_RTE ("SharedMutex::rdlock");
-
-        }
-    }
-    while (LOG4CPLUS_UNLIKELY (ret != 0));
-}
-
-
-inline
-void
-SharedMutex::rdunlock () const
-{
-    unlock ();
-}
-
-
-inline
-void
-SharedMutex::wrlock () const
-{
-    int ret = pthread_rwlock_wrlock (&rwl);
-    if (LOG4CPLUS_UNLIKELY (ret != 0))
-        LOG4CPLUS_THROW_RTE ("SharedMutex::wrlock");
-}
-
-
-inline
-void
-SharedMutex::wrunlock () const
-{
-    unlock ();
-}
-
-
-inline
-void
-SharedMutex::unlock () const
-{
-    int ret = pthread_rwlock_unlock (&rwl);
-    if (LOG4CPLUS_UNLIKELY (ret != 0))
-        LOG4CPLUS_THROW_RTE ("SharedMutex::unlock");
-
-}
-
-
-#endif
-
-
-} } } // namespace log4cplus { namespace thread { namespace impl {

+ 0 - 328
include/log4cplus/thread/impl/syncprims-win32.h

@@ -1,328 +0,0 @@
-// -*- C++ -*-
-//  Copyright (C) 2009-2015, Vaclav Haisman. All rights reserved.
-//  
-//  Redistribution and use in source and binary forms, with or without modifica-
-//  tion, are permitted provided that the following conditions are met:
-//  
-//  1. Redistributions of  source code must  retain the above copyright  notice,
-//     this list of conditions and the following disclaimer.
-//  
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  
-//  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
-//  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-//  FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
-//  APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
-//  INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
-//  DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
-//  OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
-//  ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
-//  (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
-//  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-//! @file
-//! This file contains implementations of synchronization
-//! primitives using the Win32 API. It does not contain any include
-//! guards because it is only a fragment to be included by
-//! syncprims.h.
-
-#include <stdexcept>
-
-
-namespace log4cplus { namespace thread { namespace impl {
-
-
-//
-//
-//
-
-inline
-bool
-InitializeCriticalSection_wrapInternal (LPCRITICAL_SECTION cs)
-{
-#if defined (_MSC_VER)
-    __try
-    {
-#endif
-
-    InitializeCriticalSection (cs);
-
-#if defined (_MSC_VER)
-    }
-    __except (GetExceptionCode() == STATUS_NO_MEMORY
-        ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
-    {
-        return false;
-    }
-#endif
-
-    return true;
-}
-
-
-inline
-void
-InitializeCriticalSection_wrap (LPCRITICAL_SECTION cs)
-{
-    if (! InitializeCriticalSection_wrapInternal (cs))
-        throw std::runtime_error (
-            "InitializeCriticalSection: STATUS_NO_MEMORY");
-}
-
-
-inline
-Mutex::Mutex (log4cplus::thread::Mutex::Type)
-{
-    InitializeCriticalSection_wrap (&cs);
-}
-
-
-inline
-Mutex::~Mutex ()
-{
-    DeleteCriticalSection (&cs);
-}
-
-
-inline
-void
-Mutex::lock () const
-{
-    EnterCriticalSection (&cs);
-}
-
-
-inline
-void
-Mutex::unlock () const
-{
-    LeaveCriticalSection (&cs);
-}
-
-
-//
-//
-//
-
-inline
-Semaphore::Semaphore (unsigned max, unsigned initial)
-{
-    sem = CreateSemaphore (0, initial, max, 0);
-    if (! sem)
-        LOG4CPLUS_THROW_RTE ("Semaphore::Semaphore");
-}
-
-
-inline
-Semaphore::~Semaphore ()
-{
-    try
-    {
-        if (! CloseHandle (sem))
-            LOG4CPLUS_THROW_RTE ("Semaphore::~Semaphore");
-    }
-    catch (...)
-    { }
-}
-
-
-inline
-void
-Semaphore::unlock () const
-{
-    DWORD ret = ReleaseSemaphore (sem, 1, 0);
-    if (! ret)
-         LOG4CPLUS_THROW_RTE ("Semaphore::unlock");
-}
-
-
-inline
-void
-Semaphore::lock () const
-{
-    DWORD ret = WaitForSingleObject (sem, INFINITE);
-    if (ret != WAIT_OBJECT_0)
-        LOG4CPLUS_THROW_RTE ("Semaphore::lock");
-}
-
-
-//
-//
-//
-
-
-inline
-FairMutex::FairMutex ()
-{
-    mtx = CreateMutex (0, false, 0);
-    if (! mtx)
-        LOG4CPLUS_THROW_RTE ("FairMutex::FairMutex");
-}
-
-
-inline
-FairMutex::~FairMutex ()
-{
-    try
-    {
-        if (! CloseHandle (mtx))
-            LOG4CPLUS_THROW_RTE ("FairMutex::~FairMutex");
-    }
-    catch (...)
-    { }
-}
-
-
-inline
-void
-FairMutex::lock () const
-{
-    DWORD ret = WaitForSingleObject (mtx, INFINITE);
-    if (ret != WAIT_OBJECT_0)
-        LOG4CPLUS_THROW_RTE ("FairMutex::lock");
-}
-
-
-inline
-void
-FairMutex::unlock () const
-{
-    if (! ReleaseMutex (mtx))
-        LOG4CPLUS_THROW_RTE ("FairMutex::unlock");
-}
-
-
-//
-//
-//
-
-inline
-ManualResetEvent::ManualResetEvent (bool sig)
-{
-    ev = CreateEvent (0, true, sig, 0);
-    if (! ev)
-        LOG4CPLUS_THROW_RTE ("ManualResetEvent::ManualResetEvent");
-}
-
-
-inline
-ManualResetEvent::~ManualResetEvent ()
-{
-    try
-    {
-        if (! CloseHandle (ev))
-            LOG4CPLUS_THROW_RTE ("ManualResetEvent::~ManualResetEvent");
-    }
-    catch (...)
-    { }
-}
-
-
-inline
-void
-ManualResetEvent::signal () const
-{
-    if (! SetEvent (ev))
-        LOG4CPLUS_THROW_RTE ("ManualResetEVent::signal");
-}
-
-
-inline
-void
-ManualResetEvent::wait () const
-{
-    DWORD ret = WaitForSingleObject (ev, INFINITE);
-    if (ret != WAIT_OBJECT_0)
-        LOG4CPLUS_THROW_RTE ("ManualResetEvent::wait");
-}
-
-
-inline
-bool
-ManualResetEvent::timed_wait (unsigned long msec) const
-{
-    DWORD ret = WaitForSingleObject (ev, static_cast<DWORD>(msec));
-    switch(ret)
-    {
-    case WAIT_OBJECT_0:
-        return true;
-
-    case WAIT_TIMEOUT:
-        return false;
-
-    default:
-        LOG4CPLUS_THROW_RTE ("ManualResetEvent::timed_wait");
-        // Silence warnings about not returning any value from function
-        // returning bool.
-        return false;
-    }
-}
-
-
-inline
-void
-ManualResetEvent::reset () const
-{
-    if (! ResetEvent (ev))
-        LOG4CPLUS_THROW_RTE ("ManualResetEvent::reset");
-}
-
-
-//
-//
-//
-
-#if defined (LOG4CPLUS_POOR_MANS_SHAREDMUTEX)
-#include "log4cplus/thread/impl/syncprims-pmsm.h"
-
-#else
-inline
-SharedMutex::SharedMutex ()
-{
-    InitializeSRWLock (&srwl);
-}
-
-
-inline
-SharedMutex::~SharedMutex ()
-{ }
-
-
-inline
-void
-SharedMutex::rdlock () const
-{
-    AcquireSRWLockShared (&srwl);
-}
-
-
-inline
-void
-SharedMutex::rdunlock () const
-{
-    ReleaseSRWLockShared (&srwl);
-}
-
-
-inline
-void
-SharedMutex::wrlock () const
-{
-    AcquireSRWLockExclusive (&srwl);
-}
-
-
-inline
-void
-SharedMutex::wrunlock () const
-{
-    ReleaseSRWLockExclusive (&srwl);
-}
-
-
-#endif
-
-
-} } } // namespace log4cplus { namespace thread { namespace impl {

+ 1 - 65
include/log4cplus/thread/impl/threads-impl.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2001-2015 Tad E. Smith
+// Copyright 2001-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -90,70 +90,6 @@ getCurrentThreadId ()
 #endif
 
 
-#ifndef LOG4CPLUS_SINGLE_THREADED
-
-
-struct ThreadStart
-{
-#  ifdef LOG4CPLUS_USE_PTHREADS
-static void* threadStartFuncWorker(void *);
-#  elif defined(LOG4CPLUS_USE_WIN32_THREADS)
-static unsigned threadStartFuncWorker(void *);
-#  endif
-};
-
-
-/**
- * There are many cross-platform C++ Threading libraries.  The goal of
- * this class is not to replace (or match in functionality) those
- * libraries.  The goal of this class is to provide a simple Threading
- * class with basic functionality.
- */
-class Thread
-    : public ThreadImplBase
-{
-public:
-    Thread();
-    bool isRunning() const;
-    os_id_type getThreadId() const;
-    os_handle_type getThreadHandle () const;
-    void start();
-    void join ();
-
-protected:
-    // Force objects to be constructed on the heap
-    virtual ~Thread();
-    virtual void run() = 0;
-
-private:
-    // Friends.
-    friend struct ThreadStart;
-
-    enum Flags
-    {
-        fRUNNING  = 0x01,
-        fJOINED   = 0x02
-    };
-
-    unsigned flags;
-
-    os_handle_type handle;
-
-#  if defined(LOG4CPLUS_USE_WIN32_THREADS)
-    unsigned thread_id;
-#  endif
-
-    // Disallow copying of instances of this class.
-    Thread(const Thread&);
-    Thread& operator=(const Thread&);
-};
-
-typedef helpers::SharedObjectPtr<Thread> ThreadPtr;
-
-
-#endif // LOG4CPLUS_SINGLE_THREADED
-
-
 } } } // namespace log4cplus { namespace thread { namespace impl {
 
 

+ 21 - 8
include/log4cplus/thread/impl/tls.h

@@ -1,5 +1,5 @@
 // -*- C++ -*-
-//  Copyright (C) 2010-2015, Vaclav Haisman. All rights reserved.
+//  Copyright (C) 2010-2017, Vaclav Haisman. All rights reserved.
 //  
 //  Redistribution and use in source and binary forms, with or without modifica-
 //  tion, are permitted provided that the following conditions are met:
@@ -33,6 +33,7 @@
 
 #include <new>
 #include <cassert>
+#include <system_error>
 
 #if ! defined (INSIDE_LOG4CPLUS)
 #  error "This header must not be be used outside log4cplus' implementation files."
@@ -54,16 +55,18 @@ namespace log4cplus { namespace thread { namespace impl {
 
 
 typedef void * tls_value_type;
-typedef void (* tls_init_cleanup_func_type)(void *);
 
 #ifdef LOG4CPLUS_USE_PTHREADS
 typedef pthread_key_t * tls_key_type;
+typedef void (* tls_init_cleanup_func_type)(void *);
 
 #elif defined (LOG4CPLUS_USE_WIN32_THREADS)
 typedef DWORD tls_key_type;
+typedef PFLS_CALLBACK_FUNCTION tls_init_cleanup_func_type;
 
 #elif defined (LOG4CPLUS_SINGLE_THREADED)
 typedef std::size_t tls_key_type;
+typedef void (* tls_init_cleanup_func_type)(void *);
 
 #endif
 
@@ -79,7 +82,10 @@ tls_key_type
 tls_init (tls_init_cleanup_func_type cleanupfunc)
 {
     pthread_key_t * key = new pthread_key_t;
-    pthread_key_create (key, cleanupfunc);
+    int ret = pthread_key_create (key, cleanupfunc);
+    if (LOG4CPLUS_UNLIKELY (ret != 0))
+        throw std::system_error(ret, std::system_category (),
+            "pthread_key_create() failed");
     return key;
 }
 
@@ -108,29 +114,36 @@ tls_cleanup (tls_key_type key)
 
 #elif defined (LOG4CPLUS_USE_WIN32_THREADS)
 tls_key_type
-tls_init (tls_init_cleanup_func_type)
+tls_init (tls_init_cleanup_func_type cleanupfunc)
 {
-    return TlsAlloc ();
+    DWORD const slot = FlsAlloc (cleanupfunc);
+    if (LOG4CPLUS_UNLIKELY (slot == FLS_OUT_OF_INDEXES))
+    {
+        DWORD const eno = GetLastError ();
+        throw std::system_error (static_cast<int>(eno),
+            std::system_category (), "FlsAlloc() failed");
+    }
+    return slot;
 }
 
 
 tls_value_type tls_get_value (tls_key_type k)
 {
-    return TlsGetValue (k);
+    return FlsGetValue (k);
 }
 
 
 void
 tls_set_value (tls_key_type k, tls_value_type value)
 {
-    TlsSetValue (k, value);
+    FlsSetValue (k, value);
 }
 
 
 void
 tls_cleanup (tls_key_type k)
 {
-    TlsFree (k);
+    FlsFree (k);
 }
 
 

+ 133 - 80
include/log4cplus/thread/syncprims-pub-impl.h

@@ -1,5 +1,5 @@
 // -*- C++ -*-
-//  Copyright (C) 2010-2015, Vaclav Haisman. All rights reserved.
+//  Copyright (C) 2010-2017, Vaclav Haisman. All rights reserved.
 //
 //  Redistribution and use in source and binary forms, with or without modifica-
 //  tion, are permitted provided that the following conditions are met:
@@ -31,64 +31,71 @@
 #pragma once
 #endif
 
+#include <algorithm>
+
 #if (defined (LOG4CPLUS_INLINES_ARE_EXPORTED)           \
     && defined (LOG4CPLUS_BUILD_DLL))                   \
     || defined (LOG4CPLUS_ENABLE_SYNCPRIMS_PUB_IMPL)
 #include <log4cplus/thread/syncprims.h>
 
-#if defined (LOG4CPLUS_SINGLE_THREADED)
-#  define LOG4CPLUS_THREADED(x)
-#  define LOG4CPLUS_THREADED2(x, y) (y)
-#else
+#if ! defined (LOG4CPLUS_SINGLE_THREADED)
 #  include <log4cplus/thread/impl/syncprims-impl.h>
-#  define LOG4CPLUS_THREADED(x) (x)
-#  define LOG4CPLUS_THREADED2(x, y) (x)
 #endif
 
+#define LOG4CPLUS_THROW_RTE(msg) \
+    do { log4cplus::thread::impl::syncprims_throw_exception (msg, __FILE__, \
+            __LINE__); } while (0)
 
 namespace log4cplus { namespace thread {
 
+namespace impl
+{
+
+LOG4CPLUS_EXPORT void LOG4CPLUS_ATTRIBUTE_NORETURN
+    syncprims_throw_exception(char const * const msg,
+    char const * const file, int line);
+
+}
 
 //
 //
 //
 
 LOG4CPLUS_INLINE_EXPORT
-MutexImplBase::~MutexImplBase ()
+SimpleMutex::SimpleMutex ()
+    LOG4CPLUS_THREADED (: mtx ())
 { }
 
 
-//
-//
-//
-
 LOG4CPLUS_INLINE_EXPORT
-Mutex::Mutex (Mutex::Type LOG4CPLUS_THREADED (t))
-    : mtx (LOG4CPLUS_THREADED2 (new impl::Mutex (t),
-            static_cast<MutexImplBase *>(0)))
+SimpleMutex::~SimpleMutex ()
 { }
 
 
 LOG4CPLUS_INLINE_EXPORT
-Mutex::~Mutex ()
+void
+SimpleMutex::lock () const
 {
-    LOG4CPLUS_THREADED (delete static_cast<impl::Mutex *>(mtx));
+    LOG4CPLUS_THREADED (mtx.lock ());
 }
 
-
 LOG4CPLUS_INLINE_EXPORT
-void
-Mutex::lock () const
+bool
+SimpleMutex::try_lock () const
 {
-    LOG4CPLUS_THREADED (static_cast<impl::Mutex *>(mtx)->lock ());
+#if defined (LOG4CPLUS_SINGLE_THREADED)
+    return true;
+#else
+    return mtx.try_lock ();
+#endif
 }
 
 
 LOG4CPLUS_INLINE_EXPORT
 void
-Mutex::unlock () const
+SimpleMutex::unlock () const
 {
-    LOG4CPLUS_THREADED (static_cast<impl::Mutex *>(mtx)->unlock ());
+    LOG4CPLUS_THREADED (mtx.unlock ());
 }
 
 
@@ -97,42 +104,29 @@ Mutex::unlock () const
 //
 
 LOG4CPLUS_INLINE_EXPORT
-SemaphoreImplBase::~SemaphoreImplBase ()
+Mutex::Mutex ()
+    LOG4CPLUS_THREADED (: mtx ())
 { }
 
 
-//
-//
-//
-
 LOG4CPLUS_INLINE_EXPORT
-Semaphore::Semaphore (unsigned LOG4CPLUS_THREADED (max),
-    unsigned LOG4CPLUS_THREADED (initial))
-    : sem (LOG4CPLUS_THREADED2 (new impl::Semaphore (max, initial),
-            static_cast<SemaphoreImplBase *>(0)))
+Mutex::~Mutex ()
 { }
 
 
-LOG4CPLUS_INLINE_EXPORT
-Semaphore::~Semaphore ()
-{
-    LOG4CPLUS_THREADED (delete static_cast<impl::Semaphore *>(sem));
-}
-
-
 LOG4CPLUS_INLINE_EXPORT
 void
-Semaphore::lock () const
+Mutex::lock () const
 {
-    LOG4CPLUS_THREADED (static_cast<impl::Semaphore *>(sem)->lock ());
+    LOG4CPLUS_THREADED (mtx.lock ());
 }
 
 
 LOG4CPLUS_INLINE_EXPORT
 void
-Semaphore::unlock () const
+Mutex::unlock () const
 {
-    LOG4CPLUS_THREADED (static_cast<impl::Semaphore *>(sem)->unlock ());
+    LOG4CPLUS_THREADED (mtx.unlock ());
 }
 
 
@@ -141,51 +135,55 @@ Semaphore::unlock () const
 //
 
 LOG4CPLUS_INLINE_EXPORT
-FairMutexImplBase::~FairMutexImplBase ()
+Semaphore::Semaphore (unsigned LOG4CPLUS_THREADED (max_),
+    unsigned LOG4CPLUS_THREADED (initial))
+#if ! defined (LOG4CPLUS_SINGLE_THREADED)
+    : maximum(max_)
+    , val ((std::min) (maximum, initial))
+#endif
 { }
 
 
-//
-//
-//
-
 LOG4CPLUS_INLINE_EXPORT
-FairMutex::FairMutex ()
-    : mtx (LOG4CPLUS_THREADED2 (new impl::FairMutex,
-            static_cast<FairMutexImplBase *>(0)))
+Semaphore::~Semaphore ()
 { }
 
 
 LOG4CPLUS_INLINE_EXPORT
-FairMutex::~FairMutex ()
+void
+Semaphore::unlock () const
 {
-    LOG4CPLUS_THREADED (delete static_cast<impl::FairMutex *>(mtx));
-}
+#if ! defined (LOG4CPLUS_SINGLE_THREADED)
+    std::lock_guard<std::mutex> guard (mtx);
 
+    if (val >= maximum)
+        LOG4CPLUS_THROW_RTE ("Semaphore::unlock(): val >= max");
 
-LOG4CPLUS_INLINE_EXPORT
-void
-FairMutex::lock () const
-{
-    LOG4CPLUS_THREADED (static_cast<impl::FairMutex *>(mtx)->lock ());
+    ++val;
+    cv.notify_all ();
+#endif
 }
 
 
 LOG4CPLUS_INLINE_EXPORT
 void
-FairMutex::unlock () const
+Semaphore::lock () const
 {
-    LOG4CPLUS_THREADED (static_cast<impl::FairMutex *>(mtx)->unlock ());
-}
+#if ! defined (LOG4CPLUS_SINGLE_THREADED)
+    std::unique_lock<std::mutex> guard (mtx);
 
+    if (LOG4CPLUS_UNLIKELY(val > maximum))
+        LOG4CPLUS_THROW_RTE ("Semaphore::unlock(): val > max");
 
-//
-//
-//
+    while (val == 0)
+        cv.wait (guard);
 
-LOG4CPLUS_INLINE_EXPORT
-ManualResetEventImplBase::~ManualResetEventImplBase ()
-{ }
+    --val;
+
+    if (LOG4CPLUS_UNLIKELY(val >= maximum))
+        LOG4CPLUS_THROW_RTE ("Semaphore::unlock(): val >= max");
+#endif
+}
 
 
 //
@@ -194,23 +192,29 @@ ManualResetEventImplBase::~ManualResetEventImplBase ()
 
 LOG4CPLUS_INLINE_EXPORT
 ManualResetEvent::ManualResetEvent (bool LOG4CPLUS_THREADED (sig))
-    : ev (LOG4CPLUS_THREADED2 (new impl::ManualResetEvent (sig),
-            static_cast<ManualResetEventImplBase *>(0)))
+#if ! defined (LOG4CPLUS_SINGLE_THREADED)
+    : signaled (sig)
+    , sigcount (0)
+#endif
 { }
 
 
 LOG4CPLUS_INLINE_EXPORT
 ManualResetEvent::~ManualResetEvent ()
-{
-    LOG4CPLUS_THREADED (delete static_cast<impl::ManualResetEvent *>(ev));
-}
+{ }
 
 
 LOG4CPLUS_INLINE_EXPORT
 void
 ManualResetEvent::signal () const
 {
-    LOG4CPLUS_THREADED (static_cast<impl::ManualResetEvent *>(ev)->signal ());
+#if ! defined (LOG4CPLUS_SINGLE_THREADED)
+    std::unique_lock<std::mutex> guard (mtx);
+
+    signaled = true;
+    sigcount += 1;
+    cv.notify_all ();
+#endif
 }
 
 
@@ -218,7 +222,19 @@ LOG4CPLUS_INLINE_EXPORT
 void
 ManualResetEvent::wait () const
 {
-    LOG4CPLUS_THREADED (static_cast<impl::ManualResetEvent *>(ev)->wait ());
+#if ! defined (LOG4CPLUS_SINGLE_THREADED)
+    std::unique_lock<std::mutex> guard (mtx);
+
+    if (! signaled)
+    {
+        unsigned prev_count = sigcount;
+        do
+        {
+            cv.wait (guard);
+        }
+        while (prev_count == sigcount);
+    }
+#endif
 }
 
 
@@ -228,8 +244,40 @@ ManualResetEvent::timed_wait (unsigned long LOG4CPLUS_THREADED (msec)) const
 {
 #if defined (LOG4CPLUS_SINGLE_THREADED)
     return true;
+
 #else
-    return static_cast<impl::ManualResetEvent *>(ev)->timed_wait (msec);
+    std::unique_lock<std::mutex> guard (mtx);
+
+    if (! signaled)
+    {
+        unsigned prev_count = sigcount;
+
+        std::chrono::steady_clock::time_point const wait_until_time
+            = std::chrono::steady_clock::now ()
+            + std::chrono::milliseconds (msec);
+
+        do
+        {
+            int ret = static_cast<int>(
+                cv.wait_until (guard, wait_until_time));
+            switch (ret)
+            {
+            case static_cast<int>(std::cv_status::no_timeout):
+                break;
+
+            case static_cast<int>(std::cv_status::timeout):
+                return false;
+
+            default:
+                guard.unlock ();
+                guard.release ();
+                LOG4CPLUS_THROW_RTE ("ManualResetEvent::timed_wait");
+            }
+        }
+        while (prev_count == sigcount);
+    }
+
+    return true;
 #endif
 }
 
@@ -238,7 +286,11 @@ LOG4CPLUS_INLINE_EXPORT
 void
 ManualResetEvent::reset () const
 {
-    LOG4CPLUS_THREADED (static_cast<impl::ManualResetEvent *>(ev)->reset ());
+#if ! defined (LOG4CPLUS_SINGLE_THREADED)
+    std::lock_guard<std::mutex> guard (mtx);
+
+    signaled = false;
+#endif
 }
 
 
@@ -257,14 +309,15 @@ SharedMutexImplBase::~SharedMutexImplBase ()
 
 LOG4CPLUS_INLINE_EXPORT
 SharedMutex::SharedMutex ()
-    : sm (LOG4CPLUS_THREADED2 (new impl::SharedMutex,
-            static_cast<SharedMutexImplBase *>(0)))
+    : sm (LOG4CPLUS_THREADED (new impl::SharedMutex))
 { }
 
 
 LOG4CPLUS_INLINE_EXPORT
 SharedMutex::~SharedMutex ()
-{ }
+{
+    LOG4CPLUS_THREADED (delete static_cast<impl::SharedMutex *>(sm));
+}
 
 
 LOG4CPLUS_INLINE_EXPORT

+ 47 - 75
include/log4cplus/thread/syncprims.h

@@ -1,16 +1,16 @@
 // -*- C++ -*-
-//  Copyright (C) 2010-2015, Vaclav Haisman. All rights reserved.
-//  
+//  Copyright (C) 2010-2017, Vaclav Haisman. All rights reserved.
+//
 //  Redistribution and use in source and binary forms, with or without modifica-
 //  tion, are permitted provided that the following conditions are met:
-//  
+//
 //  1. Redistributions of  source code must  retain the above copyright  notice,
 //     this list of conditions and the following disclaimer.
-//  
+//
 //  2. Redistributions in binary form must reproduce the above copyright notice,
 //     this list of conditions and the following disclaimer in the documentation
 //     and/or other materials provided with the distribution.
-//  
+//
 //  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 //  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 //  FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
@@ -31,6 +31,9 @@
 #pragma once
 #endif
 
+#include <mutex>
+#include <condition_variable>
+
 
 namespace log4cplus { namespace thread {
 
@@ -42,6 +45,8 @@ public:
     SyncGuard ();
     SyncGuard (SyncPrim const &);
     ~SyncGuard ();
+    SyncGuard (SyncGuard const &) = delete;
+    SyncGuard & operator = (SyncGuard const &) = delete;
 
     void lock ();
     void unlock ();
@@ -51,114 +56,79 @@ public:
 
 private:
     SyncPrim const * sp;
-
-    SyncGuard (SyncGuard const &);
-    SyncGuard & operator = (SyncGuard const &);
 };
 
 
-class ManualResetEvent;
-
-
-class MutexImplBase
-{
-protected:
-    ~MutexImplBase ();
-};
-
-
-class LOG4CPLUS_EXPORT Mutex
+class LOG4CPLUS_EXPORT SimpleMutex
 {
 public:
-    enum Type
-    {
-        DEFAULT,
-        RECURSIVE
-    };
-
-    explicit Mutex (Type = RECURSIVE);
-    ~Mutex ();
+    SimpleMutex ();
+    ~SimpleMutex ();
+    SimpleMutex (SimpleMutex const &) = delete;
+    SimpleMutex & operator = (SimpleMutex const &) = delete;
 
     void lock () const;
+    bool try_lock () const;
     void unlock () const;
 
 private:
-    MutexImplBase * mtx;
-
-    Mutex (Mutex const &);
-    Mutex & operator = (Mutex &);
+    LOG4CPLUS_THREADED (mutable std::mutex mtx;)
 };
 
 
-typedef SyncGuard<Mutex> MutexGuard;
-
-
-class SemaphoreImplBase
-{
-protected:
-    ~SemaphoreImplBase ();
-};
+typedef SyncGuard<SimpleMutex> SimpleMutexGuard;
 
 
-class LOG4CPLUS_EXPORT Semaphore
+class LOG4CPLUS_EXPORT Mutex
 {
 public:
-    Semaphore (unsigned max, unsigned initial);
-    ~Semaphore ();
+    Mutex ();
+    ~Mutex ();
+    Mutex (Mutex const &) = delete;
+    Mutex & operator = (Mutex const &) = delete;
 
     void lock () const;
     void unlock () const;
 
 private:
-    SemaphoreImplBase * sem;
-
-    Semaphore (Semaphore const &);
-    Semaphore & operator = (Semaphore const &);
+    LOG4CPLUS_THREADED (mutable std::recursive_mutex mtx;)
 };
 
 
-typedef SyncGuard<Semaphore> SemaphoreGuard;
-
-
-class FairMutexImplBase
-{
-protected:
-    ~FairMutexImplBase ();
-};
+typedef SyncGuard<Mutex> MutexGuard;
 
 
-class LOG4CPLUS_EXPORT FairMutex
+class LOG4CPLUS_EXPORT Semaphore
 {
 public:
-    FairMutex ();
-    ~FairMutex ();
+    Semaphore (unsigned max, unsigned initial);
+    ~Semaphore ();
+    Semaphore (Semaphore const &) = delete;
+    Semaphore & operator = (Semaphore const &) = delete;
 
     void lock () const;
     void unlock () const;
 
 private:
-    FairMutexImplBase * mtx;
-
-    FairMutex (FairMutex const &);
-    FairMutex & operator = (FairMutex &);
+#if ! defined (LOG4CPLUS_SINGLE_THREADED)
+    mutable std::mutex mtx;
+    mutable std::condition_variable cv;
+    mutable unsigned maximum;
+    mutable unsigned val;
+#endif
 };
 
 
-typedef SyncGuard<FairMutex> FairMutexGuard;
-
-
-class ManualResetEventImplBase
-{
-protected:
-    ~ManualResetEventImplBase ();
-};
+typedef SyncGuard<Semaphore> SemaphoreGuard;
 
 
 class LOG4CPLUS_EXPORT ManualResetEvent
 {
 public:
-    ManualResetEvent (bool = false);
+    explicit ManualResetEvent (bool = false);
     ~ManualResetEvent ();
+    ManualResetEvent (ManualResetEvent const &) = delete;
+    ManualResetEvent & operator = (ManualResetEvent const &) = delete;
 
     void signal () const;
     void wait () const;
@@ -166,10 +136,12 @@ public:
     void reset () const;
 
 private:
-    ManualResetEventImplBase * ev;
-
-    ManualResetEvent (ManualResetEvent const &);
-    ManualResetEvent & operator = (ManualResetEvent const &);
+#if ! defined (LOG4CPLUS_SINGLE_THREADED)
+    mutable std::mutex mtx;
+    mutable std::condition_variable cv;
+    mutable bool signaled;
+    mutable unsigned sigcount;
+#endif
 };
 
 
@@ -376,7 +348,7 @@ SyncGuardFunc<SyncPrim, lock_func, unlock_func>::detach ()
 }
 
 
-} } // namespace log4cplus { namespace thread { 
+} } // namespace log4cplus { namespace thread {
 
 
 #endif // LOG4CPLUS_THREAD_SYNCPRIMS_H

+ 31 - 14
include/log4cplus/thread/threads.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2001-2015 Tad E. Smith
+// Copyright 2001-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -30,6 +30,9 @@
 #pragma once
 #endif
 
+#include <memory>
+#include <thread>
+
 #include <log4cplus/tstring.h>
 #include <log4cplus/helpers/pointer.h>
 
@@ -44,17 +47,25 @@ LOG4CPLUS_EXPORT void setCurrentThreadName2(const log4cplus::tstring & name);
 LOG4CPLUS_EXPORT void yield();
 LOG4CPLUS_EXPORT void blockAllSignals();
 
-
-#ifndef LOG4CPLUS_SINGLE_THREADED
-
-class ThreadImplBase
-    : public virtual log4cplus::helpers::SharedObject
+/**
+ * This class blocks all POSIX signals when created and unblocks them when
+ * destroyed.
+ */
+class LOG4CPLUS_EXPORT SignalsBlocker
 {
-protected:
-    virtual ~ThreadImplBase ();
+public:
+    SignalsBlocker();
+    ~SignalsBlocker();
+
+private:
+    struct SignalsBlockerImpl;
+    std::unique_ptr<SignalsBlockerImpl> impl;
 };
 
 
+#ifndef LOG4CPLUS_SINGLE_THREADED
+
+
 /**
  * There are many cross-platform C++ Threading libraries.  The goal of
  * this class is not to replace (or match in functionality) those
@@ -66,6 +77,10 @@ class LOG4CPLUS_EXPORT AbstractThread
 {
 public:
     AbstractThread();
+    // Disallow copying of instances of this class.
+    AbstractThread(const AbstractThread&) = delete;
+    AbstractThread& operator=(const AbstractThread&) = delete;
+
     bool isRunning() const;
     virtual void start();
     void join () const;
@@ -76,11 +91,14 @@ protected:
     virtual ~AbstractThread();
 
 private:
-    helpers::SharedObjectPtr<ThreadImplBase> thread;
-
-    // Disallow copying of instances of this class.
-    AbstractThread(const AbstractThread&);
-    AbstractThread& operator=(const AbstractThread&);
+    enum Flags
+    {
+        fRUNNING = 1,
+        fJOINED = 2
+    };
+
+    std::unique_ptr<std::thread> thread;
+    mutable std::atomic<int> flags;
 };
 
 typedef helpers::SharedObjectPtr<AbstractThread> AbstractThreadPtr;
@@ -93,4 +111,3 @@ typedef helpers::SharedObjectPtr<AbstractThread> AbstractThreadPtr;
 
 
 #endif // LOG4CPLUS_THREADS_HEADER_
-

+ 7 - 6
include/log4cplus/tracelogger.h

@@ -5,7 +5,7 @@
 // Author:  Vaclav Haisman
 //
 //
-// Copyright 2009-2015 Tad E. Smith
+// Copyright 2009-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -50,22 +50,23 @@ namespace log4cplus
 class TraceLogger
 {
 public:
-    TraceLogger(const Logger& l, const log4cplus::tstring& _msg,
+    TraceLogger(Logger l, log4cplus::tstring _msg,
         const char* _file = LOG4CPLUS_CALLER_FILE (),
         int _line = LOG4CPLUS_CALLER_LINE (),
-        char const * _function = LOG4CPLUS_CALLER_FUNCTION ()) 
-        : logger(l), msg(_msg), file(_file), function(_function), line(_line)
+        char const * _function = LOG4CPLUS_CALLER_FUNCTION ())
+        : logger(std::move (l)), msg(std::move (_msg)), file(_file),
+          function(_function), line(_line)
     {
         if(logger.isEnabledFor(TRACE_LOG_LEVEL))
             logger.forcedLog(TRACE_LOG_LEVEL, LOG4CPLUS_TEXT("ENTER: ") + msg,
-                file, line, function); 
+                file, line, function);
     }
 
     ~TraceLogger()
     {
         if(logger.isEnabledFor(TRACE_LOG_LEVEL))
             logger.forcedLog(TRACE_LOG_LEVEL, LOG4CPLUS_TEXT("EXIT:  ") + msg,
-                file, line, function); 
+                file, line, function);
     }
 
 private:

+ 3 - 9
include/log4cplus/tstring.h

@@ -5,7 +5,7 @@
 // Author:  Tad E. Smith
 //
 //
-// Copyright 2003-2015 Tad E. Smith
+// Copyright 2003-2017 Tad E. Smith
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -63,7 +63,6 @@ tostring (std::string & str)
     return str;
 }
 
-#ifdef LOG4CPLUS_HAVE_RVALUE_REFS
 inline
 std::string
 tostring (std::string && str)
@@ -71,9 +70,6 @@ tostring (std::string && str)
     return std::move (str);
 }
 
-#endif
-
-
 
 inline
 std::wstring
@@ -90,21 +86,19 @@ towstring (std::wstring const & str)
 }
 
 inline
-std::wstring const & 
+std::wstring const &
 towstring (std::wstring & str)
 {
     return str;
 }
 
-#ifdef LOG4CPLUS_HAVE_RVALUE_REFS
 inline
-std::wstring 
+std::wstring
 towstring (std::wstring && str)
 {
     return std::move (str);
 }
 
-#endif
 
 LOG4CPLUS_EXPORT std::string tostring(const std::wstring&);
 LOG4CPLUS_EXPORT std::string tostring(wchar_t const *);

+ 7 - 7
include/log4cplus/version.h

@@ -1,16 +1,16 @@
 // -*- C++ -*-
-//  Copyright (C) 2010-2015, Vaclav Haisman. All rights reserved.
-//  
+//  Copyright (C) 2010-2017, Vaclav Haisman. All rights reserved.
+//
 //  Redistribution and use in source and binary forms, with or without modifica-
 //  tion, are permitted provided that the following conditions are met:
-//  
+//
 //  1. Redistributions of  source code must  retain the above copyright  notice,
 //     this list of conditions and the following disclaimer.
-//  
+//
 //  2. Redistributions in binary form must reproduce the above copyright notice,
 //     this list of conditions and the following disclaimer in the documentation
 //     and/or other materials provided with the distribution.
-//  
+//
 //  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 //  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 //  FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
@@ -41,10 +41,10 @@
 //! This is log4cplus version number as unsigned integer.  This must
 //! be kept on a single line. It is used by Autotool and CMake build
 //! systems to parse version number.
-#define LOG4CPLUS_VERSION LOG4CPLUS_MAKE_VERSION(1, 2, 0)
+#define LOG4CPLUS_VERSION LOG4CPLUS_MAKE_VERSION(2, 1, 3)
 
 //! This is log4cplus version number as a string.
-#define LOG4CPLUS_VERSION_STR LOG4CPLUS_MAKE_VERSION_STR(1, 2, 0)
+#define LOG4CPLUS_VERSION_STR LOG4CPLUS_MAKE_VERSION_STR(2, 1, 3)
 
 
 namespace log4cplus

+ 1 - 1
include/log4cplus/win32consoleappender.h

@@ -1,5 +1,5 @@
 // -*- C++ -*-
-//  Copyright (C) 2009-2015, Vaclav Haisman. All rights reserved.
+//  Copyright (C) 2009-2017, Vaclav Haisman. All rights reserved.
 //  
 //  Redistribution and use in source and binary forms, with or without modifica-
 //  tion, are permitted provided that the following conditions are met:

+ 1 - 1
include/log4cplus/win32debugappender.h

@@ -5,7 +5,7 @@
 // Author:  Eduardo Francos, Odalio SARL
 //
 //
-// Copyright 2003-2015 Odalio SARL
+// Copyright 2003-2017 Odalio SARL
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.

BIN
lib/debug/log4cplusUD.lib


BIN
lib/release/log4cplusU.lib