Uncrustify maxscale
See script directory for method. The script to run in the top level MaxScale directory is called maxscale-uncrustify.sh, which uses another script, list-src, from the same directory (so you need to set your PATH). The uncrustify version was 0.66.
This commit is contained in:
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxbase/cdefs.h>
|
||||
#include <signal.h>
|
||||
@ -21,19 +21,31 @@
|
||||
MXB_BEGIN_DECLS
|
||||
|
||||
// TODO: Provide an MXB_DEBUG with the same meaning.
|
||||
#if defined(SS_DEBUG)
|
||||
#if defined (SS_DEBUG)
|
||||
|
||||
#define mxb_assert(exp) do { if(!(exp)){\
|
||||
const char *debug_expr = #exp; /** The MXB_ERROR marco doesn't seem to like stringification */ \
|
||||
#define mxb_assert(exp) \
|
||||
do {if (!(exp)) { \
|
||||
const char* debug_expr = #exp; /** The MXB_ERROR marco doesn't seem to like stringification
|
||||
* */ \
|
||||
MXB_ERROR("debug assert at %s:%d failed: %s\n", (char*)__FILE__, __LINE__, debug_expr); \
|
||||
fprintf(stderr, "debug assert at %s:%d failed: %s\n", (char*)__FILE__, __LINE__, debug_expr); \
|
||||
raise(SIGABRT);} } while (false)
|
||||
raise(SIGABRT);}} while (false)
|
||||
|
||||
#define mxb_assert_message(exp,message) do { if(!(exp)){ \
|
||||
const char *debug_expr = #exp; \
|
||||
MXB_ERROR("debug assert at %s:%d failed: %s (%s)\n", (char*)__FILE__, __LINE__, message, debug_expr); \
|
||||
fprintf(stderr, "debug assert at %s:%d failed: %s (%s)\n", (char*)__FILE__, __LINE__, message, debug_expr); \
|
||||
raise(SIGABRT);} } while (false)
|
||||
#define mxb_assert_message(exp, message) \
|
||||
do {if (!(exp)) { \
|
||||
const char* debug_expr = #exp; \
|
||||
MXB_ERROR("debug assert at %s:%d failed: %s (%s)\n", \
|
||||
(char*)__FILE__, \
|
||||
__LINE__, \
|
||||
message, \
|
||||
debug_expr); \
|
||||
fprintf(stderr, \
|
||||
"debug assert at %s:%d failed: %s (%s)\n", \
|
||||
(char*)__FILE__, \
|
||||
__LINE__, \
|
||||
message, \
|
||||
debug_expr); \
|
||||
raise(SIGABRT);}} while (false)
|
||||
|
||||
#define MXB_AT_DEBUG(exp) exp
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file atomic.h Atomic operations on integers.
|
||||
@ -43,10 +43,10 @@ MXB_BEGIN_DECLS
|
||||
* @param value Value to be added
|
||||
* @return The value of variable before the add occurred
|
||||
*/
|
||||
int atomic_add(int *variable, int value);
|
||||
uint32_t atomic_add_uint32(uint32_t *variable, int32_t value);
|
||||
int64_t atomic_add_int64(int64_t *variable, int64_t value);
|
||||
uint64_t atomic_add_uint64(uint64_t *variable, int64_t value);
|
||||
int atomic_add(int* variable, int value);
|
||||
uint32_t atomic_add_uint32(uint32_t* variable, int32_t value);
|
||||
int64_t atomic_add_int64(int64_t* variable, int64_t value);
|
||||
uint64_t atomic_add_uint64(uint64_t* variable, int64_t value);
|
||||
|
||||
/**
|
||||
* Implementation of an atomic load operation for the GCC environment.
|
||||
@ -57,12 +57,12 @@ uint64_t atomic_add_uint64(uint64_t *variable, int64_t value);
|
||||
* @param variable Pointer the the variable to load from
|
||||
* @return The stored value
|
||||
*/
|
||||
int atomic_load_int(const int *variable);
|
||||
int32_t atomic_load_int32(const int32_t *variable);
|
||||
int64_t atomic_load_int64(const int64_t *variable);
|
||||
uint32_t atomic_load_uint32(const uint32_t *variable);
|
||||
uint64_t atomic_load_uint64(const uint64_t *variable);
|
||||
void* atomic_load_ptr(void * const *variable);
|
||||
int atomic_load_int(const int* variable);
|
||||
int32_t atomic_load_int32(const int32_t* variable);
|
||||
int64_t atomic_load_int64(const int64_t* variable);
|
||||
uint32_t atomic_load_uint32(const uint32_t* variable);
|
||||
uint64_t atomic_load_uint64(const uint64_t* variable);
|
||||
void* atomic_load_ptr(void* const* variable);
|
||||
|
||||
/**
|
||||
* Implementation of an atomic store operation for the GCC environment.
|
||||
@ -73,12 +73,12 @@ void* atomic_load_ptr(void * const *variable);
|
||||
* @param variable Pointer the the variable to store to
|
||||
* @param value Value to be stored
|
||||
*/
|
||||
void atomic_store_int(int *variable, int value);
|
||||
void atomic_store_int32(int32_t *variable, int32_t value);
|
||||
void atomic_store_int64(int64_t *variable, int64_t value);
|
||||
void atomic_store_uint32(uint32_t *variable, uint32_t value);
|
||||
void atomic_store_uint64(uint64_t *variable, uint64_t value);
|
||||
void atomic_store_ptr(void **variable, void *value);
|
||||
void atomic_store_int(int* variable, int value);
|
||||
void atomic_store_int32(int32_t* variable, int32_t value);
|
||||
void atomic_store_int64(int64_t* variable, int64_t value);
|
||||
void atomic_store_uint32(uint32_t* variable, uint32_t value);
|
||||
void atomic_store_uint64(uint64_t* variable, uint64_t value);
|
||||
void atomic_store_ptr(void** variable, void* value);
|
||||
|
||||
/**
|
||||
* @brief Impose a full memory barrier
|
||||
@ -98,7 +98,7 @@ static inline void atomic_synchronize()
|
||||
#ifdef MXB_USE_ATOMIC_BUILTINS
|
||||
__atomic_thread_fence(__ATOMIC_SEQ_CST);
|
||||
#else
|
||||
__sync_synchronize(); /* Memory barrier. */
|
||||
__sync_synchronize(); /* Memory barrier. */
|
||||
#endif
|
||||
|
||||
#else
|
||||
@ -119,7 +119,7 @@ static inline void atomic_synchronize()
|
||||
* written to @c old_value if the two are not equal. Do not rely on this behavior
|
||||
* and always do a separate read before attempting a compare-and-swap.
|
||||
*/
|
||||
bool atomic_cas_ptr(void **variable, void** old_value, void *new_value);
|
||||
bool atomic_cas_ptr(void** variable, void** old_value, void* new_value);
|
||||
|
||||
/**
|
||||
* Atomic read-and-write. Writes new value into the given memory address and returns the old value.
|
||||
@ -128,6 +128,6 @@ bool atomic_cas_ptr(void **variable, void** old_value, void *new_value);
|
||||
* @param new_value The value to write
|
||||
* @return The value before writing
|
||||
*/
|
||||
int atomic_exchange_int(int *variable, int new_value);
|
||||
int atomic_exchange_int(int* variable, int new_value);
|
||||
|
||||
MXB_END_DECLS
|
||||
|
||||
@ -23,10 +23,10 @@ class CumulativeAverage
|
||||
{
|
||||
public:
|
||||
// add an average made of num_samples
|
||||
void add(double ave, int num_samples = 1);
|
||||
double average() const;
|
||||
int num_samples() const;
|
||||
void reset();
|
||||
void add(double ave, int num_samples = 1);
|
||||
double average() const;
|
||||
int num_samples() const;
|
||||
void reset();
|
||||
CumulativeAverage& operator+=(const CumulativeAverage& rhs);
|
||||
private:
|
||||
double m_ave = 0;
|
||||
@ -43,8 +43,8 @@ public:
|
||||
EMAverage(double min_alpha, double max_alpha, int sample_max);
|
||||
|
||||
/* add an average made of num_samples
|
||||
* alpha = m_min_alpha + m_max_alpha * std::min(double(num_samples) / sample_max, 1.0);
|
||||
* ave = alpha * ave + (1 - alpha) * sample; */
|
||||
* alpha = m_min_alpha + m_max_alpha * std::min(double(num_samples) / sample_max, 1.0);
|
||||
* ave = alpha * ave + (1 - alpha) * sample; */
|
||||
void add(double ave, int num_samples = 1);
|
||||
void add(const CumulativeAverage& ca);
|
||||
double average() const;
|
||||
@ -53,11 +53,10 @@ public:
|
||||
int sample_max() const;
|
||||
void reset();
|
||||
private:
|
||||
const double m_min_alpha;
|
||||
const double m_max_alpha;
|
||||
int m_sample_max;
|
||||
int m_num_samples = 0;
|
||||
double m_ave = 0;
|
||||
const double m_min_alpha;
|
||||
const double m_max_alpha;
|
||||
int m_sample_max;
|
||||
int m_num_samples = 0;
|
||||
double m_ave = 0;
|
||||
};
|
||||
|
||||
} // maxbase
|
||||
} // maxbase
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
* This file is to be included first by all C++ headers.
|
||||
*/
|
||||
|
||||
#if !defined(__cplusplus)
|
||||
#if !defined (__cplusplus)
|
||||
#error This file is only to be included by C++ code.
|
||||
#endif
|
||||
|
||||
|
||||
@ -61,7 +61,7 @@
|
||||
* The function attributes are compiler specific.
|
||||
*/
|
||||
#ifdef __GNUC__
|
||||
#define mxb_attribute(a) __attribute__(a)
|
||||
#define mxb_attribute(a) __attribute__ (a)
|
||||
#else
|
||||
#define mxb_attribute(a)
|
||||
#endif
|
||||
@ -76,11 +76,11 @@
|
||||
/**
|
||||
* thread_local
|
||||
*/
|
||||
#if !defined(__cplusplus)
|
||||
#if !defined (__cplusplus)
|
||||
|
||||
#if __STDC_VERSION__ >= 201112
|
||||
|
||||
#if defined(__STDC_NO_THREADS__)
|
||||
#if defined (__STDC_NO_THREADS__)
|
||||
#define thread_local _Thread_local
|
||||
#else
|
||||
#include <threads.h>
|
||||
@ -88,7 +88,7 @@
|
||||
|
||||
#else // __STDC_VERSION >= 201112
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#if defined (__GNUC__)
|
||||
#define thread_local __thread
|
||||
#else
|
||||
#error Do not know how to define thread_local on this compiler/OS platform.
|
||||
@ -101,7 +101,7 @@
|
||||
// GCC 4.8 added support for native thread_local.
|
||||
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8)
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#if defined (__GNUC__)
|
||||
#define thread_local __thread
|
||||
#else
|
||||
#error Do not know how to define thread_local on this compiler/OS platform.
|
||||
|
||||
@ -35,10 +35,11 @@ class EventCount
|
||||
public:
|
||||
EventCount(const EventCount&) = delete;
|
||||
EventCount& operator=(const EventCount&) = delete;
|
||||
explicit EventCount(const std::string& event_id, Duration time_window,
|
||||
explicit EventCount(const std::string& event_id,
|
||||
Duration time_window,
|
||||
Duration granularity = Duration(std::chrono::milliseconds(10)));
|
||||
EventCount(EventCount&&); // can't be defaulted in gcc 4.4
|
||||
EventCount& operator=(EventCount&&); // can't be defaulted in gcc 4.4
|
||||
EventCount(EventCount&&); // can't be defaulted in gcc 4.4
|
||||
EventCount& operator=(EventCount&&);// can't be defaulted in gcc 4.4
|
||||
|
||||
const std::string& event_id() const
|
||||
{
|
||||
@ -49,22 +50,25 @@ public:
|
||||
return m_time_window;
|
||||
}
|
||||
void dump(std::ostream& os) const;
|
||||
int count() const;
|
||||
int count() const;
|
||||
void increment();
|
||||
|
||||
// these defs need not be public once lambdas are available
|
||||
struct Timestamp
|
||||
{
|
||||
TimePoint time_point;
|
||||
int count;
|
||||
Timestamp(TimePoint p, int c) : time_point(p), count(c) {}
|
||||
int count;
|
||||
Timestamp(TimePoint p, int c) : time_point(p)
|
||||
, count(c)
|
||||
{
|
||||
}
|
||||
};
|
||||
private:
|
||||
void purge() const; // remove out of window stats
|
||||
void purge() const; // remove out of window stats
|
||||
|
||||
std::string m_event_id;
|
||||
Duration m_time_window;
|
||||
Duration::rep m_granularity;
|
||||
std::string m_event_id;
|
||||
Duration m_time_window;
|
||||
Duration::rep m_granularity;
|
||||
mutable std::vector<Timestamp> m_timestamps;
|
||||
};
|
||||
|
||||
@ -76,10 +80,11 @@ class SessionCount
|
||||
public:
|
||||
SessionCount(const SessionCount&) = delete;
|
||||
SessionCount& operator=(const SessionCount&) = delete;
|
||||
SessionCount(const std::string& sess_id, Duration time_window,
|
||||
SessionCount(const std::string& sess_id,
|
||||
Duration time_window,
|
||||
Duration granularity = Duration(std::chrono::milliseconds(10)));
|
||||
SessionCount(SessionCount &&); // can't be defaulted in gcc 4.4
|
||||
SessionCount& operator=(SessionCount&&); // can't be defaulted in gcc 4.4
|
||||
SessionCount(SessionCount&&); // can't be defaulted in gcc 4.4
|
||||
SessionCount& operator=(SessionCount&&);// can't be defaulted in gcc 4.4
|
||||
|
||||
const std::string& session_id() const
|
||||
{
|
||||
@ -90,23 +95,22 @@ public:
|
||||
return m_time_window;
|
||||
}
|
||||
const std::vector<EventCount>& event_counts() const;
|
||||
void dump(std::ostream& os) const;
|
||||
bool empty() const; // no stats
|
||||
void dump(std::ostream& os) const;
|
||||
bool empty() const; // no stats
|
||||
|
||||
void increment(const std::string& event_id);
|
||||
private:
|
||||
void purge() const; // remove out of window stats
|
||||
void purge() const; // remove out of window stats
|
||||
|
||||
std::string m_sess_id;
|
||||
Duration m_time_window;
|
||||
Duration m_granularity;
|
||||
mutable int m_cleanup_countdown;
|
||||
std::string m_sess_id;
|
||||
Duration m_time_window;
|
||||
Duration m_granularity;
|
||||
mutable int m_cleanup_countdown;
|
||||
mutable std::vector<EventCount> m_event_counts;
|
||||
};
|
||||
|
||||
// conveniece. Any real formatted output should go elsewhere.
|
||||
std::ostream& operator<<(std::ostream& os, const SessionCount& stats);
|
||||
void dump(std::ostream& os, const std::vector<SessionCount>& sessions);
|
||||
void dumpTotals(std::ostream& os, const std::vector<SessionCount> &sessions);
|
||||
|
||||
} // maxbase
|
||||
void dump(std::ostream& os, const std::vector<SessionCount>& sessions);
|
||||
void dumpTotals(std::ostream& os, const std::vector<SessionCount>& sessions);
|
||||
} // maxbase
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxbase/cdefs.h>
|
||||
#include <jansson.h>
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxbase/cdefs.h>
|
||||
|
||||
@ -45,7 +45,7 @@ MXB_BEGIN_DECLS
|
||||
* Any file that is compiled into maxscale-common should *not* have
|
||||
* MXB_MODULE_NAME defined.
|
||||
*/
|
||||
#if !defined(MXB_MODULE_NAME)
|
||||
#if !defined (MXB_MODULE_NAME)
|
||||
#define MXB_MODULE_NAME NULL
|
||||
#endif
|
||||
|
||||
@ -54,13 +54,13 @@ extern int mxb_log_enabled_priorities;
|
||||
typedef enum mxb_log_target_t
|
||||
{
|
||||
MXB_LOG_TARGET_DEFAULT,
|
||||
MXB_LOG_TARGET_FS, // File system
|
||||
MXB_LOG_TARGET_STDOUT, // Standard output
|
||||
MXB_LOG_TARGET_FS, // File system
|
||||
MXB_LOG_TARGET_STDOUT, // Standard output
|
||||
} mxb_log_target_t;
|
||||
|
||||
typedef enum mxb_log_augmentation_t
|
||||
{
|
||||
MXB_LOG_AUGMENT_WITH_FUNCTION = 1, // Each logged line is suffixed with [function-name]
|
||||
MXB_LOG_AUGMENT_WITH_FUNCTION = 1, // Each logged line is suffixed with [function-name]
|
||||
MXB_LOG_AUGMENTATION_MASK = (MXB_LOG_AUGMENT_WITH_FUNCTION)
|
||||
} mxb_log_augmentation_t;
|
||||
|
||||
@ -83,7 +83,7 @@ typedef struct MXB_LOG_THROTTLING
|
||||
*
|
||||
* @return Length of data written to buffer.
|
||||
*/
|
||||
typedef size_t (*mxb_log_context_provider_t)(char* buffer, size_t len);
|
||||
typedef size_t (* mxb_log_context_provider_t)(char* buffer, size_t len);
|
||||
|
||||
/**
|
||||
* @brief Initialize the log
|
||||
@ -241,8 +241,11 @@ void mxb_log_get_throttling(MXB_LOG_THROTTLING* throttling);
|
||||
*/
|
||||
int mxb_log_message(int priority,
|
||||
const char* modname,
|
||||
const char* file, int line, const char* function,
|
||||
const char* format, ...) mxb_attribute((format(printf, 6, 7)));
|
||||
const char* file,
|
||||
int line,
|
||||
const char* function,
|
||||
const char* format,
|
||||
...) mxb_attribute((format(printf, 6, 7)));
|
||||
|
||||
/**
|
||||
* Log an Out-Of-Memory message.
|
||||
@ -267,10 +270,10 @@ int mxb_log_oom(const char* message);
|
||||
* @attention Should typically not be called directly. Use some of the
|
||||
* MXB_ERROR, MXB_WARNING, etc. macros instead.
|
||||
*/
|
||||
#define MXB_LOG_MESSAGE(priority, format, ...)\
|
||||
(mxb_log_is_priority_enabled(priority) ? \
|
||||
mxb_log_message(priority, MXB_MODULE_NAME, __FILE__, __LINE__, __func__, format, ##__VA_ARGS__) :\
|
||||
0)
|
||||
#define MXB_LOG_MESSAGE(priority, format, ...) \
|
||||
(mxb_log_is_priority_enabled(priority) \
|
||||
? mxb_log_message(priority, MXB_MODULE_NAME, __FILE__, __LINE__, __func__, format, ##__VA_ARGS__) \
|
||||
: 0)
|
||||
|
||||
/**
|
||||
* Log an alert, error, warning, notice, info, or debug message.
|
||||
@ -288,14 +291,14 @@ int mxb_log_oom(const char* message);
|
||||
*
|
||||
* @return 0 for success, non-zero otherwise.
|
||||
*/
|
||||
#define MXB_ALERT(format, ...) MXB_LOG_MESSAGE(LOG_ALERT, format, ##__VA_ARGS__)
|
||||
#define MXB_ERROR(format, ...) MXB_LOG_MESSAGE(LOG_ERR, format, ##__VA_ARGS__)
|
||||
#define MXB_ALERT(format, ...) MXB_LOG_MESSAGE(LOG_ALERT, format, ##__VA_ARGS__)
|
||||
#define MXB_ERROR(format, ...) MXB_LOG_MESSAGE(LOG_ERR, format, ##__VA_ARGS__)
|
||||
#define MXB_WARNING(format, ...) MXB_LOG_MESSAGE(LOG_WARNING, format, ##__VA_ARGS__)
|
||||
#define MXB_NOTICE(format, ...) MXB_LOG_MESSAGE(LOG_NOTICE, format, ##__VA_ARGS__)
|
||||
#define MXB_INFO(format, ...) MXB_LOG_MESSAGE(LOG_INFO, format, ##__VA_ARGS__)
|
||||
#define MXB_NOTICE(format, ...) MXB_LOG_MESSAGE(LOG_NOTICE, format, ##__VA_ARGS__)
|
||||
#define MXB_INFO(format, ...) MXB_LOG_MESSAGE(LOG_INFO, format, ##__VA_ARGS__)
|
||||
|
||||
#if defined(SS_DEBUG)
|
||||
#define MXB_DEBUG(format, ...) MXB_LOG_MESSAGE(LOG_DEBUG, format, ##__VA_ARGS__)
|
||||
#if defined (SS_DEBUG)
|
||||
#define MXB_DEBUG(format, ...) MXB_LOG_MESSAGE(LOG_DEBUG, format, ##__VA_ARGS__)
|
||||
#else
|
||||
#define MXB_DEBUG(format, ...)
|
||||
#endif
|
||||
@ -326,7 +329,7 @@ int mxb_log_oom(const char* message);
|
||||
*
|
||||
* @return 0 for success, non-zero otherwise.
|
||||
*/
|
||||
#define MXB_OOM_IFNULL(p) do { if (!p) { MXB_OOM(); } } while (false)
|
||||
#define MXB_OOM_IFNULL(p) do {if (!p) {MXB_OOM();}} while (false)
|
||||
|
||||
/**
|
||||
* Log an out of memory error using custom message, if the
|
||||
@ -337,6 +340,6 @@ int mxb_log_oom(const char* message);
|
||||
*
|
||||
* @return 0 for success, non-zero otherwise.
|
||||
*/
|
||||
#define MXB_OOM_MESSAGE_IFNULL(p, message) do { if (!p) { MXB_OOM_MESSAGE(message); } } while (false)
|
||||
#define MXB_OOM_MESSAGE_IFNULL(p, message) do {if (!p) {MXB_OOM_MESSAGE(message);}} while (false)
|
||||
|
||||
MXB_END_DECLS
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxbase/ccdefs.hh>
|
||||
#include <stdexcept>
|
||||
@ -70,5 +70,4 @@ public:
|
||||
mxb_log_finish();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxbase/ccdefs.hh>
|
||||
|
||||
@ -73,15 +73,15 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
Logger(const std::string& filename):
|
||||
m_filename(filename)
|
||||
Logger(const std::string& filename)
|
||||
: m_filename(filename)
|
||||
{
|
||||
}
|
||||
|
||||
std::string m_filename;
|
||||
};
|
||||
|
||||
class FileLogger: public Logger
|
||||
class FileLogger : public Logger
|
||||
{
|
||||
public:
|
||||
FileLogger(const FileLogger&) = delete;
|
||||
@ -122,8 +122,8 @@ public:
|
||||
bool rotate();
|
||||
|
||||
private:
|
||||
int m_fd;
|
||||
std::mutex m_lock;
|
||||
int m_fd;
|
||||
std::mutex m_lock;
|
||||
|
||||
FileLogger(int fd, const std::string& filename);
|
||||
bool write_header();
|
||||
@ -131,7 +131,7 @@ private:
|
||||
void close(const char* msg);
|
||||
};
|
||||
|
||||
class StdoutLogger: public Logger
|
||||
class StdoutLogger : public Logger
|
||||
{
|
||||
public:
|
||||
StdoutLogger(const StdoutLogger&) = delete;
|
||||
@ -170,13 +170,12 @@ public:
|
||||
bool rotate()
|
||||
{
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
private:
|
||||
StdoutLogger(const std::string& filename):
|
||||
Logger(filename)
|
||||
StdoutLogger(const std::string& filename)
|
||||
: Logger(filename)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxbase/cdefs.h>
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxbase/ccdefs.hh>
|
||||
#include <stdexcept>
|
||||
@ -105,5 +105,4 @@ public:
|
||||
private:
|
||||
bool m_log_inited;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxbase/ccdefs.hh>
|
||||
#include <maxbase/poll.hh>
|
||||
@ -28,7 +28,7 @@ class Worker;
|
||||
* the caller's and recipient's responsibility to manage the lifetime and
|
||||
* concurrent access of anything possibly pointed to from the message.
|
||||
*/
|
||||
class MessageQueueMessage /* final */
|
||||
class MessageQueueMessage /* final */
|
||||
{
|
||||
public:
|
||||
/**
|
||||
@ -110,7 +110,7 @@ public:
|
||||
class MessageQueue : private mxb::PollData
|
||||
{
|
||||
MessageQueue(const MessageQueue&);
|
||||
MessageQueue& operator = (const MessageQueue&);
|
||||
MessageQueue& operator=(const MessageQueue&);
|
||||
|
||||
public:
|
||||
typedef MessageQueueHandler Handler;
|
||||
@ -193,5 +193,4 @@ private:
|
||||
int m_write_fd;
|
||||
Worker* m_pWorker;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxbase/cdefs.h>
|
||||
#include <sys/epoll.h>
|
||||
@ -43,7 +43,7 @@ typedef struct MXB_WORKER
|
||||
*
|
||||
* @return A combination of mxb_poll_action_t enumeration values.
|
||||
*/
|
||||
typedef uint32_t (*mxb_poll_handler_t)(struct MXB_POLL_DATA* data, MXB_WORKER* worker, uint32_t events);
|
||||
typedef uint32_t (* mxb_poll_handler_t)(struct MXB_POLL_DATA* data, MXB_WORKER* worker, uint32_t events);
|
||||
|
||||
typedef struct MXB_POLL_DATA
|
||||
{
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxbase/ccdefs.hh>
|
||||
#include <maxbase/poll.h>
|
||||
@ -33,5 +33,4 @@ public:
|
||||
owner = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file semaphore.h Semaphores used by MaxScale.
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxbase/ccdefs.hh>
|
||||
#include <cerrno>
|
||||
@ -24,13 +24,13 @@ namespace maxbase
|
||||
class Semaphore
|
||||
{
|
||||
Semaphore(const Semaphore&) = delete;
|
||||
Semaphore& operator = (const Semaphore&) = delete;
|
||||
Semaphore& operator=(const Semaphore&) = delete;
|
||||
|
||||
public:
|
||||
enum signal_approach_t
|
||||
{
|
||||
HONOUR_SIGNALS, /* Honour signals and return when interrupted. */
|
||||
IGNORE_SIGNALS /* Ignore signals and re-issue the comment when signals occur. */
|
||||
HONOUR_SIGNALS, /* Honour signals and return when interrupted. */
|
||||
IGNORE_SIGNALS /* Ignore signals and re-issue the comment when signals occur. */
|
||||
};
|
||||
|
||||
/**
|
||||
@ -48,7 +48,7 @@ public:
|
||||
initial_count = SEM_VALUE_MAX;
|
||||
}
|
||||
|
||||
MXB_AT_DEBUG(int rc =) sem_init(&m_sem, 0, initial_count);
|
||||
MXB_AT_DEBUG(int rc = ) sem_init(&m_sem, 0, initial_count);
|
||||
mxb_assert(rc == 0);
|
||||
}
|
||||
|
||||
@ -66,7 +66,7 @@ public:
|
||||
mxb_assert(rc == 0);
|
||||
mxb_assert(count == 0);
|
||||
#endif
|
||||
MXB_AT_DEBUG(rc =) sem_destroy(&m_sem);
|
||||
MXB_AT_DEBUG(rc = ) sem_destroy(&m_sem);
|
||||
mxb_assert(rc == 0);
|
||||
}
|
||||
|
||||
@ -181,9 +181,9 @@ public:
|
||||
}
|
||||
while ((rc != 0) && ((errno == EINTR) && (signal_approach == IGNORE_SIGNALS)));
|
||||
|
||||
mxb_assert((rc == 0) ||
|
||||
(errno == EAGAIN) ||
|
||||
((errno == EINTR) && (signal_approach == HONOUR_SIGNALS)));
|
||||
mxb_assert((rc == 0)
|
||||
|| (errno == EAGAIN)
|
||||
|| ((errno == EINTR) && (signal_approach == HONOUR_SIGNALS)));
|
||||
|
||||
return rc == 0;
|
||||
}
|
||||
@ -217,9 +217,9 @@ public:
|
||||
}
|
||||
while ((rc != 0) && ((errno == EINTR) && (signal_approach == IGNORE_SIGNALS)));
|
||||
|
||||
mxb_assert((rc == 0) ||
|
||||
(errno == ETIMEDOUT) ||
|
||||
((errno == EINTR) && (signal_approach == HONOUR_SIGNALS)));
|
||||
mxb_assert((rc == 0)
|
||||
|| (errno == ETIMEDOUT)
|
||||
|| ((errno == EINTR) && (signal_approach == HONOUR_SIGNALS)));
|
||||
|
||||
return rc == 0;
|
||||
}
|
||||
@ -285,7 +285,7 @@ public:
|
||||
* and in the latter `EINTR.
|
||||
*/
|
||||
bool timedwait(time_t seconds,
|
||||
long nseconds,
|
||||
long nseconds,
|
||||
signal_approach_t signal_approach = IGNORE_SIGNALS) const
|
||||
{
|
||||
timespec ts;
|
||||
@ -316,7 +316,7 @@ public:
|
||||
*/
|
||||
size_t timedwait_n(size_t n_wait,
|
||||
time_t seconds,
|
||||
long nseconds,
|
||||
long nseconds,
|
||||
signal_approach_t signal_approach = IGNORE_SIGNALS) const
|
||||
{
|
||||
timespec ts;
|
||||
@ -380,5 +380,4 @@ private:
|
||||
private:
|
||||
mutable sem_t m_sem;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxbase/ccdefs.hh>
|
||||
#include <unistd.h>
|
||||
@ -27,6 +27,5 @@ static inline void default_stacktrace_handler(const char* symbol, const char* co
|
||||
write(STDOUT_FILENO, "\n", 1);
|
||||
}
|
||||
|
||||
void dump_stacktrace(void (*handler)(const char* symbol, const char* command) = default_stacktrace_handler);
|
||||
|
||||
void dump_stacktrace(void (* handler)(const char* symbol, const char* command) = default_stacktrace_handler);
|
||||
}
|
||||
|
||||
@ -22,15 +22,20 @@ namespace maxbase
|
||||
|
||||
using Clock = std::chrono::steady_clock;
|
||||
|
||||
struct Duration : public Clock::duration // for ADL
|
||||
struct Duration : public Clock::duration // for ADL
|
||||
{
|
||||
using Clock::duration::duration;
|
||||
Duration() = default;
|
||||
Duration(Clock::duration d) : Clock::duration(d) {}
|
||||
Duration(long long l) : Clock::duration(l) {} // FIXME. Get rid of this.
|
||||
Duration(Clock::duration d) : Clock::duration(d)
|
||||
{
|
||||
}
|
||||
Duration(long long l) : Clock::duration(l)
|
||||
{
|
||||
} // FIXME. Get rid of this.
|
||||
|
||||
explicit Duration(double secs) : Duration{rep(secs * period::den / period::num)}
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
double secs()
|
||||
{
|
||||
@ -60,7 +65,6 @@ std::pair<double, std::string> dur_to_human_readable(Duration dur);
|
||||
std::ostream& operator<<(std::ostream&, Duration dur);
|
||||
|
||||
// TimePoint
|
||||
std::string time_point_to_string(TimePoint tp, const std::string& fmt = "%F %T");
|
||||
std::string time_point_to_string(TimePoint tp, const std::string& fmt = "%F %T");
|
||||
std::ostream& operator<<(std::ostream&, TimePoint tp);
|
||||
|
||||
} // maxbase
|
||||
} // maxbase
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxbase/cdefs.h>
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/cdefs.h>
|
||||
#include <maxbase/poll.h>
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxbase/ccdefs.hh>
|
||||
|
||||
@ -40,22 +40,22 @@ struct WORKER_STATISTICS
|
||||
|
||||
enum
|
||||
{
|
||||
MAXNFDS = 10,
|
||||
MAXNFDS = 10,
|
||||
N_QUEUE_TIMES = 30
|
||||
};
|
||||
|
||||
int64_t n_read; /*< Number of read events */
|
||||
int64_t n_write; /*< Number of write events */
|
||||
int64_t n_error; /*< Number of error events */
|
||||
int64_t n_hup; /*< Number of hangup events */
|
||||
int64_t n_accept; /*< Number of accept events */
|
||||
int64_t n_polls; /*< Number of poll cycles */
|
||||
int64_t n_pollev; /*< Number of polls returning events */
|
||||
int64_t n_nbpollev; /*< Number of polls returning events */
|
||||
int64_t n_fds[MAXNFDS]; /*< Number of wakeups with particular n_fds value */
|
||||
int64_t evq_avg; /*< Average event queue length */
|
||||
int64_t evq_max; /*< Maximum event queue length */
|
||||
int64_t blockingpolls; /*< Number of epoll_waits with a timeout specified */
|
||||
int64_t n_read; /*< Number of read events */
|
||||
int64_t n_write; /*< Number of write events */
|
||||
int64_t n_error; /*< Number of error events */
|
||||
int64_t n_hup; /*< Number of hangup events */
|
||||
int64_t n_accept; /*< Number of accept events */
|
||||
int64_t n_polls; /*< Number of poll cycles */
|
||||
int64_t n_pollev; /*< Number of polls returning events */
|
||||
int64_t n_nbpollev; /*< Number of polls returning events */
|
||||
int64_t n_fds[MAXNFDS]; /*< Number of wakeups with particular n_fds value */
|
||||
int64_t evq_avg; /*< Average event queue length */
|
||||
int64_t evq_max; /*< Maximum event queue length */
|
||||
int64_t blockingpolls; /*< Number of epoll_waits with a timeout specified */
|
||||
uint32_t qtimes[N_QUEUE_TIMES + 1];
|
||||
uint32_t exectimes[N_QUEUE_TIMES + 1];
|
||||
int64_t maxqtime;
|
||||
@ -76,7 +76,7 @@ struct WORKER_STATISTICS
|
||||
class WorkerLoad
|
||||
{
|
||||
WorkerLoad(const WorkerLoad&) = delete;
|
||||
WorkerLoad& operator = (const WorkerLoad&) = delete;
|
||||
WorkerLoad& operator=(const WorkerLoad&) = delete;
|
||||
|
||||
public:
|
||||
enum counter_t
|
||||
@ -157,7 +157,7 @@ public:
|
||||
default:
|
||||
mxb_assert(!true);
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -187,7 +187,7 @@ private:
|
||||
class Average
|
||||
{
|
||||
Average(const Average&) = delete;
|
||||
Average& operator = (const Average&) = delete;
|
||||
Average& operator=(const Average&) = delete;
|
||||
|
||||
public:
|
||||
/**
|
||||
@ -198,7 +198,8 @@ private:
|
||||
Average(Average* pDependant = NULL)
|
||||
: m_pDependant(pDependant)
|
||||
, m_value(0)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~Average();
|
||||
|
||||
@ -238,8 +239,8 @@ private:
|
||||
}
|
||||
|
||||
protected:
|
||||
Average* m_pDependant; /*< The optional dependant Average. */
|
||||
uint32_t m_value; /*< The current average value. */
|
||||
Average* m_pDependant; /*< The optional dependant Average. */
|
||||
uint32_t m_value; /*< The current average value. */
|
||||
|
||||
protected:
|
||||
void set_value(uint32_t value)
|
||||
@ -314,7 +315,7 @@ private:
|
||||
}
|
||||
|
||||
*m_i = value;
|
||||
m_sum += *m_i; // Update the sum of all values.
|
||||
m_sum += *m_i; // Update the sum of all values.
|
||||
|
||||
m_i = next(m_i);
|
||||
|
||||
@ -409,19 +410,19 @@ private:
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t m_begin[N]; /*< Buffer containing values from which the average is calculated. */
|
||||
uint8_t* m_end; /*< Points to one past the end of the buffer. */
|
||||
uint8_t* m_i; /*< Current position in the buffer. */
|
||||
uint32_t m_sum; /*< Sum of all values in the buffer. */
|
||||
uint32_t m_nValues; /*< How many values the buffer contains. */
|
||||
uint8_t m_begin[N]; /*< Buffer containing values from which the average is calculated. */
|
||||
uint8_t* m_end; /*< Points to one past the end of the buffer. */
|
||||
uint8_t* m_i; /*< Current position in the buffer. */
|
||||
uint32_t m_sum; /*< Sum of all values in the buffer. */
|
||||
uint32_t m_nValues; /*< How many values the buffer contains. */
|
||||
};
|
||||
|
||||
uint64_t m_start_time; /*< When was the current 1-second period started. */
|
||||
uint64_t m_wait_start; /*< The time when the worker entered epoll_wait(). */
|
||||
uint64_t m_wait_time; /*< How much time the worker has spent in epoll_wait(). */
|
||||
AverageN<60> m_load_1_hour; /*< The average load during the last hour. */
|
||||
AverageN<60> m_load_1_minute; /*< The average load during the last minute. */
|
||||
Average1 m_load_1_second; /*< The load during the last 1-second period. */
|
||||
uint64_t m_start_time; /*< When was the current 1-second period started. */
|
||||
uint64_t m_wait_start; /*< The time when the worker entered epoll_wait(). */
|
||||
uint64_t m_wait_time; /*< How much time the worker has spent in epoll_wait(). */
|
||||
AverageN<60> m_load_1_hour; /*< The average load during the last hour. */
|
||||
AverageN<60> m_load_1_minute; /*< The average load during the last minute. */
|
||||
Average1 m_load_1_second; /*< The load during the last 1-second period. */
|
||||
};
|
||||
|
||||
/**
|
||||
@ -434,7 +435,7 @@ private:
|
||||
class WorkerTimer : private MXB_POLL_DATA
|
||||
{
|
||||
WorkerTimer(const WorkerTimer&) = delete;
|
||||
WorkerTimer& operator = (const WorkerTimer&) = delete;
|
||||
WorkerTimer& operator=(const WorkerTimer&) = delete;
|
||||
|
||||
public:
|
||||
virtual ~WorkerTimer();
|
||||
@ -474,8 +475,8 @@ private:
|
||||
static uint32_t handler(MXB_POLL_DATA* pThis, MXB_WORKER* pWorker, uint32_t events);
|
||||
|
||||
private:
|
||||
int m_fd; /**< The timerfd descriptor. */
|
||||
Worker* m_pWorker; /**< The worker in whose context the timer runs. */
|
||||
int m_fd; /**< The timerfd descriptor. */
|
||||
Worker* m_pWorker; /**< The worker in whose context the timer runs. */
|
||||
};
|
||||
|
||||
/**
|
||||
@ -487,14 +488,14 @@ class Worker : public MXB_WORKER
|
||||
, private MessageQueue::Handler
|
||||
{
|
||||
Worker(const Worker&) = delete;
|
||||
Worker& operator = (const Worker&) = delete;
|
||||
Worker& operator=(const Worker&) = delete;
|
||||
|
||||
public:
|
||||
typedef WORKER_STATISTICS STATISTICS;
|
||||
typedef WorkerTask Task;
|
||||
typedef WorkerDisposableTask DisposableTask;
|
||||
typedef WorkerLoad Load;
|
||||
typedef WorkerTimer Timer;
|
||||
typedef WORKER_STATISTICS STATISTICS;
|
||||
typedef WorkerTask Task;
|
||||
typedef WorkerDisposableTask DisposableTask;
|
||||
typedef WorkerLoad Load;
|
||||
typedef WorkerTimer Timer;
|
||||
|
||||
/**
|
||||
* A delegating timer that delegates the timer tick handling
|
||||
@ -504,10 +505,10 @@ public:
|
||||
class DelegatingTimer : public Timer
|
||||
{
|
||||
DelegatingTimer(const DelegatingTimer&) = delete;
|
||||
DelegatingTimer& operator = (const DelegatingTimer&) = delete;
|
||||
DelegatingTimer& operator=(const DelegatingTimer&) = delete;
|
||||
|
||||
public:
|
||||
typedef void (T::*PMethod)();
|
||||
typedef void (T::* PMethod)();
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
@ -525,7 +526,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
void tick() /* final */
|
||||
void tick() /* final */
|
||||
{
|
||||
(m_pDelegatee->*m_pMethod)();
|
||||
}
|
||||
@ -546,16 +547,16 @@ public:
|
||||
|
||||
enum execute_mode_t
|
||||
{
|
||||
EXECUTE_AUTO, /**< Execute tasks immediately */
|
||||
EXECUTE_QUEUED /**< Only queue tasks for execution */
|
||||
EXECUTE_AUTO, /**< Execute tasks immediately */
|
||||
EXECUTE_QUEUED /**< Only queue tasks for execution */
|
||||
};
|
||||
|
||||
struct Call
|
||||
{
|
||||
enum action_t
|
||||
{
|
||||
EXECUTE, /**< Execute the call */
|
||||
CANCEL /**< Cancel the call */
|
||||
EXECUTE, /**< Execute the call */
|
||||
CANCEL /**< Cancel the call */
|
||||
};
|
||||
};
|
||||
|
||||
@ -704,7 +705,7 @@ public:
|
||||
* @param mode Execution mode
|
||||
*
|
||||
* @return True if the task could be posted to the worker (i.e. not executed yet),
|
||||
false otherwise.
|
||||
* false otherwise.
|
||||
*
|
||||
* @attention The instance must remain valid for as long as it takes for the
|
||||
* task to be transferred to the worker and its `execute` function
|
||||
@ -823,7 +824,7 @@ public:
|
||||
* be called again.
|
||||
*/
|
||||
uint32_t delayed_call(int32_t delay,
|
||||
bool (*pFunction)(Worker::Call::action_t action))
|
||||
bool (* pFunction)(Worker::Call::action_t action))
|
||||
{
|
||||
return add_delayed_call(new DelayedCallFunctionVoid(delay, pFunction));
|
||||
}
|
||||
@ -850,7 +851,7 @@ public:
|
||||
*/
|
||||
template<class D>
|
||||
uint32_t delayed_call(int32_t delay,
|
||||
bool (*pFunction)(Worker::Call::action_t action, D data),
|
||||
bool (* pFunction)(Worker::Call::action_t action, D data),
|
||||
D data)
|
||||
{
|
||||
return add_delayed_call(new DelayedCallFunction<D>(delay, pFunction, data));
|
||||
@ -877,7 +878,7 @@ public:
|
||||
*/
|
||||
template<class T>
|
||||
uint32_t delayed_call(int32_t delay,
|
||||
bool (T::*pMethod)(Worker::Call::action_t action),
|
||||
bool (T::* pMethod)(Worker::Call::action_t action),
|
||||
T* pT)
|
||||
{
|
||||
return add_delayed_call(new DelayedCallMethodVoid<T>(delay, pMethod, pT));
|
||||
@ -905,7 +906,7 @@ public:
|
||||
*/
|
||||
template<class T, class D>
|
||||
uint32_t delayed_call(int32_t delay,
|
||||
bool (T::*pMethod)(Worker::Call::action_t action, D data),
|
||||
bool (T::* pMethod)(Worker::Call::action_t action, D data),
|
||||
T* pT,
|
||||
D data)
|
||||
{
|
||||
@ -926,8 +927,8 @@ public:
|
||||
bool cancel_delayed_call(uint32_t id);
|
||||
|
||||
protected:
|
||||
const int m_epoll_fd; /*< The epoll file descriptor. */
|
||||
state_t m_state; /*< The state of the worker */
|
||||
const int m_epoll_fd; /*< The epoll file descriptor. */
|
||||
state_t m_state; /*< The state of the worker */
|
||||
|
||||
static void inc_ref(WorkerDisposableTask* pTask)
|
||||
{
|
||||
@ -993,8 +994,8 @@ private:
|
||||
|
||||
class DelayedCall
|
||||
{
|
||||
DelayedCall(const DelayedCall&) = delete;;
|
||||
DelayedCall& operator = (const DelayedCall&) = delete;
|
||||
DelayedCall(const DelayedCall&) = delete;
|
||||
DelayedCall& operator=(const DelayedCall&) = delete;
|
||||
|
||||
public:
|
||||
virtual ~DelayedCall()
|
||||
@ -1044,27 +1045,28 @@ private:
|
||||
mxb_assert(delay > 0);
|
||||
|
||||
struct timespec ts;
|
||||
MXB_AT_DEBUG(int rv =) clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
MXB_AT_DEBUG(int rv = ) clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
mxb_assert(rv == 0);
|
||||
|
||||
return delay + (ts.tv_sec * 1000 + ts.tv_nsec / 1000000);
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t m_id; // The id of the delayed call.
|
||||
int32_t m_delay; // The delay in milliseconds.
|
||||
int64_t m_at; // The next time the function should be invoked.
|
||||
uint32_t m_id; // The id of the delayed call.
|
||||
int32_t m_delay; // The delay in milliseconds.
|
||||
int64_t m_at; // The next time the function should be invoked.
|
||||
};
|
||||
|
||||
template<class D>
|
||||
class DelayedCallFunction : public DelayedCall
|
||||
{
|
||||
DelayedCallFunction(const DelayedCallFunction&) = delete;
|
||||
DelayedCallFunction& operator = (const DelayedCallFunction&) = delete;
|
||||
DelayedCallFunction& operator=(const DelayedCallFunction&) = delete;
|
||||
|
||||
public:
|
||||
DelayedCallFunction(int32_t delay,
|
||||
bool (*pFunction)(Worker::Call::action_t action, D data), D data)
|
||||
bool (*pFunction)(Worker::Call::action_t action, D data),
|
||||
D data)
|
||||
: DelayedCall(delay)
|
||||
, m_pFunction(pFunction)
|
||||
, m_data(data)
|
||||
@ -1078,15 +1080,15 @@ private:
|
||||
}
|
||||
|
||||
private:
|
||||
bool (*m_pFunction)(Worker::Call::action_t, D);
|
||||
D m_data;
|
||||
bool (* m_pFunction)(Worker::Call::action_t, D);
|
||||
D m_data;
|
||||
};
|
||||
|
||||
// Explicit specialization requires namespace scope
|
||||
class DelayedCallFunctionVoid : public DelayedCall
|
||||
{
|
||||
DelayedCallFunctionVoid(const DelayedCallFunctionVoid&) = delete;
|
||||
DelayedCallFunctionVoid& operator = (const DelayedCallFunctionVoid&) = delete;
|
||||
DelayedCallFunctionVoid& operator=(const DelayedCallFunctionVoid&) = delete;
|
||||
|
||||
public:
|
||||
DelayedCallFunctionVoid(int32_t delay,
|
||||
@ -1103,18 +1105,18 @@ private:
|
||||
}
|
||||
|
||||
private:
|
||||
bool (*m_pFunction)(Worker::Call::action_t action);
|
||||
bool (* m_pFunction)(Worker::Call::action_t action);
|
||||
};
|
||||
|
||||
template<class T, class D>
|
||||
class DelayedCallMethod : public DelayedCall
|
||||
{
|
||||
DelayedCallMethod(const DelayedCallMethod&) = delete;
|
||||
DelayedCallMethod& operator = (const DelayedCallMethod&) = delete;
|
||||
DelayedCallMethod& operator=(const DelayedCallMethod&) = delete;
|
||||
|
||||
public:
|
||||
DelayedCallMethod(int32_t delay,
|
||||
bool (T::*pMethod)(Worker::Call::action_t action, D data),
|
||||
bool (T::* pMethod)(Worker::Call::action_t action, D data),
|
||||
T* pT,
|
||||
D data)
|
||||
: DelayedCall(delay)
|
||||
@ -1131,20 +1133,20 @@ private:
|
||||
}
|
||||
|
||||
private:
|
||||
bool (T::*m_pMethod)(Worker::Call::action_t, D);
|
||||
bool (T::* m_pMethod)(Worker::Call::action_t, D);
|
||||
T* m_pT;
|
||||
D m_data;
|
||||
D m_data;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class DelayedCallMethodVoid : public DelayedCall
|
||||
{
|
||||
DelayedCallMethodVoid(const DelayedCallMethodVoid&) = delete;
|
||||
DelayedCallMethodVoid& operator = (const DelayedCallMethodVoid&) = delete;
|
||||
DelayedCallMethodVoid& operator=(const DelayedCallMethodVoid&) = delete;
|
||||
|
||||
public:
|
||||
DelayedCallMethodVoid(int32_t delay,
|
||||
bool (T::*pMethod)(Worker::Call::action_t),
|
||||
bool (T::* pMethod)(Worker::Call::action_t),
|
||||
T* pT)
|
||||
: DelayedCall(delay)
|
||||
, m_pMethod(pMethod)
|
||||
@ -1159,14 +1161,14 @@ private:
|
||||
}
|
||||
|
||||
private:
|
||||
bool (T::*m_pMethod)(Worker::Call::action_t);
|
||||
bool (T::* m_pMethod)(Worker::Call::action_t);
|
||||
T* m_pT;
|
||||
};
|
||||
|
||||
uint32_t add_delayed_call(DelayedCall* pDelayed_call);
|
||||
void adjust_timer();
|
||||
void adjust_timer();
|
||||
|
||||
void handle_message(MessageQueue& queue, const MessageQueue::Message& msg); // override
|
||||
void handle_message(MessageQueue& queue, const MessageQueue::Message& msg); // override
|
||||
|
||||
static void thread_main(Worker* pThis, mxb::Semaphore* pSem);
|
||||
|
||||
@ -1178,7 +1180,7 @@ private:
|
||||
class LaterAt : public std::binary_function<const DelayedCall*, const DelayedCall*, bool>
|
||||
{
|
||||
public:
|
||||
bool operator () (const DelayedCall* pLhs, const DelayedCall* pRhs)
|
||||
bool operator()(const DelayedCall* pLhs, const DelayedCall* pRhs)
|
||||
{
|
||||
return pLhs->at() > pRhs->at();
|
||||
}
|
||||
@ -1186,25 +1188,24 @@ private:
|
||||
|
||||
void run(mxb::Semaphore* pSem);
|
||||
|
||||
typedef DelegatingTimer<Worker> PrivateTimer;
|
||||
typedef std::multimap<int64_t, DelayedCall*> DelayedCallsByTime;
|
||||
typedef std::unordered_map<uint32_t, DelayedCall*> DelayedCallsById;
|
||||
typedef DelegatingTimer<Worker> PrivateTimer;
|
||||
typedef std::multimap<int64_t, DelayedCall*> DelayedCallsByTime;
|
||||
typedef std::unordered_map<uint32_t, DelayedCall*> DelayedCallsById;
|
||||
|
||||
uint32_t m_max_events; /*< Maximum numer of events in each epoll_wait call. */
|
||||
STATISTICS m_statistics; /*< Worker statistics. */
|
||||
MessageQueue* m_pQueue; /*< The message queue of the worker. */
|
||||
std::thread m_thread; /*< The thread object of the worker. */
|
||||
bool m_started; /*< Whether the thread has been started or not. */
|
||||
bool m_should_shutdown; /*< Whether shutdown should be performed. */
|
||||
bool m_shutdown_initiated; /*< Whether shutdown has been initated. */
|
||||
uint32_t m_nCurrent_descriptors; /*< Current number of descriptors. */
|
||||
uint64_t m_nTotal_descriptors; /*< Total number of descriptors. */
|
||||
Load m_load; /*< The worker load. */
|
||||
PrivateTimer* m_pTimer; /*< The worker's own timer. */
|
||||
DelayedCallsByTime m_sorted_calls; /*< Current delayed calls sorted by time. */
|
||||
DelayedCallsById m_calls; /*< Current delayed calls indexed by id. */
|
||||
uint32_t m_max_events; /*< Maximum numer of events in each epoll_wait call. */
|
||||
STATISTICS m_statistics; /*< Worker statistics. */
|
||||
MessageQueue* m_pQueue; /*< The message queue of the worker. */
|
||||
std::thread m_thread; /*< The thread object of the worker. */
|
||||
bool m_started; /*< Whether the thread has been started or not. */
|
||||
bool m_should_shutdown; /*< Whether shutdown should be performed. */
|
||||
bool m_shutdown_initiated; /*< Whether shutdown has been initated. */
|
||||
uint32_t m_nCurrent_descriptors; /*< Current number of descriptors. */
|
||||
uint64_t m_nTotal_descriptors; /*< Total number of descriptors. */
|
||||
Load m_load; /*< The worker load. */
|
||||
PrivateTimer* m_pTimer; /*< The worker's own timer. */
|
||||
DelayedCallsByTime m_sorted_calls; /*< Current delayed calls sorted by time. */
|
||||
DelayedCallsById m_calls; /*< Current delayed calls indexed by id. */
|
||||
|
||||
static uint32_t s_next_delayed_call_id; /*< The next delayed call id. */
|
||||
static uint32_t s_next_delayed_call_id; /*< The next delayed call id. */
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxbase/ccdefs.hh>
|
||||
|
||||
@ -80,5 +80,4 @@ private:
|
||||
private:
|
||||
int32_t m_count;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -17,93 +17,97 @@
|
||||
* @file atomic.c - Implementation of atomic operations
|
||||
*/
|
||||
|
||||
int atomic_add(int *variable, int value)
|
||||
int atomic_add(int* variable, int value)
|
||||
{
|
||||
return __atomic_fetch_add(variable, value, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
uint32_t atomic_add_uint32(uint32_t *variable, int32_t value)
|
||||
uint32_t atomic_add_uint32(uint32_t* variable, int32_t value)
|
||||
{
|
||||
return __atomic_fetch_add(variable, value, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
int64_t atomic_add_int64(int64_t *variable, int64_t value)
|
||||
int64_t atomic_add_int64(int64_t* variable, int64_t value)
|
||||
{
|
||||
return __atomic_fetch_add(variable, value, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
uint64_t atomic_add_uint64(uint64_t *variable, int64_t value)
|
||||
uint64_t atomic_add_uint64(uint64_t* variable, int64_t value)
|
||||
{
|
||||
return __atomic_fetch_add(variable, value, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
int atomic_load_int(const int *variable)
|
||||
int atomic_load_int(const int* variable)
|
||||
{
|
||||
return __atomic_load_n(variable, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
int32_t atomic_load_int32(const int32_t *variable)
|
||||
int32_t atomic_load_int32(const int32_t* variable)
|
||||
{
|
||||
return __atomic_load_n(variable, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
int64_t atomic_load_int64(const int64_t *variable)
|
||||
int64_t atomic_load_int64(const int64_t* variable)
|
||||
{
|
||||
return __atomic_load_n(variable, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
uint32_t atomic_load_uint32(const uint32_t *variable)
|
||||
uint32_t atomic_load_uint32(const uint32_t* variable)
|
||||
{
|
||||
return __atomic_load_n(variable, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
uint64_t atomic_load_uint64(const uint64_t *variable)
|
||||
uint64_t atomic_load_uint64(const uint64_t* variable)
|
||||
{
|
||||
return __atomic_load_n(variable, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
void* atomic_load_ptr(void * const *variable)
|
||||
void* atomic_load_ptr(void* const* variable)
|
||||
{
|
||||
return __atomic_load_n(variable, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
void atomic_store_int(int *variable, int value)
|
||||
void atomic_store_int(int* variable, int value)
|
||||
{
|
||||
__atomic_store_n(variable, value, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
void atomic_store_int32(int32_t *variable, int32_t value)
|
||||
void atomic_store_int32(int32_t* variable, int32_t value)
|
||||
{
|
||||
__atomic_store_n(variable, value, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
void atomic_store_int64(int64_t *variable, int64_t value)
|
||||
void atomic_store_int64(int64_t* variable, int64_t value)
|
||||
{
|
||||
__atomic_store_n(variable, value, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
void atomic_store_uint32(uint32_t *variable, uint32_t value)
|
||||
void atomic_store_uint32(uint32_t* variable, uint32_t value)
|
||||
{
|
||||
__atomic_store_n(variable, value, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
void atomic_store_uint64(uint64_t *variable, uint64_t value)
|
||||
void atomic_store_uint64(uint64_t* variable, uint64_t value)
|
||||
{
|
||||
__atomic_store_n(variable, value, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
void atomic_store_ptr(void **variable, void *value)
|
||||
void atomic_store_ptr(void** variable, void* value)
|
||||
{
|
||||
__atomic_store_n(variable, value, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
bool atomic_cas_ptr(void **variable, void** old_value, void *new_value)
|
||||
bool atomic_cas_ptr(void** variable, void** old_value, void* new_value)
|
||||
{
|
||||
return __atomic_compare_exchange_n(variable, old_value, new_value,
|
||||
false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
|
||||
return __atomic_compare_exchange_n(variable,
|
||||
old_value,
|
||||
new_value,
|
||||
false,
|
||||
__ATOMIC_SEQ_CST,
|
||||
__ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
int atomic_exchange_int(int *variable, int new_value)
|
||||
int atomic_exchange_int(int* variable, int new_value)
|
||||
{
|
||||
return __atomic_exchange_n(variable, new_value, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
@ -43,7 +43,7 @@ int CumulativeAverage::num_samples() const
|
||||
return m_num_samples;
|
||||
}
|
||||
|
||||
CumulativeAverage &CumulativeAverage::operator+=(const CumulativeAverage& rhs)
|
||||
CumulativeAverage& CumulativeAverage::operator+=(const CumulativeAverage& rhs)
|
||||
{
|
||||
this->add(rhs.m_ave, rhs.m_num_samples);
|
||||
return *this;
|
||||
@ -61,10 +61,10 @@ void CumulativeAverage::reset()
|
||||
m_num_last_added = 0;
|
||||
}
|
||||
|
||||
EMAverage::EMAverage(double min_alpha, double max_alpha, int sample_max) :
|
||||
m_min_alpha{min_alpha},
|
||||
m_max_alpha{max_alpha},
|
||||
m_sample_max{sample_max}
|
||||
EMAverage::EMAverage(double min_alpha, double max_alpha, int sample_max)
|
||||
: m_min_alpha{min_alpha}
|
||||
, m_max_alpha{max_alpha}
|
||||
, m_sample_max{sample_max}
|
||||
{
|
||||
}
|
||||
|
||||
@ -73,8 +73,8 @@ void EMAverage::add(double ave, int num_samples)
|
||||
// Give more weight to initial samples.
|
||||
int sample_max = std::min(m_num_samples ? m_num_samples : 1, m_sample_max);
|
||||
|
||||
double alpha = m_min_alpha + m_max_alpha *
|
||||
std::min(double(num_samples) / sample_max, 1.0);
|
||||
double alpha = m_min_alpha + m_max_alpha
|
||||
* std::min(double(num_samples) / sample_max, 1.0);
|
||||
|
||||
m_num_samples += num_samples;
|
||||
if (m_num_samples == num_samples)
|
||||
@ -117,6 +117,4 @@ void EMAverage::reset()
|
||||
m_ave = 0;
|
||||
m_num_samples = 0;
|
||||
}
|
||||
|
||||
|
||||
} // maxbase
|
||||
} // maxbase
|
||||
|
||||
@ -22,10 +22,10 @@
|
||||
namespace maxbase
|
||||
{
|
||||
|
||||
EventCount::EventCount(const std::string& event_id, Duration time_window, Duration granularity) :
|
||||
m_event_id(event_id),
|
||||
m_time_window(time_window),
|
||||
m_granularity(granularity.count())
|
||||
EventCount::EventCount(const std::string& event_id, Duration time_window, Duration granularity)
|
||||
: m_event_id(event_id)
|
||||
, m_time_window(time_window)
|
||||
, m_granularity(granularity.count())
|
||||
{
|
||||
increment();
|
||||
}
|
||||
@ -55,7 +55,9 @@ namespace
|
||||
struct TimePointLessEqual
|
||||
{
|
||||
TimePoint lhs;
|
||||
TimePointLessEqual(TimePoint tp) : lhs(tp) {}
|
||||
TimePointLessEqual(TimePoint tp) : lhs(tp)
|
||||
{
|
||||
}
|
||||
bool operator()(const EventCount::Timestamp& rhs) const
|
||||
{
|
||||
return lhs <= rhs.time_point;
|
||||
@ -72,7 +74,8 @@ void EventCount::purge() const
|
||||
StopWatch sw;
|
||||
auto windowBegin = Clock::now() - m_time_window;
|
||||
|
||||
auto ite = std::find_if(m_timestamps.begin(), m_timestamps.end(),
|
||||
auto ite = std::find_if(m_timestamps.begin(),
|
||||
m_timestamps.end(),
|
||||
TimePointLessEqual(windowBegin));
|
||||
m_timestamps.erase(m_timestamps.begin(), ite);
|
||||
}
|
||||
@ -89,7 +92,7 @@ int EventCount::count() const
|
||||
return count;
|
||||
}
|
||||
|
||||
void EventCount::dump(std::ostream &os) const
|
||||
void EventCount::dump(std::ostream& os) const
|
||||
{
|
||||
os << m_event_id << ": " << count() << " " << m_timestamps.size();
|
||||
}
|
||||
@ -104,14 +107,17 @@ std::ostream& operator<<(std::ostream& os, const EventCount& EventCount)
|
||||
// a client generates lots of events but rarely reads them back (purges).
|
||||
const int CleanupCountdown = 10000;
|
||||
|
||||
SessionCount::SessionCount(const std::string& sess_id, Duration time_window,
|
||||
Duration granularity) :
|
||||
m_sess_id(sess_id), m_time_window(time_window), m_granularity(granularity),
|
||||
m_cleanup_countdown(CleanupCountdown)
|
||||
SessionCount::SessionCount(const std::string& sess_id,
|
||||
Duration time_window,
|
||||
Duration granularity)
|
||||
: m_sess_id(sess_id)
|
||||
, m_time_window(time_window)
|
||||
, m_granularity(granularity)
|
||||
, m_cleanup_countdown(CleanupCountdown)
|
||||
{
|
||||
}
|
||||
|
||||
const std::vector<EventCount> &SessionCount::event_counts() const
|
||||
const std::vector<EventCount>& SessionCount::event_counts() const
|
||||
{
|
||||
purge();
|
||||
return m_event_counts;
|
||||
@ -128,7 +134,9 @@ namespace
|
||||
struct MatchEventId
|
||||
{
|
||||
std::string event_id;
|
||||
MatchEventId(const std::string& id) : event_id(id) {};
|
||||
MatchEventId(const std::string& id) : event_id(id)
|
||||
{
|
||||
}
|
||||
bool operator()(const EventCount& stats) const
|
||||
{
|
||||
return event_id == stats.event_id();
|
||||
@ -143,7 +151,8 @@ void SessionCount::increment(const std::string& event_id)
|
||||
|
||||
// Find in reverse, the entry is more likely to be towards the end. Actually no,
|
||||
// for some reason the normal search is slightly faster when measured.
|
||||
auto ite = find_if(m_event_counts.begin(), m_event_counts.end(),
|
||||
auto ite = find_if(m_event_counts.begin(),
|
||||
m_event_counts.end(),
|
||||
MatchEventId(event_id));
|
||||
if (ite == m_event_counts.end())
|
||||
{
|
||||
@ -221,7 +230,7 @@ void dump(std::ostream& os, const std::vector<SessionCount>& sessions)
|
||||
}
|
||||
}
|
||||
|
||||
void dumpTotals(std::ostream& os, const std::vector<SessionCount> &sessions)
|
||||
void dumpTotals(std::ostream& os, const std::vector<SessionCount>& sessions)
|
||||
{
|
||||
if (sessions.empty())
|
||||
{
|
||||
@ -251,15 +260,15 @@ void dumpTotals(std::ostream& os, const std::vector<SessionCount> &sessions)
|
||||
// EXTRA
|
||||
// This section needed for gcc 4.4, to use move semantics and variadics.
|
||||
|
||||
EventCount::EventCount(EventCount && ss) :
|
||||
m_event_id(std::move(ss.m_event_id)),
|
||||
m_time_window(std::move(ss.m_time_window)),
|
||||
m_granularity(std::move(ss.m_granularity)),
|
||||
m_timestamps(std::move(ss.m_timestamps))
|
||||
EventCount::EventCount(EventCount&& ss)
|
||||
: m_event_id(std::move(ss.m_event_id))
|
||||
, m_time_window(std::move(ss.m_time_window))
|
||||
, m_granularity(std::move(ss.m_granularity))
|
||||
, m_timestamps(std::move(ss.m_timestamps))
|
||||
{
|
||||
}
|
||||
|
||||
EventCount &EventCount::operator=(EventCount && ss)
|
||||
EventCount& EventCount::operator=(EventCount&& ss)
|
||||
{
|
||||
m_event_id = std::move(ss.m_event_id);
|
||||
m_time_window = std::move(ss.m_time_window);
|
||||
@ -268,16 +277,16 @@ EventCount &EventCount::operator=(EventCount && ss)
|
||||
return *this;
|
||||
}
|
||||
|
||||
SessionCount::SessionCount(SessionCount&& ss) :
|
||||
m_sess_id(std::move(ss.m_sess_id)),
|
||||
m_time_window(std::move(ss.m_time_window)),
|
||||
m_granularity(std::move(ss.m_granularity)),
|
||||
m_cleanup_countdown(std::move(ss.m_cleanup_countdown)),
|
||||
m_event_counts(std::move(ss.m_event_counts))
|
||||
SessionCount::SessionCount(SessionCount&& ss)
|
||||
: m_sess_id(std::move(ss.m_sess_id))
|
||||
, m_time_window(std::move(ss.m_time_window))
|
||||
, m_granularity(std::move(ss.m_granularity))
|
||||
, m_cleanup_countdown(std::move(ss.m_cleanup_countdown))
|
||||
, m_event_counts(std::move(ss.m_event_counts))
|
||||
{
|
||||
}
|
||||
|
||||
SessionCount & SessionCount::operator=(SessionCount&& ss)
|
||||
SessionCount& SessionCount::operator=(SessionCount&& ss)
|
||||
{
|
||||
m_sess_id = std::move(ss.m_sess_id);
|
||||
m_time_window = std::move(ss.m_time_window);
|
||||
@ -287,4 +296,4 @@ SessionCount & SessionCount::operator=(SessionCount&& ss)
|
||||
|
||||
return *this;
|
||||
}
|
||||
} // maxbase
|
||||
} // maxbase
|
||||
|
||||
@ -41,7 +41,7 @@ namespace
|
||||
int DEFAULT_LOG_AUGMENTATION = 0;
|
||||
|
||||
// A message that is logged 10 times in 1 second will be suppressed for 10 seconds.
|
||||
static MXB_LOG_THROTTLING DEFAULT_LOG_THROTTLING = { 10, 1000, 10000 };
|
||||
static MXB_LOG_THROTTLING DEFAULT_LOG_THROTTLING = {10, 1000, 10000};
|
||||
|
||||
// BUFSIZ comes from the system. It equals with block size or its multiplication.
|
||||
const int MAX_LOGSTRLEN = BUFSIZ;
|
||||
@ -62,14 +62,26 @@ std::string get_timestamp(void)
|
||||
struct tm tm;
|
||||
localtime_r(&t, &tm);
|
||||
static const char timestamp_formatstr[] = "%04d-%02d-%02d %02d:%02d:%02d ";
|
||||
static int required = snprintf(NULL, 0, timestamp_formatstr,
|
||||
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
|
||||
tm.tm_min, tm.tm_sec);
|
||||
static int required = snprintf(NULL,
|
||||
0,
|
||||
timestamp_formatstr,
|
||||
tm.tm_year + 1900,
|
||||
tm.tm_mon + 1,
|
||||
tm.tm_mday,
|
||||
tm.tm_hour,
|
||||
tm.tm_min,
|
||||
tm.tm_sec);
|
||||
char buf[required + 1];
|
||||
|
||||
snprintf(buf, sizeof(buf), timestamp_formatstr,
|
||||
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
|
||||
tm.tm_min, tm.tm_sec);
|
||||
snprintf(buf,
|
||||
sizeof(buf),
|
||||
timestamp_formatstr,
|
||||
tm.tm_year + 1900,
|
||||
tm.tm_mon + 1,
|
||||
tm.tm_mday,
|
||||
tm.tm_hour,
|
||||
tm.tm_min,
|
||||
tm.tm_sec);
|
||||
|
||||
return buf;
|
||||
}
|
||||
@ -84,33 +96,47 @@ std::string get_timestamp_hp(void)
|
||||
int usec = tv.tv_usec / 1000;
|
||||
|
||||
static const char timestamp_formatstr_hp[] = "%04d-%02d-%02d %02d:%02d:%02d.%03d ";
|
||||
static int required = snprintf(NULL, 0, timestamp_formatstr_hp,
|
||||
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
|
||||
tm.tm_hour, tm.tm_min, tm.tm_sec, usec);
|
||||
static int required = snprintf(NULL,
|
||||
0,
|
||||
timestamp_formatstr_hp,
|
||||
tm.tm_year + 1900,
|
||||
tm.tm_mon + 1,
|
||||
tm.tm_mday,
|
||||
tm.tm_hour,
|
||||
tm.tm_min,
|
||||
tm.tm_sec,
|
||||
usec);
|
||||
|
||||
char buf[required + 1];
|
||||
|
||||
snprintf(buf, sizeof(buf), timestamp_formatstr_hp,
|
||||
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
|
||||
tm.tm_hour, tm.tm_min, tm.tm_sec, usec);
|
||||
snprintf(buf,
|
||||
sizeof(buf),
|
||||
timestamp_formatstr_hp,
|
||||
tm.tm_year + 1900,
|
||||
tm.tm_mon + 1,
|
||||
tm.tm_mday,
|
||||
tm.tm_hour,
|
||||
tm.tm_min,
|
||||
tm.tm_sec,
|
||||
usec);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
struct LOG_PREFIX
|
||||
{
|
||||
const char* text; // The prefix, e.g. "error: "
|
||||
int len; // The length of the prefix without the trailing NULL.
|
||||
const char* text; // The prefix, e.g. "error: "
|
||||
int len; // The length of the prefix without the trailing NULL.
|
||||
};
|
||||
|
||||
const char PREFIX_EMERG[] = "emerg : ";
|
||||
const char PREFIX_ALERT[] = "alert : ";
|
||||
const char PREFIX_CRIT[] = "crit : ";
|
||||
const char PREFIX_ERROR[] = "error : ";
|
||||
const char PREFIX_EMERG[] = "emerg : ";
|
||||
const char PREFIX_ALERT[] = "alert : ";
|
||||
const char PREFIX_CRIT[] = "crit : ";
|
||||
const char PREFIX_ERROR[] = "error : ";
|
||||
const char PREFIX_WARNING[] = "warning: ";
|
||||
const char PREFIX_NOTICE[] = "notice : ";
|
||||
const char PREFIX_INFO[] = "info : ";
|
||||
const char PREFIX_DEBUG[] = "debug : ";
|
||||
const char PREFIX_NOTICE[] = "notice : ";
|
||||
const char PREFIX_INFO[] = "info : ";
|
||||
const char PREFIX_DEBUG[] = "debug : ";
|
||||
|
||||
LOG_PREFIX level_to_prefix(int level)
|
||||
{
|
||||
@ -167,16 +193,16 @@ LOG_PREFIX level_to_prefix(int level)
|
||||
break;
|
||||
}
|
||||
|
||||
--prefix.len; // Remove trailing NULL.
|
||||
--prefix.len; // Remove trailing NULL.
|
||||
|
||||
return prefix;
|
||||
}
|
||||
|
||||
enum message_suppression_t
|
||||
{
|
||||
MESSAGE_NOT_SUPPRESSED, // Message is not suppressed.
|
||||
MESSAGE_SUPPRESSED, // Message is suppressed for the first time (for this round)
|
||||
MESSAGE_STILL_SUPPRESSED // Message is still suppressed (for this round)
|
||||
MESSAGE_NOT_SUPPRESSED, // Message is not suppressed.
|
||||
MESSAGE_SUPPRESSED, // Message is suppressed for the first time (for this round)
|
||||
MESSAGE_STILL_SUPPRESSED // Message is still suppressed (for this round)
|
||||
};
|
||||
|
||||
class MessageRegistryKey
|
||||
@ -200,9 +226,8 @@ public:
|
||||
|
||||
bool eq(const MessageRegistryKey& other) const
|
||||
{
|
||||
return
|
||||
filename == other.filename && // Yes, we compare the pointer values and not the strings.
|
||||
linenumber == other.linenumber;
|
||||
return filename == other.filename // Yes, we compare the pointer values and not the strings.
|
||||
&& linenumber == other.linenumber;
|
||||
}
|
||||
|
||||
size_t hash() const
|
||||
@ -212,7 +237,7 @@ public:
|
||||
* https://en.wikipedia.org/wiki/Jenkins_hash_function
|
||||
*/
|
||||
uint64_t key1 = (uint64_t)filename;
|
||||
uint16_t key2 = (uint16_t)linenumber; // The first 48 bits are likely to be 0.
|
||||
uint16_t key2 = (uint16_t)linenumber; // The first 48 bits are likely to be 0.
|
||||
|
||||
uint32_t hash_value = 0;
|
||||
size_t i;
|
||||
@ -313,11 +338,10 @@ public:
|
||||
|
||||
private:
|
||||
std::mutex m_lock;
|
||||
uint64_t m_first_ms; /** The time when the error was logged the first time in this window. */
|
||||
uint64_t m_last_ms; /** The time when the error was logged the last time. */
|
||||
size_t m_count; /** How many times the error has been reported within this window. */
|
||||
uint64_t m_first_ms; /** The time when the error was logged the first time in this window. */
|
||||
uint64_t m_last_ms; /** The time when the error was logged the last time. */
|
||||
size_t m_count; /** How many times the error has been reported within this window. */
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace std
|
||||
@ -347,7 +371,6 @@ struct equal_to<MessageRegistryKey>
|
||||
return lhs.eq(rhs);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace
|
||||
@ -357,21 +380,21 @@ class MessageRegistry;
|
||||
|
||||
struct this_unit
|
||||
{
|
||||
int augmentation; // Can change during the lifetime of log_manager.
|
||||
bool do_highprecision; // Can change during the lifetime of log_manager.
|
||||
bool do_syslog; // Can change during the lifetime of log_manager.
|
||||
bool do_maxlog; // Can change during the lifetime of log_manager.
|
||||
MXB_LOG_THROTTLING throttling; // Can change during the lifetime of log_manager.
|
||||
int augmentation; // Can change during the lifetime of log_manager.
|
||||
bool do_highprecision; // Can change during the lifetime of log_manager.
|
||||
bool do_syslog; // Can change during the lifetime of log_manager.
|
||||
bool do_maxlog; // Can change during the lifetime of log_manager.
|
||||
MXB_LOG_THROTTLING throttling; // Can change during the lifetime of log_manager.
|
||||
std::unique_ptr<mxb::Logger> sLogger;
|
||||
std::unique_ptr<MessageRegistry> sMessage_registry;
|
||||
size_t (*context_provider)(char* buffer, size_t len);
|
||||
size_t (* context_provider)(char* buffer, size_t len);
|
||||
} this_unit =
|
||||
{
|
||||
DEFAULT_LOG_AUGMENTATION, // augmentation
|
||||
false, // do_highprecision
|
||||
true, // do_syslog
|
||||
true, // do_maxlog
|
||||
DEFAULT_LOG_THROTTLING, // throttling
|
||||
DEFAULT_LOG_AUGMENTATION, // augmentation
|
||||
false, // do_highprecision
|
||||
true, // do_syslog
|
||||
true, // do_maxlog
|
||||
DEFAULT_LOG_THROTTLING, // throttling
|
||||
};
|
||||
|
||||
class MessageRegistry
|
||||
@ -417,7 +440,6 @@ private:
|
||||
std::mutex m_lock;
|
||||
std::unordered_map<Key, Stats> m_registry;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
bool mxb_log_init(const char* ident,
|
||||
@ -457,22 +479,22 @@ bool mxb_log_init(const char* ident,
|
||||
filepath = std::string(logdir) + "/" + suffix;
|
||||
}
|
||||
|
||||
this_unit.sMessage_registry.reset(new (std::nothrow) MessageRegistry);
|
||||
this_unit.sMessage_registry.reset(new( std::nothrow) MessageRegistry);
|
||||
|
||||
switch (target)
|
||||
{
|
||||
case MXB_LOG_TARGET_FS:
|
||||
case MXB_LOG_TARGET_DEFAULT:
|
||||
this_unit.sLogger = mxb::FileLogger::create(filepath);
|
||||
break;
|
||||
case MXB_LOG_TARGET_FS:
|
||||
case MXB_LOG_TARGET_DEFAULT:
|
||||
this_unit.sLogger = mxb::FileLogger::create(filepath);
|
||||
break;
|
||||
|
||||
case MXB_LOG_TARGET_STDOUT:
|
||||
this_unit.sLogger = mxb::StdoutLogger::create(filepath);
|
||||
break;
|
||||
case MXB_LOG_TARGET_STDOUT:
|
||||
this_unit.sLogger = mxb::StdoutLogger::create(filepath);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(!true);
|
||||
break;
|
||||
default:
|
||||
assert(!true);
|
||||
break;
|
||||
}
|
||||
|
||||
if (this_unit.sLogger && this_unit.sMessage_registry)
|
||||
@ -552,9 +574,9 @@ void mxb_log_set_throttling(const MXB_LOG_THROTTLING* throttling)
|
||||
// is used right when its values are modified.
|
||||
this_unit.throttling = *throttling;
|
||||
|
||||
if ((this_unit.throttling.count == 0) ||
|
||||
(this_unit.throttling.window_ms == 0) ||
|
||||
(this_unit.throttling.suppress_ms == 0))
|
||||
if ((this_unit.throttling.count == 0)
|
||||
|| (this_unit.throttling.window_ms == 0)
|
||||
|| (this_unit.throttling.suppress_ms == 0))
|
||||
{
|
||||
MXB_NOTICE("Log throttling has been disabled.");
|
||||
}
|
||||
@ -592,20 +614,28 @@ static const char* level_to_string(int level)
|
||||
{
|
||||
case LOG_EMERG:
|
||||
return "emergency";
|
||||
|
||||
case LOG_ALERT:
|
||||
return "alert";
|
||||
|
||||
case LOG_CRIT:
|
||||
return "critical";
|
||||
|
||||
case LOG_ERR:
|
||||
return "error";
|
||||
|
||||
case LOG_WARNING:
|
||||
return "warning";
|
||||
|
||||
case LOG_NOTICE:
|
||||
return "notice";
|
||||
|
||||
case LOG_INFO:
|
||||
return "informational";
|
||||
|
||||
case LOG_DEBUG:
|
||||
return "debug";
|
||||
|
||||
default:
|
||||
assert(!true);
|
||||
return "unknown";
|
||||
@ -643,8 +673,11 @@ bool mxb_log_set_priority_enabled(int level, bool enable)
|
||||
|
||||
int mxb_log_message(int priority,
|
||||
const char* modname,
|
||||
const char* file, int line, const char* function,
|
||||
const char* format, ...)
|
||||
const char* file,
|
||||
int line,
|
||||
const char* function,
|
||||
const char* format,
|
||||
...)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
@ -653,7 +686,7 @@ int mxb_log_message(int priority,
|
||||
|
||||
int level = priority & LOG_PRIMASK;
|
||||
|
||||
if ((priority & ~(LOG_PRIMASK | LOG_FACMASK)) == 0) // Check that the priority is ok,
|
||||
if ((priority & ~(LOG_PRIMASK | LOG_FACMASK)) == 0) // Check that the priority is ok,
|
||||
{
|
||||
message_suppression_t status = MESSAGE_NOT_SUPPRESSED;
|
||||
|
||||
@ -671,7 +704,7 @@ int mxb_log_message(int priority,
|
||||
{
|
||||
va_list valist;
|
||||
|
||||
char context[32]; // The documentation will guarantee a buffer of at least 32 bytes.
|
||||
char context[32]; // The documentation will guarantee a buffer of at least 32 bytes.
|
||||
int context_len = 0;
|
||||
|
||||
if (this_unit.context_provider)
|
||||
@ -680,21 +713,21 @@ int mxb_log_message(int priority,
|
||||
|
||||
if (context_len != 0)
|
||||
{
|
||||
context_len += 3; // The added "() "
|
||||
context_len += 3; // The added "() "
|
||||
}
|
||||
}
|
||||
|
||||
int modname_len = modname ? strlen(modname) + 3 : 0; // +3 due to "[...] "
|
||||
int modname_len = modname ? strlen(modname) + 3 : 0; // +3 due to "[...] "
|
||||
|
||||
static const char SUPPRESSION[] =
|
||||
" (subsequent similar messages suppressed for %lu milliseconds)";
|
||||
static const char SUPPRESSION[]
|
||||
= " (subsequent similar messages suppressed for %lu milliseconds)";
|
||||
int suppression_len = 0;
|
||||
size_t suppress_ms = this_unit.throttling.suppress_ms;
|
||||
|
||||
if (status == MESSAGE_SUPPRESSED)
|
||||
{
|
||||
suppression_len += sizeof(SUPPRESSION) - 1; // Remove trailing NULL
|
||||
suppression_len -= 3; // Remove the %lu
|
||||
suppression_len -= 3; // Remove the %lu
|
||||
suppression_len += UINTLEN(suppress_ms);
|
||||
}
|
||||
|
||||
@ -719,7 +752,7 @@ int mxb_log_message(int priority,
|
||||
{
|
||||
case MXB_LOG_AUGMENT_WITH_FUNCTION:
|
||||
augmentation_len = sizeof(FORMAT_FUNCTION) - 1; // Remove trailing 0
|
||||
augmentation_len -= 2; // Remove the %s
|
||||
augmentation_len -= 2; // Remove the %s
|
||||
augmentation_len += strlen(function);
|
||||
break;
|
||||
|
||||
@ -740,18 +773,18 @@ int mxb_log_message(int priority,
|
||||
message_len -= (buffer_len - MAX_LOGSTRLEN);
|
||||
buffer_len = MAX_LOGSTRLEN;
|
||||
|
||||
assert(prefix.len + context_len + modname_len +
|
||||
augmentation_len + message_len + suppression_len == buffer_len);
|
||||
assert(prefix.len + context_len + modname_len
|
||||
+ augmentation_len + message_len + suppression_len == buffer_len);
|
||||
}
|
||||
|
||||
char buffer[buffer_len + 1];
|
||||
|
||||
char *prefix_text = buffer;
|
||||
char *context_text = prefix_text + prefix.len;
|
||||
char *modname_text = context_text + context_len;
|
||||
char *augmentation_text = modname_text + modname_len;
|
||||
char *message_text = augmentation_text + augmentation_len;
|
||||
char *suppression_text = message_text + message_len;
|
||||
char* prefix_text = buffer;
|
||||
char* context_text = prefix_text + prefix.len;
|
||||
char* modname_text = context_text + context_len;
|
||||
char* augmentation_text = modname_text + modname_len;
|
||||
char* message_text = augmentation_text + augmentation_len;
|
||||
char* suppression_text = message_text + message_len;
|
||||
|
||||
strcpy(prefix_text, prefix.text);
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
*
|
||||
* For obvious reasons, it cannot use its own functions for reporting errors.
|
||||
*/
|
||||
#define LOG_ERROR(format, ...) do { fprintf(stderr, format, ##__VA_ARGS__); } while (false)
|
||||
#define LOG_ERROR(format, ...) do {fprintf(stderr, format, ##__VA_ARGS__);} while (false)
|
||||
|
||||
//
|
||||
// Helper functions
|
||||
@ -40,7 +40,8 @@ namespace
|
||||
|
||||
int open_fd(const std::string& filename)
|
||||
{
|
||||
int fd = open(filename.c_str(), O_WRONLY | O_APPEND | O_CREAT,
|
||||
int fd = open(filename.c_str(),
|
||||
O_WRONLY | O_APPEND | O_CREAT,
|
||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
|
||||
|
||||
if (fd == -1)
|
||||
@ -85,7 +86,6 @@ std::string get_ident()
|
||||
|
||||
return this_unit.ident;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace maxbase
|
||||
@ -108,7 +108,7 @@ std::unique_ptr<Logger> FileLogger::create(const std::string& filename)
|
||||
|
||||
if (fd != -1)
|
||||
{
|
||||
logger.reset(new (std::nothrow) FileLogger(fd, filename));
|
||||
logger.reset(new( std::nothrow) FileLogger(fd, filename));
|
||||
|
||||
if (logger)
|
||||
{
|
||||
@ -151,7 +151,7 @@ bool FileLogger::write(const char* msg, int len)
|
||||
|
||||
if (rc == -1)
|
||||
{
|
||||
if (should_log_error()) // Coarse error suppression
|
||||
if (should_log_error()) // Coarse error suppression
|
||||
{
|
||||
LOG_ERROR("Failed to write to log: %d, %s\n", errno, mxb_strerror(errno));
|
||||
}
|
||||
@ -186,9 +186,9 @@ bool FileLogger::rotate()
|
||||
// Private methods
|
||||
//
|
||||
|
||||
FileLogger::FileLogger(int fd, const std::string& filename):
|
||||
Logger(filename),
|
||||
m_fd(fd)
|
||||
FileLogger::FileLogger(int fd, const std::string& filename)
|
||||
: Logger(filename)
|
||||
, m_fd(fd)
|
||||
{
|
||||
}
|
||||
|
||||
@ -207,25 +207,27 @@ bool FileLogger::write_header()
|
||||
localtime_r(&t, &tm);
|
||||
|
||||
std::string ident = get_ident();
|
||||
char time_string[32]; // 26 would be enough, according to "man asctime".
|
||||
char time_string[32]; // 26 would be enough, according to "man asctime".
|
||||
asctime_r(&tm, time_string);
|
||||
|
||||
size_t size = ident.length() + 2 * sizeof(' ') + m_filename.length() + 2 * sizeof(' ') + strlen(time_string);
|
||||
size_t size = ident.length() + 2 * sizeof(' ') + m_filename.length() + 2 * sizeof(' ') + strlen(
|
||||
time_string);
|
||||
|
||||
char header[size + 2 + 1]; // For the 2 newlines and the trailing NULL.
|
||||
char header[size + 2 + 1]; // For the 2 newlines and the trailing NULL.
|
||||
sprintf(header, "\n\n%s %s %s", ident.c_str(), m_filename.c_str(), time_string);
|
||||
|
||||
char line[sizeof(header) - 1];
|
||||
memset(line, '-', sizeof(line) - 1);
|
||||
line[sizeof(line) - 1] = '\n';
|
||||
|
||||
bool ok = ::write(m_fd, header, sizeof(header) - 1) != -1 &&
|
||||
::write(m_fd, line, sizeof(line)) != -1;
|
||||
bool ok = ::write(m_fd, header, sizeof(header) - 1) != -1
|
||||
&& ::write(m_fd, line, sizeof(line)) != -1;
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
LOG_ERROR("Error: Writing log header failed due to %d, %s\n",
|
||||
errno, mxb_strerror(errno));
|
||||
errno,
|
||||
mxb_strerror(errno));
|
||||
}
|
||||
|
||||
return ok;
|
||||
@ -239,10 +241,16 @@ bool FileLogger::write_footer(const char* suffix)
|
||||
localtime_r(&t, &tm);
|
||||
|
||||
const char FORMAT[] = "%04d-%02d-%02d %02d:%02d:%02d";
|
||||
char time_string[20]; // 19 chars + NULL.
|
||||
char time_string[20]; // 19 chars + NULL.
|
||||
|
||||
sprintf(time_string, FORMAT,
|
||||
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
|
||||
sprintf(time_string,
|
||||
FORMAT,
|
||||
tm.tm_year + 1900,
|
||||
tm.tm_mon + 1,
|
||||
tm.tm_mday,
|
||||
tm.tm_hour,
|
||||
tm.tm_min,
|
||||
tm.tm_sec);
|
||||
|
||||
size_t size = sizeof(time_string) + 3 * sizeof(' ') + strlen(suffix) + sizeof('\n');
|
||||
|
||||
@ -253,16 +261,16 @@ bool FileLogger::write_footer(const char* suffix)
|
||||
memset(line, '-', sizeof(line) - 1);
|
||||
line[sizeof(line) - 1] = '\n';
|
||||
|
||||
bool ok = ::write(m_fd, header, sizeof(header) - 1) != -1 &&
|
||||
::write(m_fd, line, sizeof(line)) != -1;
|
||||
bool ok = ::write(m_fd, header, sizeof(header) - 1) != -1
|
||||
&& ::write(m_fd, line, sizeof(line)) != -1;
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
LOG_ERROR("Error: Writing log footer failed due to %d, %s\n",
|
||||
errno, mxb_strerror(errno));
|
||||
errno,
|
||||
mxb_strerror(errno));
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -65,8 +65,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
typedef bool (*init_function_t)();
|
||||
typedef void (*finish_function_t)();
|
||||
typedef bool (* init_function_t)();
|
||||
typedef void (* finish_function_t)();
|
||||
|
||||
struct component_t
|
||||
{
|
||||
@ -78,7 +78,7 @@ private:
|
||||
static int s_nComponents;
|
||||
};
|
||||
|
||||
#define MAXBASE_COMPONENT(X) { &X::init, &X::finish }
|
||||
#define MAXBASE_COMPONENT(X) {&X::init, &X::finish}
|
||||
|
||||
Initer::component_t Initer::s_components[] =
|
||||
{
|
||||
@ -103,9 +103,9 @@ MaxBase::MaxBase(const char* zIdent,
|
||||
|
||||
if (!m_log_inited)
|
||||
{
|
||||
zMessage =
|
||||
"The initialization of the MaxScale base library succeeded, but the "
|
||||
"initialization of the MaxScale log failed.";
|
||||
zMessage
|
||||
= "The initialization of the MaxScale base library succeeded, but the "
|
||||
"initialization of the MaxScale log failed.";
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -160,7 +160,6 @@ void finish()
|
||||
{
|
||||
Initer::finish();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool maxbase_init()
|
||||
|
||||
@ -36,7 +36,7 @@ static struct
|
||||
|
||||
int get_pipe_max_size()
|
||||
{
|
||||
int size = 65536; // Default value from pipe(7)
|
||||
int size = 65536; // Default value from pipe(7)
|
||||
std::ifstream file("/proc/sys/fs/pipe-max-size");
|
||||
|
||||
if (file.good())
|
||||
@ -46,7 +46,6 @@ int get_pipe_max_size()
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace maxbase
|
||||
@ -75,7 +74,7 @@ MessageQueue::~MessageQueue()
|
||||
close(m_write_fd);
|
||||
}
|
||||
|
||||
//static
|
||||
// static
|
||||
bool MessageQueue::init()
|
||||
{
|
||||
mxb_assert(!this_unit.initialized);
|
||||
@ -86,14 +85,14 @@ bool MessageQueue::init()
|
||||
return this_unit.initialized;
|
||||
}
|
||||
|
||||
//static
|
||||
// static
|
||||
void MessageQueue::finish()
|
||||
{
|
||||
mxb_assert(this_unit.initialized);
|
||||
this_unit.initialized = false;
|
||||
}
|
||||
|
||||
//static
|
||||
// static
|
||||
MessageQueue* MessageQueue::create(Handler* pHandler)
|
||||
{
|
||||
mxb_assert(this_unit.initialized);
|
||||
@ -148,10 +147,12 @@ MessageQueue* MessageQueue::create(Handler* pHandler)
|
||||
if (fcntl(fds[0], F_SETPIPE_SZ, this_unit.pipe_max_size) == -1)
|
||||
{
|
||||
MXB_WARNING("Failed to increase pipe buffer size to '%d': %d, %s",
|
||||
this_unit.pipe_max_size, errno, mxb_strerror(errno));
|
||||
this_unit.pipe_max_size,
|
||||
errno,
|
||||
mxb_strerror(errno));
|
||||
}
|
||||
#endif
|
||||
pThis = new (std::nothrow) MessageQueue(pHandler, read_fd, write_fd);
|
||||
pThis = new( std::nothrow) MessageQueue(pHandler, read_fd, write_fd);
|
||||
|
||||
if (!pThis)
|
||||
{
|
||||
@ -303,7 +304,9 @@ uint32_t MessageQueue::handle_poll_events(Worker* pWorker, uint32_t events)
|
||||
// mode we continue reading in order to empty the pipe as otherwise the
|
||||
// thread may hang.
|
||||
MXB_ERROR("MessageQueue could only read %ld bytes from pipe, although "
|
||||
"expected %lu bytes.", n, sizeof(message));
|
||||
"expected %lu bytes.",
|
||||
n,
|
||||
sizeof(message));
|
||||
mxb_assert(!true);
|
||||
}
|
||||
}
|
||||
@ -315,12 +318,11 @@ uint32_t MessageQueue::handle_poll_events(Worker* pWorker, uint32_t events)
|
||||
return rc;
|
||||
}
|
||||
|
||||
//static
|
||||
// static
|
||||
uint32_t MessageQueue::poll_handler(MXB_POLL_DATA* pData, MXB_WORKER* pWorker, uint32_t events)
|
||||
{
|
||||
MessageQueue* pThis = static_cast<MessageQueue*>(pData);
|
||||
|
||||
return pThis->handle_poll_events(static_cast<Worker*>(pWorker), events);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -17,9 +17,9 @@
|
||||
namespace maxbase
|
||||
{
|
||||
|
||||
//static
|
||||
// static
|
||||
void Semaphore::get_current_timespec(time_t seconds,
|
||||
long nseconds,
|
||||
long nseconds,
|
||||
timespec* pTs)
|
||||
{
|
||||
mxb_assert(nseconds <= 999999999);
|
||||
@ -41,5 +41,4 @@ void Semaphore::get_current_timespec(time_t seconds,
|
||||
|
||||
ts.tv_nsec = nseconds_sum;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -93,17 +93,21 @@ static void extract_file_and_line(const char* symbols, char* cmd, size_t size)
|
||||
snprintf(offset, sizeof(offset), "%.*s", (int)(symname_end - addr_offset), addr_offset);
|
||||
|
||||
// Get the hexadecimal address of the symbol
|
||||
get_command_output(cmd, size,
|
||||
get_command_output(cmd,
|
||||
size,
|
||||
"nm %s |grep ' %s$'|sed -e 's/ .*//' -e 's/^/0x/'",
|
||||
filename, symname);
|
||||
filename,
|
||||
symname);
|
||||
long long symaddr = strtoll(cmd, NULL, 16);
|
||||
long long offsetaddr = strtoll(offset, NULL, 16);
|
||||
|
||||
// Calculate the file and line now that we have the raw offset into
|
||||
// the library
|
||||
get_command_output(cmd, size,
|
||||
get_command_output(cmd,
|
||||
size,
|
||||
"addr2line -e %s 0x%x",
|
||||
filename, symaddr + offsetaddr);
|
||||
filename,
|
||||
symaddr + offsetaddr);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -114,7 +118,6 @@ static void extract_file_and_line(const char* symbols, char* cmd, size_t size)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace maxbase
|
||||
@ -122,7 +125,7 @@ namespace maxbase
|
||||
|
||||
void dump_stacktrace(std::function<void(const char*, const char*)> handler)
|
||||
{
|
||||
void *addrs[128];
|
||||
void* addrs[128];
|
||||
int count = backtrace(addrs, 128);
|
||||
char** symbols = backtrace_symbols(addrs, count);
|
||||
|
||||
@ -138,11 +141,12 @@ void dump_stacktrace(std::function<void(const char*, const char*)> handler)
|
||||
}
|
||||
}
|
||||
|
||||
void dump_stacktrace(void (*handler)(const char* symbol, const char* command))
|
||||
void dump_stacktrace(void (* handler)(const char* symbol, const char* command))
|
||||
{
|
||||
dump_stacktrace([&](const char* symbol, const char* command){handler(symbol, command);});
|
||||
dump_stacktrace([&](const char* symbol, const char* command) {
|
||||
handler(symbol, command);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
@ -150,11 +154,10 @@ void dump_stacktrace(void (*handler)(const char* symbol, const char* command))
|
||||
namespace maxbase
|
||||
{
|
||||
|
||||
void dump_stacktrace(void (*handler)(const char*, const char*))
|
||||
void dump_stacktrace(void (* handler)(const char*, const char*))
|
||||
{
|
||||
// We can't dump stacktraces on non-GLIBC systems
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -38,7 +38,7 @@ Duration StopWatch::restart()
|
||||
m_start = now;
|
||||
return lap;
|
||||
}
|
||||
} // maxbase
|
||||
} // maxbase
|
||||
|
||||
/********** OUTPUT ***********/
|
||||
namespace
|
||||
@ -46,21 +46,20 @@ namespace
|
||||
using namespace maxbase;
|
||||
struct TimeConvert
|
||||
{
|
||||
double div; // divide the value of the previous unit by this
|
||||
std::string suffix; // milliseconds, hours etc.
|
||||
double max_visual; // threashold to switch to the next unit
|
||||
double div; // divide the value of the previous unit by this
|
||||
std::string suffix; // milliseconds, hours etc.
|
||||
double max_visual; // threashold to switch to the next unit
|
||||
};
|
||||
// Will never get to centuries because the duration is a long carrying nanoseconds
|
||||
TimeConvert convert[]
|
||||
{
|
||||
{1, "ns", 1000}, {1000, "us", 1000}, {1000, "ms", 1000},
|
||||
{1, "ns", 1000}, {1000, "us", 1000}, {1000, "ms", 1000},
|
||||
{1000, "s", 60}, {60, "min", 60}, {60, "hours", 24},
|
||||
{24, "days", 365.25}, {365.25, "years", 10000},
|
||||
{100, "centuries", std::numeric_limits<double>::max()}
|
||||
};
|
||||
|
||||
int convert_size = sizeof(convert) / sizeof(convert[0]);
|
||||
|
||||
}
|
||||
|
||||
namespace maxbase
|
||||
@ -87,7 +86,7 @@ std::pair<double, std::string> dur_to_human_readable(Duration dur)
|
||||
}
|
||||
}
|
||||
|
||||
abort(); // should never get here
|
||||
abort(); // should never get here
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, Duration dur)
|
||||
@ -101,13 +100,13 @@ std::ostream& operator<<(std::ostream& os, Duration dur)
|
||||
// TODO: this will require some thought. time_point_to_string() for a system_clock is
|
||||
// obvious, but not so for a steady_clock. Maybe TimePoint belongs to a system clock
|
||||
// and sould be called something else here, and live in a time_measuring namespace.
|
||||
std::string time_point_to_string(TimePoint tp, const std::string &fmt)
|
||||
std::string time_point_to_string(TimePoint tp, const std::string& fmt)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
std::time_t timet = system_clock::to_time_t(system_clock::now()
|
||||
+ (tp - Clock::now()));
|
||||
|
||||
struct tm * ptm;
|
||||
struct tm* ptm;
|
||||
ptm = gmtime (&timet);
|
||||
const int sz = 1024;
|
||||
char buf[sz];
|
||||
@ -115,30 +114,30 @@ std::string time_point_to_string(TimePoint tp, const std::string &fmt)
|
||||
return buf;
|
||||
}
|
||||
|
||||
std::ostream & operator<<(std::ostream & os, TimePoint tp)
|
||||
std::ostream& operator<<(std::ostream& os, TimePoint tp)
|
||||
{
|
||||
os << time_point_to_string(tp);
|
||||
return os;
|
||||
}
|
||||
|
||||
void test_stopwatch_output(std::ostream & os)
|
||||
void test_stopwatch_output(std::ostream& os)
|
||||
{
|
||||
long long dur[] =
|
||||
{
|
||||
400, // 400ns
|
||||
5 * 1000, // 5us
|
||||
500 * 1000, // 500us
|
||||
1 * 1000000, // 1ms
|
||||
700 * 1000000LL, // 700ms
|
||||
5 * 1000000000LL, // 5s
|
||||
200 * 1000000000LL, // 200s
|
||||
5 * 60 * 1000000000LL, // 5m
|
||||
45 * 60 * 1000000000LL, // 45m
|
||||
130 * 60 * 1000000000LL, // 130m
|
||||
24 * 60 * 60 * 1000000000LL, // 24 hours
|
||||
3 * 24 * 60 * 60 * 1000000000LL, // 72 hours
|
||||
180 * 24 * 60 * 60 * 1000000000LL, // 180 days
|
||||
1000 * 24 * 60 * 60 * 1000000000LL // 1000 days
|
||||
400, // 400ns
|
||||
5 * 1000, // 5us
|
||||
500 * 1000, // 500us
|
||||
1 * 1000000, // 1ms
|
||||
700 * 1000000LL, // 700ms
|
||||
5 * 1000000000LL, // 5s
|
||||
200 * 1000000000LL, // 200s
|
||||
5 * 60 * 1000000000LL, // 5m
|
||||
45 * 60 * 1000000000LL, // 45m
|
||||
130 * 60 * 1000000000LL, // 130m
|
||||
24 * 60 * 60 * 1000000000LL, // 24 hours
|
||||
3 * 24 * 60 * 60 * 1000000000LL, // 72 hours
|
||||
180 * 24 * 60 * 60 * 1000000000LL, // 180 days
|
||||
1000 * 24 * 60 * 60 * 1000000000LL // 1000 days
|
||||
};
|
||||
|
||||
for (unsigned i = 0; i < sizeof(dur) / sizeof(dur[0]); ++i)
|
||||
@ -146,4 +145,4 @@ void test_stopwatch_output(std::ostream & os)
|
||||
os << Duration(dur[i]) << std::endl;
|
||||
}
|
||||
}
|
||||
} // maxbase
|
||||
} // maxbase
|
||||
|
||||
@ -18,8 +18,7 @@
|
||||
namespace
|
||||
{
|
||||
|
||||
thread_local char errbuf[512]; // Enough for all errors
|
||||
|
||||
thread_local char errbuf[512]; // Enough for all errors
|
||||
}
|
||||
|
||||
const char* mxb_strerror(int error)
|
||||
|
||||
@ -11,10 +11,10 @@
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
#if !defined(SS_DEBUG)
|
||||
#if !defined (SS_DEBUG)
|
||||
#define SS_DEBUG
|
||||
#endif
|
||||
#if defined(NDEBUG)
|
||||
#if defined (NDEBUG)
|
||||
#undef NDEBUG
|
||||
#endif
|
||||
|
||||
@ -181,7 +181,6 @@ void test_signal()
|
||||
|
||||
thread.join();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
|
||||
@ -26,7 +26,7 @@ namespace
|
||||
int64_t get_monotonic_time_ms()
|
||||
{
|
||||
struct timespec ts;
|
||||
MXB_AT_DEBUG(int rv =) clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
MXB_AT_DEBUG(int rv = ) clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
mxb_assert(rv == 0);
|
||||
|
||||
return ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
|
||||
@ -118,7 +118,6 @@ int run()
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main()
|
||||
|
||||
@ -45,15 +45,15 @@ const int MXB_WORKER_MSG_DISPOSABLE_TASK = -2;
|
||||
*/
|
||||
struct this_unit
|
||||
{
|
||||
bool initialized; // Whether the initialization has been performed.
|
||||
bool initialized; // Whether the initialization has been performed.
|
||||
} this_unit =
|
||||
{
|
||||
false, // initialized
|
||||
false, // initialized
|
||||
};
|
||||
|
||||
thread_local struct this_thread
|
||||
{
|
||||
Worker* pCurrent_worker; // The current worker
|
||||
Worker* pCurrent_worker; // The current worker
|
||||
} this_thread =
|
||||
{
|
||||
nullptr
|
||||
@ -64,11 +64,10 @@ thread_local struct this_thread
|
||||
*/
|
||||
typedef struct worker_message
|
||||
{
|
||||
uint32_t id; /*< Message id. */
|
||||
intptr_t arg1; /*< Message specific first argument. */
|
||||
intptr_t arg2; /*< Message specific second argument. */
|
||||
uint32_t id; /*< Message id. */
|
||||
intptr_t arg1; /*< Message specific first argument. */
|
||||
intptr_t arg2; /*< Message specific second argument. */
|
||||
} WORKER_MESSAGE;
|
||||
|
||||
}
|
||||
|
||||
static bool modules_thread_init();
|
||||
@ -107,14 +106,14 @@ WorkerLoad::Average::~Average()
|
||||
{
|
||||
}
|
||||
|
||||
//static
|
||||
// static
|
||||
uint64_t WorkerLoad::get_time()
|
||||
{
|
||||
uint64_t now;
|
||||
|
||||
timespec t;
|
||||
|
||||
MXB_AT_DEBUG(int rv = )clock_gettime(CLOCK_MONOTONIC, &t);
|
||||
MXB_AT_DEBUG(int rv = ) clock_gettime(CLOCK_MONOTONIC, &t);
|
||||
mxb_assert(rv == 0);
|
||||
|
||||
return t.tv_sec * 1000 + (t.tv_nsec / 1000000);
|
||||
@ -161,7 +160,8 @@ int create_timerfd()
|
||||
else
|
||||
{
|
||||
MXB_ALERT("Could not create timer file descriptor even with no flags, system "
|
||||
"will not work: %s", mxb_strerror(errno));
|
||||
"will not work: %s",
|
||||
mxb_strerror(errno));
|
||||
mxb_assert(!true);
|
||||
}
|
||||
}
|
||||
@ -175,7 +175,6 @@ int create_timerfd()
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
WorkerTimer::WorkerTimer(Worker* pWorker)
|
||||
@ -256,7 +255,7 @@ uint32_t WorkerTimer::handle(Worker* pWorker, uint32_t events)
|
||||
return MXB_POLL_READ;
|
||||
}
|
||||
|
||||
//static
|
||||
// static
|
||||
uint32_t WorkerTimer::handler(MXB_POLL_DATA* pThis, MXB_WORKER* pWorker, uint32_t events)
|
||||
{
|
||||
return static_cast<WorkerTimer*>(pThis)->handle(static_cast<Worker*>(pWorker), events);
|
||||
@ -280,10 +279,9 @@ int create_epoll_instance()
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//static
|
||||
// static
|
||||
uint32_t Worker::s_next_delayed_call_id = 1;
|
||||
|
||||
Worker::Worker(int max_events)
|
||||
@ -494,7 +492,7 @@ bool Worker::execute(function<void ()> func, mxb::Semaphore* pSem, execute_mode_
|
||||
};
|
||||
|
||||
bool rval = false;
|
||||
CustomTask* task = new (std::nothrow) CustomTask(func);
|
||||
CustomTask* task = new( std::nothrow) CustomTask(func);
|
||||
|
||||
if (task)
|
||||
{
|
||||
@ -616,7 +614,7 @@ void Worker::shutdown()
|
||||
*/
|
||||
void Worker::handle_message(MessageQueue& queue, const MessageQueue::Message& msg)
|
||||
{
|
||||
switch (msg.id())
|
||||
switch (msg.id())
|
||||
{
|
||||
case MXB_WORKER_MSG_SHUTDOWN:
|
||||
{
|
||||
@ -627,7 +625,7 @@ void Worker::handle_message(MessageQueue& queue, const MessageQueue::Message& ms
|
||||
|
||||
case MXB_WORKER_MSG_CALL:
|
||||
{
|
||||
void (*f)(MXB_WORKER*, void*) = (void (*)(MXB_WORKER*, void*))msg.arg1();
|
||||
void (* f)(MXB_WORKER*, void*) = (void (*)(MXB_WORKER*, void*))msg.arg1();
|
||||
|
||||
f(this, (void*)msg.arg2());
|
||||
}
|
||||
@ -635,7 +633,7 @@ void Worker::handle_message(MessageQueue& queue, const MessageQueue::Message& ms
|
||||
|
||||
case MXB_WORKER_MSG_TASK:
|
||||
{
|
||||
Task *pTask = reinterpret_cast<Task*>(msg.arg1());
|
||||
Task* pTask = reinterpret_cast<Task*>(msg.arg1());
|
||||
mxb::Semaphore* pSem = reinterpret_cast<mxb::Semaphore*>(msg.arg2());
|
||||
|
||||
pTask->execute(*this);
|
||||
@ -649,7 +647,7 @@ void Worker::handle_message(MessageQueue& queue, const MessageQueue::Message& ms
|
||||
|
||||
case MXB_WORKER_MSG_DISPOSABLE_TASK:
|
||||
{
|
||||
DisposableTask *pTask = reinterpret_cast<DisposableTask*>(msg.arg1());
|
||||
DisposableTask* pTask = reinterpret_cast<DisposableTask*>(msg.arg1());
|
||||
pTask->execute(*this);
|
||||
pTask->dec_ref();
|
||||
}
|
||||
@ -665,7 +663,7 @@ void Worker::handle_message(MessageQueue& queue, const MessageQueue::Message& ms
|
||||
*
|
||||
* @param arg A worker.
|
||||
*/
|
||||
//static
|
||||
// static
|
||||
void Worker::thread_main(Worker* pThis, mxb::Semaphore* pSem)
|
||||
{
|
||||
pThis->run(pSem);
|
||||
@ -698,7 +696,8 @@ void Worker::resolve_poll_error(int fd, int errornum, int op)
|
||||
if (ENOSPC == errornum)
|
||||
{
|
||||
MXB_ERROR("The limit imposed by /proc/sys/fs/epoll/max_user_watches was "
|
||||
"reached when trying to add file descriptor %d to an epoll instance.", fd);
|
||||
"reached when trying to add file descriptor %d to an epoll instance.",
|
||||
fd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -741,14 +740,13 @@ namespace
|
||||
|
||||
long time_in_100ms_ticks()
|
||||
{
|
||||
using TenthSecondDuration = std::chrono::duration<long, std::ratio<1,10>>;
|
||||
using TenthSecondDuration = std::chrono::duration<long, std::ratio<1, 10>>;
|
||||
|
||||
auto dur = std::chrono::steady_clock::now().time_since_epoch();
|
||||
auto tenth = std::chrono::duration_cast<TenthSecondDuration>(dur);
|
||||
|
||||
return tenth.count();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -844,7 +842,7 @@ void Worker::poll_waitevents()
|
||||
|
||||
m_statistics.maxqtime = std::max(m_statistics.maxqtime, qtime);
|
||||
|
||||
MXB_POLL_DATA *data = (MXB_POLL_DATA*)events[i].data.ptr;
|
||||
MXB_POLL_DATA* data = (MXB_POLL_DATA*)events[i].data.ptr;
|
||||
|
||||
uint32_t actions = data->handler(data, this, events[i].events);
|
||||
|
||||
@ -891,7 +889,7 @@ void Worker::poll_waitevents()
|
||||
epoll_tick();
|
||||
|
||||
m_state = IDLE;
|
||||
} /*< while(1) */
|
||||
} /*< while(1) */
|
||||
}
|
||||
|
||||
namespace
|
||||
@ -905,7 +903,6 @@ int64_t get_current_time_ms()
|
||||
|
||||
return ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Worker::tick()
|
||||
@ -1051,7 +1048,6 @@ bool Worker::cancel_delayed_call(uint32_t id)
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -51,5 +51,4 @@ void WorkerDisposableTask::dec_ref()
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user