Merge branch 'dev'
This commit is contained in:
@@ -6,3 +6,5 @@ tags
|
|||||||
doc/
|
doc/
|
||||||
log_subdir/
|
log_subdir/
|
||||||
coverage/
|
coverage/
|
||||||
|
install/
|
||||||
|
libucore-*
|
||||||
|
|||||||
@@ -298,7 +298,7 @@ SUBGROUPING = YES
|
|||||||
# @ingroup) instead of on a separate page (for HTML and Man pages) or
|
# @ingroup) instead of on a separate page (for HTML and Man pages) or
|
||||||
# section (for LaTeX and RTF).
|
# section (for LaTeX and RTF).
|
||||||
|
|
||||||
INLINE_GROUPED_CLASSES = NO
|
INLINE_GROUPED_CLASSES = YES
|
||||||
|
|
||||||
# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
|
# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
|
||||||
# unions with only public data fields will be shown inline in the documentation
|
# unions with only public data fields will be shown inline in the documentation
|
||||||
|
|||||||
@@ -7,9 +7,13 @@ Build
|
|||||||
=====
|
=====
|
||||||
In addition to basic C development tools, the following is needed:
|
In addition to basic C development tools, the following is needed:
|
||||||
|
|
||||||
* scons
|
* scons 2.3.0 or later
|
||||||
* check
|
* check
|
||||||
|
|
||||||
Run scons --help to see the various options for building the library
|
Run scons --help to see the various options for building the library
|
||||||
Run "scons test" to run the test suite
|
Run "scons test" to run the test suite
|
||||||
|
|
||||||
|
Note that scons v 2.3.1 or later is recommended, since scons v 2.3.0
|
||||||
|
has a bug which prevents shared libraries from re-building properly.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+18
-2
@@ -9,6 +9,9 @@ version_info = {
|
|||||||
'version_minor': 0 ,
|
'version_minor': 0 ,
|
||||||
'version_patch': 0 ,
|
'version_patch': 0 ,
|
||||||
'version_revision': revision,
|
'version_revision': revision,
|
||||||
|
#version_abi is the abi version of the shared library. Only bump it when
|
||||||
|
#backwards compatibility breaks. Strive to not break the ABI.
|
||||||
|
'version_abi': '1.0.0'
|
||||||
}
|
}
|
||||||
version_info['version_str'] = "%d.%d.%d.%s" % (
|
version_info['version_str'] = "%d.%d.%d.%s" % (
|
||||||
version_info['version_major'],
|
version_info['version_major'],
|
||||||
@@ -86,7 +89,7 @@ def InstallPerm(env, dest, files, perm):
|
|||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
env = Environment(tools = ['default', 'textfile'])
|
env = Environment(tools = ['default', 'textfile', 'packaging'])
|
||||||
|
|
||||||
#allow shell environment to override compiler
|
#allow shell environment to override compiler
|
||||||
if os.environ.has_key('CC'):
|
if os.environ.has_key('CC'):
|
||||||
@@ -99,6 +102,7 @@ env.Append(CFLAGS = ['-Wno-unused-parameter', '-Werror=implicit-function-declara
|
|||||||
env.Append(LINKFLAGS = ['-O2', '-pthread'])
|
env.Append(LINKFLAGS = ['-O2', '-pthread'])
|
||||||
env.Append(CPPDEFINES = ['_FILE_OFFSET_BITS=64'])
|
env.Append(CPPDEFINES = ['_FILE_OFFSET_BITS=64'])
|
||||||
env.Append(CPPPATH = ['#include'])
|
env.Append(CPPPATH = ['#include'])
|
||||||
|
env.Append(SHLIBVERSION = version_info['version_abi'])
|
||||||
|
|
||||||
if GetOption('force32bit'):
|
if GetOption('force32bit'):
|
||||||
env.Append(CFLAGS = ['-m32'])
|
env.Append(CFLAGS = ['-m32'])
|
||||||
@@ -146,6 +150,18 @@ subdirs = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
for subdir in subdirs:
|
for subdir in subdirs:
|
||||||
SConscript(subdir + '/SConscript', variant_dir='#build/' + subdir, src_dir='#'+subdir, duplicate=0)
|
env.SConscript(subdir + '/SConscript', variant_dir='#build/' + subdir, src_dir='#'+subdir, duplicate=0)
|
||||||
|
|
||||||
|
env.Package(target = 'libucore-' + version_info['version_str'] + '.tar.gz',
|
||||||
|
source = env.FindInstalledFiles(),
|
||||||
|
NAME = 'libucore',
|
||||||
|
VERSION = version_info['version_str'],
|
||||||
|
PACKAGEVERSION = 0,
|
||||||
|
PACKAGETYPE = 'targz',
|
||||||
|
LICENSE = 'BSD',
|
||||||
|
SUMMARY = 'libucore is a C library of misc useful stuff including an eventloop, timer support and various data-structures.',
|
||||||
|
DESCRIPTION = 'libucore is a C library of misc useful stuff including an eventloop, timer support and various data-structures.',
|
||||||
|
X_RPM_GROUP = 'Development/Libraries'
|
||||||
|
)
|
||||||
|
|
||||||
env.Default('src')
|
env.Default('src')
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ void uc_bv_set_all(struct UCBitVec *v);
|
|||||||
* int a[] = {0,1,1,1,0};
|
* int a[] = {0,1,1,1,0};
|
||||||
* set_bits_from_array(v,a,5);
|
* set_bits_from_array(v,a,5);
|
||||||
* */
|
* */
|
||||||
void uc_bv_set_bits_from_array(struct UCBitVec *v,char *array,size_t array_len);
|
void uc_bv_set_bits_from_array(struct UCBitVec *v,const char *array,size_t array_len);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ struct UCoreClock {
|
|||||||
* Wrapper for getting the current time.
|
* Wrapper for getting the current time.
|
||||||
* @param tv timeval that will be filled in
|
* @param tv timeval that will be filled in
|
||||||
*/
|
*/
|
||||||
void (*now)(struct UCoreClock *clock, struct timeval *tv);
|
void (*now)(const struct UCoreClock *clock, struct timeval *tv);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Convenience macro for geting the time from a UCoreClock
|
/** Convenience macro for geting the time from a UCoreClock
|
||||||
@@ -82,7 +82,7 @@ extern struct UCoreClock uc_time_clock;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void uc_cached_clock_init(struct UCoreCachedClock *uclock,
|
void uc_cached_clock_init(struct UCoreCachedClock *uclock,
|
||||||
struct UCoreClock *real_clock);
|
struct UCoreClock *real_clock);
|
||||||
|
|
||||||
/** Update the cached clock from the real_clock
|
/** Update the cached clock from the real_clock
|
||||||
*/
|
*/
|
||||||
@@ -103,7 +103,7 @@ void uc_settable_clock_init(struct UCoreSettableClock *uclock);
|
|||||||
* @param tv new timeval to set the clock to
|
* @param tv new timeval to set the clock to
|
||||||
**/
|
**/
|
||||||
void uc_settable_clock_set_tv(struct UCoreSettableClock *uclock,
|
void uc_settable_clock_set_tv(struct UCoreSettableClock *uclock,
|
||||||
const struct timeval *tv);
|
const struct timeval *tv);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the new time this clock will return
|
* Set the new time this clock will return
|
||||||
@@ -114,7 +114,7 @@ void uc_settable_clock_set_tv(struct UCoreSettableClock *uclock,
|
|||||||
* @param usecs microseconds portion of the clock to set.
|
* @param usecs microseconds portion of the clock to set.
|
||||||
**/
|
**/
|
||||||
void uc_settable_clock_set(struct UCoreSettableClock *uclock,
|
void uc_settable_clock_set(struct UCoreSettableClock *uclock,
|
||||||
time_t secs, suseconds_t usecs);
|
time_t secs, suseconds_t usecs);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
#ifndef UC_CMD_H_
|
||||||
|
#define UC_CMD_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
enum UCCmdResult {
|
||||||
|
UC_CMDRES_OK,
|
||||||
|
UC_CMDRES_WARN,
|
||||||
|
UC_CMDRES_ERR
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UCCmdDef;
|
||||||
|
struct UCVTerm;
|
||||||
|
typedef enum UCCmdResult (*uc_cmd_handler)(struct UCCmd *cmd, struct UCVTerm *term, int arg, char *argv[]);
|
||||||
|
|
||||||
|
struct UCCmdDef {
|
||||||
|
uint32_t cmd_id;
|
||||||
|
uint32_t cmd_flags;
|
||||||
|
const char *cmd_syntax;
|
||||||
|
const char *cmd_desc;
|
||||||
|
uc_cmd_handler cmd_cb;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define UC_DEF_CMD_DEF(id, flags, syntax, desc)\
|
||||||
|
static const struct UCCmdDef uc_cmd_def ## cmd_id {\
|
||||||
|
.cmd_id = cmd_id,\
|
||||||
|
.cmd_flags = flags,\
|
||||||
|
.cmd_syntax = syntax,\
|
||||||
|
.cmd_desc = desc,\
|
||||||
|
};
|
||||||
|
|
||||||
|
#define UC_DEF_CMD_FUNC(id)\
|
||||||
|
static enum UCCmdResult uc_cmd_func_ ## id (struct UCCmd *cmd, struct UCVTerm *term, int nargs, char *args[])
|
||||||
|
|
||||||
|
#define UC_DEF_CMD(id, flags, syntax, desc)\
|
||||||
|
UC_DEF_CMD_DEF(id, flags, syntax, desc)\
|
||||||
|
UC_DEF_CMD_FUNC(id)
|
||||||
|
|
||||||
|
UC_DEF_CMD(111, 0 ,
|
||||||
|
"show peers",
|
||||||
|
"Show all connected peers")
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/
|
||||||
+14
-7
@@ -8,16 +8,22 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** A managed C-string, using dynamically allocated memory for the string.
|
/**@file
|
||||||
|
* A managed C-string, using dynamically allocated memory for the string.
|
||||||
*
|
*
|
||||||
* The .str member might not always be nul terminated,
|
* The .str member might not always be nul terminated, and should not be
|
||||||
* Normally, use uc_dstr_str() to retreive the managed string
|
* accessed directly. Instead use uc_dstr_str() to retreive the managed string
|
||||||
* instead of accessing ->str directly.
|
* which will always ensure the string is nul terminated
|
||||||
*
|
*
|
||||||
* Normally, let the DSTR manage the nul terminator as manually adding
|
* Normally, let the DSTR manage the nul terminator as manually adding
|
||||||
* a nul byte and potintially adding more data to the DStr would append
|
* a nul byte and potintially adding more data to the DStr would append
|
||||||
* it after that nul terminator.
|
* it after that nul terminator.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/** Dynamic string struct. The user is responsible for managing
|
||||||
|
* the struct Dstr memory, and the uc_dstr_ functions will manage
|
||||||
|
* the memory held in .str.
|
||||||
|
*/
|
||||||
struct DStr {
|
struct DStr {
|
||||||
/** Length of the managed string.*/
|
/** Length of the managed string.*/
|
||||||
size_t len;
|
size_t len;
|
||||||
@@ -27,10 +33,11 @@ struct DStr {
|
|||||||
char *str;
|
char *str;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define UC_DSTR_STATIC_INIT {0, 0, NULL}
|
#define UC_DSTR_INITIALIZER {0, 0, NULL}
|
||||||
|
|
||||||
/** Initialize a DStr.
|
/** Initialize a DStr.
|
||||||
* Note that str->str will be NULL after initialization.
|
* Note that str->str will be NULL after initialization.
|
||||||
|
* (However uc_dstr_str() will return a valid (empty) string.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void uc_dstr_init(struct DStr *str);
|
void uc_dstr_init(struct DStr *str);
|
||||||
@@ -94,7 +101,7 @@ void uc_dstr_terminate(struct DStr *str);
|
|||||||
char *uc_dstr_str(struct DStr *str);
|
char *uc_dstr_str(struct DStr *str);
|
||||||
|
|
||||||
/** Reserve len bytes for appending to the dstr
|
/** Reserve len bytes for appending to the dstr
|
||||||
* you must fill in a string in the 0-len range of
|
* you must copy characters to all bytes in the [0-len) range of
|
||||||
* the returned pointer.
|
* the returned pointer.
|
||||||
*
|
*
|
||||||
* @param len bytes to reseve
|
* @param len bytes to reseve
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ uc_pjwhash(const char *str,size_t len);
|
|||||||
uint32_t
|
uint32_t
|
||||||
uc_sax_hash(void *key, size_t len);
|
uc_sax_hash(void *key, size_t len);
|
||||||
|
|
||||||
|
unsigned long
|
||||||
|
uc_sdbmhash(const unsigned char *str);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -73,7 +73,8 @@ static inline size_t uc_htable_bucket(const struct UHTable *table, size_t hash)
|
|||||||
* @param table table
|
* @param table table
|
||||||
* @param hash hash
|
* @param hash hash
|
||||||
*/
|
*/
|
||||||
static inline struct UHNode *uc_htable_first_bucket(const struct UHTable *table, size_t hash)
|
static inline struct UHNode *uc_htable_first_bucket(const struct UHTable *table,
|
||||||
|
size_t hash)
|
||||||
{
|
{
|
||||||
size_t bucket = uc_htable_bucket(table, hash);
|
size_t bucket = uc_htable_bucket(table, hash);
|
||||||
|
|
||||||
|
|||||||
@@ -137,6 +137,13 @@ struct UCTimers *iomux_get_timers(struct IOMux *mux);
|
|||||||
* or indirectly by the UCTimers provieded in a timer callback handler.
|
* or indirectly by the UCTimers provieded in a timer callback handler.
|
||||||
*/
|
*/
|
||||||
struct IOMux *iomux_from_timers(struct UCTimers *timers);
|
struct IOMux *iomux_from_timers(struct UCTimers *timers);
|
||||||
|
|
||||||
|
|
||||||
|
/** Get the clock associated with the IOMux. This is the clock used
|
||||||
|
* used to drive the UCTimers associated with this IOMux
|
||||||
|
*/
|
||||||
|
struct UCoreClock *iomux_get_clock(struct IOMux *mux);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+25
-13
@@ -100,15 +100,18 @@ struct UCLogModule {
|
|||||||
int id;
|
int id;
|
||||||
|
|
||||||
/** A short name for the module.
|
/** A short name for the module.
|
||||||
|
* (must point to static storage)
|
||||||
* This will appear in log messages */
|
* This will appear in log messages */
|
||||||
const char *short_name;
|
const char *short_name;
|
||||||
/** A longer description for the log module*/
|
/** A longer description for the log module
|
||||||
|
* (must point to static storage)
|
||||||
|
*/
|
||||||
const char *long_name;
|
const char *long_name;
|
||||||
/** The log level of this module. Only
|
/** The log level of this module. Only
|
||||||
* log statements with a level >= the log_level
|
* log statements with a level >= the log_level
|
||||||
* are actually logged, but the log_level of a destination
|
* are actually logged, but the log_level of a destination
|
||||||
* can restrict the logging further*/
|
* can restrict the logging further*/
|
||||||
int log_level;
|
enum UC_LOG_LEVEL log_level;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* A collection of struct UCLogModule */
|
/* A collection of struct UCLogModule */
|
||||||
@@ -168,7 +171,8 @@ const char *uc_ll_2_str(enum UC_LOG_LEVEL l);
|
|||||||
* @return An opaque uc_log_destination that can be added as a destination to
|
* @return An opaque uc_log_destination that can be added as a destination to
|
||||||
* the ucore logging system
|
* the ucore logging system
|
||||||
*/
|
*/
|
||||||
struct UCLogDestination *uc_log_new_stderr(int log_level, int log_location);
|
struct UCLogDestination *uc_log_new_stderr(enum UC_LOG_LEVEL log_level,
|
||||||
|
int log_location);
|
||||||
|
|
||||||
/* creates a new uc_log_destination for logging to syslog
|
/* creates a new uc_log_destination for logging to syslog
|
||||||
*
|
*
|
||||||
@@ -181,7 +185,10 @@ struct UCLogDestination *uc_log_new_stderr(int log_level, int log_location);
|
|||||||
* @return An opaque uc_log_destination that can be added as a destination to
|
* @return An opaque uc_log_destination that can be added as a destination to
|
||||||
* the ucore logging system
|
* the ucore logging system
|
||||||
*/
|
*/
|
||||||
struct UCLogDestination *uc_log_new_syslog(const char *ident, int facility, int log_level, int log_location);
|
struct UCLogDestination *uc_log_new_syslog(const char *ident,
|
||||||
|
int facility,
|
||||||
|
enum UC_LOG_LEVEL log_level,
|
||||||
|
int log_location);
|
||||||
|
|
||||||
/* creates a new uc_log_destination for printing on stderr.
|
/* creates a new uc_log_destination for printing on stderr.
|
||||||
*
|
*
|
||||||
@@ -192,7 +199,9 @@ struct UCLogDestination *uc_log_new_syslog(const char *ident, int facility, int
|
|||||||
* @param return An opaque uc_log_destination that can be added as a destination to
|
* @param return An opaque uc_log_destination that can be added as a destination to
|
||||||
* the ucore logging system
|
* the ucore logging system
|
||||||
*/
|
*/
|
||||||
struct UCLogDestination *uc_log_new_file(const char *filename, int log_level, int log_location);
|
struct UCLogDestination *uc_log_new_file(const char *filename,
|
||||||
|
enum UC_LOG_LEVEL log_level,
|
||||||
|
int log_location);
|
||||||
|
|
||||||
/** Add a uc_log_destination to the logging system.
|
/** Add a uc_log_destination to the logging system.
|
||||||
*
|
*
|
||||||
@@ -213,7 +222,8 @@ void uc_log_remove_destination(struct UCLogDestination *dest);
|
|||||||
* @param dest destination for which to set the log level
|
* @param dest destination for which to set the log level
|
||||||
* @param level The new log level
|
* @param level The new log level
|
||||||
*/
|
*/
|
||||||
void uc_log_destination_set_loglevel(struct UCLogDestination *dest, enum UC_LOG_LEVEL level);
|
void uc_log_destination_set_loglevel(struct UCLogDestination *dest,
|
||||||
|
enum UC_LOG_LEVEL level);
|
||||||
|
|
||||||
/** Change whether to log the location (file/line no.) of logging
|
/** Change whether to log the location (file/line no.) of logging
|
||||||
* output on a destination,
|
* output on a destination,
|
||||||
@@ -221,7 +231,8 @@ void uc_log_destination_set_loglevel(struct UCLogDestination *dest, enum UC_LOG_
|
|||||||
* @param dest log destination to change
|
* @param dest log destination to change
|
||||||
* @param log_location 1=log the locaton, 0=don't log the location
|
* @param log_location 1=log the locaton, 0=don't log the location
|
||||||
*/
|
*/
|
||||||
void uc_log_destination_set_log_location(struct UCLogDestination *dest, int log_location);
|
void uc_log_destination_set_log_location(struct UCLogDestination *dest,
|
||||||
|
int log_location);
|
||||||
|
|
||||||
/** Sets the log rotation settings.
|
/** Sets the log rotation settings.
|
||||||
* Does nothing if the destination is not a UC_LDEST_FILE, or the policy is invalid.
|
* Does nothing if the destination is not a UC_LDEST_FILE, or the policy is invalid.
|
||||||
@@ -295,9 +306,9 @@ int uc_log_reopen_files(void);
|
|||||||
*
|
*
|
||||||
* @param user_struct containing an array of all the modules defined by the application.
|
* @param user_struct containing an array of all the modules defined by the application.
|
||||||
*/
|
*/
|
||||||
void uc_log_init(struct UCLogModules *user_modules);
|
void uc_log_init(const struct UCLogModules *user_modules);
|
||||||
|
|
||||||
void uc_logf(int log_level, int module, int raw,
|
void uc_logf(enum UC_LOG_LEVEL log_level, int module, int raw,
|
||||||
const char *location, const char *fmt, ...)
|
const char *location, const char *fmt, ...)
|
||||||
__attribute__((format(printf, 5, 6)));
|
__attribute__((format(printf, 5, 6)));
|
||||||
|
|
||||||
@@ -305,9 +316,9 @@ void uc_logf(int log_level, int module, int raw,
|
|||||||
// to override that by defining UC_DEBUG_ALWAYS
|
// to override that by defining UC_DEBUG_ALWAYS
|
||||||
#if defined(DEBUG) || defined(UC_DEBUG_ALWAYS)
|
#if defined(DEBUG) || defined(UC_DEBUG_ALWAYS)
|
||||||
# define UC_DEBUGF(mod, fmt, ...)\
|
# define UC_DEBUGF(mod, fmt, ...)\
|
||||||
uc_logf(UC_LL_DEBUG, mod,0 , UC_SRC_LOCATION, fmt, ## __VA_ARGS__)
|
uc_logf(UC_LL_DEBUG, mod,0 , UC_SRC_LOCATION, fmt "\n", ## __VA_ARGS__)
|
||||||
# define UC_DEBUGFR(mod, fmt, ...)\
|
# define UC_DEBUGFR(mod, fmt, ...)\
|
||||||
uc_logf(UC_LL_DEBUG, mod,1 , UC_SRC_LOCATION, fmt, ## __VA_ARGS__)
|
uc_logf(UC_LL_DEBUG, mod,1 , UC_SRC_LOCATION, fmt "\n", ## __VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
# define UC_DEBUGF(mod, fmt, ...) do {} while (0)
|
# define UC_DEBUGF(mod, fmt, ...) do {} while (0)
|
||||||
# define UC_DEBUGFR(mod, fmt, ...) do {} while (0)
|
# define UC_DEBUGFR(mod, fmt, ...) do {} while (0)
|
||||||
@@ -317,6 +328,7 @@ void uc_logf(int log_level, int module, int raw,
|
|||||||
*
|
*
|
||||||
* For log messages with UC_LL_DEBUG, the UC_DEBUGF() macro can be used,
|
* For log messages with UC_LL_DEBUG, the UC_DEBUGF() macro can be used,
|
||||||
* UC_DEBUGF will only be compiled in if the DEBUG macro is defined
|
* UC_DEBUGF will only be compiled in if the DEBUG macro is defined
|
||||||
|
* fmt must be a string literal, and a newline will be added
|
||||||
*
|
*
|
||||||
* @param lvl log level of this log message
|
* @param lvl log level of this log message
|
||||||
* @param mod module id of this log messagex.
|
* @param mod module id of this log messagex.
|
||||||
@@ -324,11 +336,11 @@ void uc_logf(int log_level, int module, int raw,
|
|||||||
* @param ... printf style arguments
|
* @param ... printf style arguments
|
||||||
*/
|
*/
|
||||||
#define UC_LOGF(lvl, mod, fmt, ...) \
|
#define UC_LOGF(lvl, mod, fmt, ...) \
|
||||||
uc_logf(lvl, mod, 0, UC_SRC_LOCATION, fmt, ## __VA_ARGS__)
|
uc_logf(lvl, mod, 0, UC_SRC_LOCATION, fmt "\n", ## __VA_ARGS__)
|
||||||
|
|
||||||
|
|
||||||
/** Raw logging ,Like UC_LOGF, but only prints the supplied
|
/** Raw logging ,Like UC_LOGF, but only prints the supplied
|
||||||
* data, not timestamp, log level etc.
|
* data, not timestamp, log level, newline, etc.
|
||||||
*/
|
*/
|
||||||
#define UC_LOGFR(lvl, mod, fmt, ...) \
|
#define UC_LOGFR(lvl, mod, fmt, ...) \
|
||||||
uc_logf(lvl, mod, 1, UC_SRC_LOCATION, fmt, ## __VA_ARGS__)
|
uc_logf(lvl, mod, 1, UC_SRC_LOCATION, fmt, ## __VA_ARGS__)
|
||||||
|
|||||||
+26
-22
@@ -4,17 +4,6 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "tailq.h"
|
#include "tailq.h"
|
||||||
|
|
||||||
#ifndef UC_INLINE
|
|
||||||
#ifdef __GNUC__
|
|
||||||
# ifdef __clang__
|
|
||||||
# define UC_INLINE inline __attribute__((always_inline))
|
|
||||||
# else
|
|
||||||
# define UC_INLINE inline __attribute__((always_inline,flatten))
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
# define UC_INLINE inline
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** @file
|
/** @file
|
||||||
* mbuf - A managed message/memory buffer.
|
* mbuf - A managed message/memory buffer.
|
||||||
@@ -35,16 +24,17 @@
|
|||||||
@endverbatim
|
@endverbatim
|
||||||
*
|
*
|
||||||
* Initially when empty, head == tail, and the length is 0.
|
* Initially when empty, head == tail, and the length is 0.
|
||||||
* Data is added to the tail.
|
* Data can be added to the tailroom or the headroom.
|
||||||
|
* The data is the memory from (including) head to (excluding) tail.
|
||||||
*
|
*
|
||||||
* If head == bufstart, there is no headroom
|
* If head == bufstart, there is no headroom
|
||||||
* if tail points one past the allocated space, there is no
|
* if tail points one past the allocated space, there is no
|
||||||
* tailroom (the buffer is full)
|
* tailroom (the buffer is full)
|
||||||
*
|
*
|
||||||
* Conventions:
|
* Conventions:
|
||||||
* push - prepend data to the buffer (in the head room part)
|
* push - prepend data to the buffer in the head room part
|
||||||
* (move head to the left)
|
* (move head to the left)
|
||||||
* pull - remove data from the beginning of the message.
|
* pull - remove data from the beginning of the data
|
||||||
* (move head to the right)
|
* (move head to the right)
|
||||||
* put - Add data to the buffer.
|
* put - Add data to the buffer.
|
||||||
* (move tail to the right)
|
* (move tail to the right)
|
||||||
@@ -114,7 +104,12 @@ struct MBuf *uc_mbuf_new_inline_hr(uint32_t len, uint32_t headroom);
|
|||||||
/** As uc_mbuf_new_inline_hr, but without any headroom*/
|
/** As uc_mbuf_new_inline_hr, but without any headroom*/
|
||||||
#define uc_mbuf_new_inline(len) uc_mbuf_new_inline_hr((len), 0)
|
#define uc_mbuf_new_inline(len) uc_mbuf_new_inline_hr((len), 0)
|
||||||
|
|
||||||
/** @param mbuf the mbuf to free. (passing NULL is a no-op)*/
|
/** Free the memory of an mbuf and its data.
|
||||||
|
* If passing in NULL or an mbuf with a UC_MBUF_FL_STATIC flag,
|
||||||
|
* no action is taken.
|
||||||
|
*
|
||||||
|
* @param mbuf the mbuf to free.
|
||||||
|
*/
|
||||||
void uc_mbuf_free(struct MBuf *mbuf);
|
void uc_mbuf_free(struct MBuf *mbuf);
|
||||||
|
|
||||||
/** Create a new mbuf, with a copy of the data from the given
|
/** Create a new mbuf, with a copy of the data from the given
|
||||||
@@ -128,9 +123,7 @@ struct MBuf *uc_mbuf_copy_data(struct MBuf *mbuf);
|
|||||||
/** Initialize an mbuf. This function is mostly used internally,
|
/** Initialize an mbuf. This function is mostly used internally,
|
||||||
* but can be used to e.g. create an mbuf based on a local array
|
* but can be used to e.g. create an mbuf based on a local array
|
||||||
* (in which case UC_MBUF_FL_STATIC must be set), or other data
|
* (in which case UC_MBUF_FL_STATIC must be set), or other data
|
||||||
* whose memory is already allocated.
|
* whose memory is already allocated. * The whole buffer must have len + headroom available data
|
||||||
*
|
|
||||||
* The whole buffer must have len + headroom available data
|
|
||||||
*
|
*
|
||||||
* @param mbuf to initialise
|
* @param mbuf to initialise
|
||||||
* @param buf start of the buffer
|
* @param buf start of the buffer
|
||||||
@@ -138,9 +131,10 @@ struct MBuf *uc_mbuf_copy_data(struct MBuf *mbuf);
|
|||||||
* @param headroom the headroom in the buffer
|
* @param headroom the headroom in the buffer
|
||||||
* @param flags The appropriate UC_MBUF_FLAGS
|
* @param flags The appropriate UC_MBUF_FLAGS
|
||||||
*/
|
*/
|
||||||
void uc_mbuf_init(struct MBuf *mbuf, uint8_t *restrict buf, uint32_t len, uint32_t headroom, uint32_t flags);
|
void uc_mbuf_init(struct MBuf *mbuf, uint8_t *restrict buf, uint32_t len,
|
||||||
|
uint32_t headroom, uint32_t flags);
|
||||||
|
|
||||||
/** Zero out all the data in this mbuf, including the headroom
|
/** Zero out all the data in this mbuf, including the headroom and tailroom
|
||||||
*
|
*
|
||||||
* @param mbuf mbuf to zero out
|
* @param mbuf mbuf to zero out
|
||||||
*/
|
*/
|
||||||
@@ -187,7 +181,7 @@ uint8_t *uc_mbuf_put(struct MBuf *mbuf, uint32_t size);
|
|||||||
* data in the buffer, retreating the head pointer by size butes
|
* data in the buffer, retreating the head pointer by size butes
|
||||||
* You need to insert the size bytes in the returned pointer.
|
* You need to insert the size bytes in the returned pointer.
|
||||||
*
|
*
|
||||||
* @oaram size bytes to prepend to the buffer
|
w* @oaram size bytes to prepend to the buffer
|
||||||
* @return NULL if the mbuf does not have enough headroom
|
* @return NULL if the mbuf does not have enough headroom
|
||||||
*/
|
*/
|
||||||
uint8_t *uc_mbuf_push(struct MBuf *mbuf, uint32_t size);
|
uint8_t *uc_mbuf_push(struct MBuf *mbuf, uint32_t size);
|
||||||
@@ -220,6 +214,16 @@ static UC_INLINE uint8_t *uc_mbuf_head(struct MBuf* mbuf)
|
|||||||
return mbuf->head;
|
return mbuf->head;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef UC_INLINE
|
/** Add the mbuf at the end of the tailq.
|
||||||
|
* This uses the tailQ entry member of the mbuf.
|
||||||
|
*/
|
||||||
|
void uc_mbuf_enqueue(struct MBuf *mbuf, struct TailQ *head);
|
||||||
|
|
||||||
|
/** Remove and return the mbuf at the start of the tailq.
|
||||||
|
* @return the first mbuf in the queue, or NULL if ti isempty.
|
||||||
|
*/
|
||||||
|
struct MBuf *uc_mbuf_dequeue(struct TailQ *head);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+1
-17
@@ -2,18 +2,7 @@
|
|||||||
#define UC_PACK_H_
|
#define UC_PACK_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "utils.h"
|
||||||
#ifndef UC_INLINE
|
|
||||||
#ifdef __GNUC__
|
|
||||||
# ifdef __clang__
|
|
||||||
# define UC_INLINE inline __attribute__((always_inline))
|
|
||||||
# else
|
|
||||||
# define UC_INLINE inline __attribute__((always_inline,flatten))
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
# define UC_INLINE inline
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** @file
|
/** @file
|
||||||
* Functions for serializing/de-serializing integers to and from
|
* Functions for serializing/de-serializing integers to and from
|
||||||
@@ -256,10 +245,5 @@ static UC_INLINE uint64_t uc_unpack_64_be(const uint8_t *r)
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#undef UC_INLINE
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ uc_read_file(const char *file_name, size_t *length, size_t max);
|
|||||||
* @see uc_read_file
|
* @see uc_read_file
|
||||||
* This is similar but reads from a file descriptor,
|
* This is similar but reads from a file descriptor,
|
||||||
* of any type as long as it supports the read() call.
|
* of any type as long as it supports the read() call.
|
||||||
|
*
|
||||||
|
* uc_read_fd close() the fd in all cases before it returns
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
uc_read_fd(int fd, size_t *length, size_t max);
|
uc_read_fd(int fd, size_t *length, size_t max);
|
||||||
|
|||||||
@@ -54,8 +54,7 @@ typedef enum {
|
|||||||
* @param filename the filename to use to keep track of the state
|
* @param filename the filename to use to keep track of the state
|
||||||
* @param flags one of UC_RC_FL_XX
|
* @param flags one of UC_RC_FL_XX
|
||||||
*/
|
*/
|
||||||
UCRCResult uc_restart_counter_init(
|
UCRCResult uc_restart_counter_init(struct UCRestartCounter *counter,
|
||||||
struct UCRestartCounter *counter,
|
|
||||||
const char *filename,
|
const char *filename,
|
||||||
unsigned int flags);
|
unsigned int flags);
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,9 @@ uint8_t* uc_hex_decode(const char *restrict in, size_t maxlen,uint8_t *restrict
|
|||||||
/** As uc_hex_encode , but inserts the @delim string between each converted
|
/** As uc_hex_encode , but inserts the @delim string between each converted
|
||||||
* byte (each 2 hex chars)
|
* byte (each 2 hex chars)
|
||||||
*/
|
*/
|
||||||
char* uc_hex_encode_delim(const uint8_t *restrict in, size_t inlen, char *restrict out, int outlen, const char *restrict delim);
|
char* uc_hex_encode_delim(const uint8_t *restrict in, size_t inlen,
|
||||||
|
char *restrict out, int outlen,
|
||||||
|
const char *restrict delim);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the string to lowercase, calls tolower() on each char.
|
* Convert the string to lowercase, calls tolower() on each char.
|
||||||
@@ -67,7 +69,9 @@ void uc_str_toupper(char *s);
|
|||||||
* if the number of ASCII digits is odd. This would usually be 0x0 or 0xf.
|
* if the number of ASCII digits is odd. This would usually be 0x0 or 0xf.
|
||||||
* @return the number of bytes written to bcdout
|
* @return the number of bytes written to bcdout
|
||||||
*/
|
*/
|
||||||
size_t uc_ascii2bcd(const char *restrict ascii, unsigned char *restrict bcdout, unsigned char filler);
|
size_t uc_ascii2bcd(const char *restrict ascii,
|
||||||
|
unsigned char *restrict bcdout,
|
||||||
|
unsigned char filler);
|
||||||
|
|
||||||
/** Convert the BCD digits to ascii.
|
/** Convert the BCD digits to ascii.
|
||||||
* The resulting ascii string is 0 terminated.
|
* The resulting ascii string is 0 terminated.
|
||||||
@@ -77,7 +81,9 @@ size_t uc_ascii2bcd(const char *restrict ascii, unsigned char *restrict bcdout,
|
|||||||
* @param asciiout buffer to place ASCII in, must be UC_ASCII_LEN(bcdlen)+1 big
|
* @param asciiout buffer to place ASCII in, must be UC_ASCII_LEN(bcdlen)+1 big
|
||||||
* @return the number of characters written to bcdout (this will always be UC_ASCII_LEN(bcdlen)
|
* @return the number of characters written to bcdout (this will always be UC_ASCII_LEN(bcdlen)
|
||||||
*/
|
*/
|
||||||
size_t uc_bcd2ascii(const unsigned char *restrict bcd, size_t bcdlen, char *restrict asciiout);
|
size_t uc_bcd2ascii(const unsigned char *restrict bcd,
|
||||||
|
size_t bcdlen,
|
||||||
|
char *restrict asciiout);
|
||||||
|
|
||||||
/** uc_sprintb for converting the values into ascii bit representation
|
/** uc_sprintb for converting the values into ascii bit representation
|
||||||
* e.g. 0x3 -> "00000011". The result must be able to hold the max number
|
* e.g. 0x3 -> "00000011". The result must be able to hold the max number
|
||||||
|
|||||||
@@ -82,7 +82,8 @@ void uc_strv_clear(struct UCStrv *strv);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* free all elements as well as the underlying array, the UCStrv is
|
* free all elements as well as the underlying array, the UCStrv is
|
||||||
* unusable after this call
|
* unusable after this call until it is initialized again.
|
||||||
|
* (strv itself is not free'd)
|
||||||
*
|
*
|
||||||
* @param strv UCStrv to destroy
|
* @param strv UCStrv to destroy
|
||||||
*/
|
*/
|
||||||
|
|||||||
+2
-13
@@ -1,17 +1,8 @@
|
|||||||
#ifndef UC_TAILQ_H_
|
#ifndef UC_TAILQ_H_
|
||||||
#define UC_TAILQ_H_
|
#define UC_TAILQ_H_
|
||||||
|
|
||||||
#ifndef UC_INLINE
|
#include "utils.h"
|
||||||
#ifdef __GNUC__
|
|
||||||
# ifdef __clang__
|
|
||||||
# define UC_INLINE inline __attribute__((always_inline))
|
|
||||||
# else
|
|
||||||
# define UC_INLINE inline __attribute__((always_inline,flatten))
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
# define UC_INLINE inline
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
/**
|
/**
|
||||||
* Doubly Linked List.
|
* Doubly Linked List.
|
||||||
* It is used either as
|
* It is used either as
|
||||||
@@ -253,6 +244,4 @@ static UC_INLINE void uc_tailq_move_tail(struct TailQ *entry, struct TailQ *head
|
|||||||
(ptr) = (prv),\
|
(ptr) = (prv),\
|
||||||
(prv) = UC_TAILQ_CONTAINER(UC_TAILQ_NEXT(&(ptr)->member), typeof(*ptr), member))
|
(prv) = UC_TAILQ_CONTAINER(UC_TAILQ_NEXT(&(ptr)->member), typeof(*ptr), member))
|
||||||
|
|
||||||
#undef UC_INLINE
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -153,6 +153,7 @@ int uc_thread_queue_init(struct uc_threadqueue *queue, unsigned int max_elements
|
|||||||
* Adds a message to a queue
|
* Adds a message to a queue
|
||||||
*
|
*
|
||||||
* thread_queue_add adds a "message" to the specified queue.
|
* thread_queue_add adds a "message" to the specified queue.
|
||||||
|
* If the queue is full, the call will block if the timeout agrument is non-NULL.
|
||||||
* It is up to the application to manage the data and memory indicated by the
|
* It is up to the application to manage the data and memory indicated by the
|
||||||
* struct uc_threadmsg.
|
* struct uc_threadmsg.
|
||||||
* The struct uc_threadmsg is assumed to be an intrusive pointer,
|
* The struct uc_threadmsg is assumed to be an intrusive pointer,
|
||||||
@@ -167,18 +168,22 @@ int uc_thread_queue_init(struct uc_threadqueue *queue, unsigned int max_elements
|
|||||||
* the front of the queue, i.e. it can be considered a "priority" message.
|
* the front of the queue, i.e. it can be considered a "priority" message.
|
||||||
*
|
*
|
||||||
* @param queue Pointer to the queue on where the message should be added.
|
* @param queue Pointer to the queue on where the message should be added.
|
||||||
* @param timeout timeout on how long to wait on a message, or NULL for no timeout
|
* @param timeout timeout on how long to wait until the queue has capacity to add the message
|
||||||
|
* to the queue.
|
||||||
* @param data the "message".
|
* @param data the "message".
|
||||||
* @return 0 on succes ENOMEM if out of memory EINVAL if queue is NULL, ETIMEDOUT if timeout occured or other
|
* @return 0 on succes ENOMEM if out of memory EINVAL if queue is NULL, ETIMEDOUT if timeout occured or other
|
||||||
* errno values if pthread functions failed.
|
* errno values if pthread functions failed.
|
||||||
*/
|
*/
|
||||||
int uc_thread_queue_tryadd(struct uc_threadqueue *queue, const struct timespec *timeout, struct uc_threadmsg *msg);
|
int uc_thread_queue_tryadd(struct uc_threadqueue *queue,
|
||||||
|
const struct timespec *timeout,
|
||||||
|
struct uc_threadmsg *msg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Like uc_thread_queue_add but will wait indefintly.
|
* Like uc_thread_queue_add but will wait indefintly.
|
||||||
* @see uc_thread_queue_add
|
* @see uc_thread_queue_add
|
||||||
*/
|
*/
|
||||||
static inline int uc_thread_queue_add(struct uc_threadqueue *queue, struct uc_threadmsg *msg)
|
static inline int uc_thread_queue_add(struct uc_threadqueue *queue,
|
||||||
|
struct uc_threadmsg *msg)
|
||||||
{
|
{
|
||||||
return uc_thread_queue_tryadd(queue, NULL, msg);
|
return uc_thread_queue_tryadd(queue, NULL, msg);
|
||||||
}
|
}
|
||||||
@@ -205,14 +210,17 @@ static inline int uc_thread_queue_add(struct uc_threadqueue *queue, struct uc_th
|
|||||||
*
|
*
|
||||||
* @return 0 on success EINVAL if queue is NULL ETIMEDOUT if timeout occurs
|
* @return 0 on success EINVAL if queue is NULL ETIMEDOUT if timeout occurs
|
||||||
*/
|
*/
|
||||||
int uc_thread_queue_tryget(struct uc_threadqueue *queue, const struct timespec *timeout, struct uc_threadmsg **msg);
|
int uc_thread_queue_tryget(struct uc_threadqueue *queue,
|
||||||
|
const struct timespec *timeout,
|
||||||
|
struct uc_threadmsg **msg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Like uc_thread_queue_tryget, but will wait indefintly for an item
|
* Like uc_thread_queue_tryget, but will wait indefintly for an item
|
||||||
* to become available
|
* to become available
|
||||||
* @see uc_thread_queue_tryget
|
* @see uc_thread_queue_tryget
|
||||||
*/
|
*/
|
||||||
static inline int uc_thread_queue_get(struct uc_threadqueue *queue, struct uc_threadmsg **msg)
|
static inline int uc_thread_queue_get(struct uc_threadqueue *queue,
|
||||||
|
struct uc_threadmsg **msg)
|
||||||
{
|
{
|
||||||
return uc_thread_queue_tryget(queue, NULL, msg);
|
return uc_thread_queue_tryget(queue, NULL, msg);
|
||||||
}
|
}
|
||||||
@@ -244,7 +252,9 @@ unsigned int uc_thread_queue_length( struct uc_threadqueue *queue );
|
|||||||
* @param cookie pointer passed back to the uc_thread_queue_walk_func
|
* @param cookie pointer passed back to the uc_thread_queue_walk_func
|
||||||
* @return 0 on success EINVAL if queue is NULL EBUSY if someone is holding any locks on the queue
|
* @return 0 on success EINVAL if queue is NULL EBUSY if someone is holding any locks on the queue
|
||||||
*/
|
*/
|
||||||
int uc_thread_queue_destroy(struct uc_threadqueue *queue, uc_thread_queue_walk_func free_func, void *cookie);
|
int uc_thread_queue_destroy(struct uc_threadqueue *queue,
|
||||||
|
uc_thread_queue_walk_func free_func,
|
||||||
|
void *cookie);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Walk the elements of the queue, intended for debugging
|
* Walk the elements of the queue, intended for debugging
|
||||||
@@ -259,7 +269,9 @@ int uc_thread_queue_destroy(struct uc_threadqueue *queue, uc_thread_queue_walk_f
|
|||||||
* The function must not in anyway interact with the queue.
|
* The function must not in anyway interact with the queue.
|
||||||
* @return 0 on success
|
* @return 0 on success
|
||||||
*/
|
*/
|
||||||
int uc_thread_queue_walk(struct uc_threadqueue *queue, uc_thread_queue_walk_func walk_func, void *cookie);
|
int uc_thread_queue_walk(struct uc_threadqueue *queue,
|
||||||
|
uc_thread_queue_walk_func walk_func,
|
||||||
|
void *cookie);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -273,7 +285,9 @@ int uc_thread_queue_walk(struct uc_threadqueue *queue, uc_thread_queue_walk_func
|
|||||||
* @param cookie pointer passed back to the uc_thread_queue_walk_func
|
* @param cookie pointer passed back to the uc_thread_queue_walk_func
|
||||||
* @return 0 on success
|
* @return 0 on success
|
||||||
*/
|
*/
|
||||||
int uc_thread_queue_clear(struct uc_threadqueue *queue, uc_thread_queue_walk_func free_func, void *cookie);
|
int uc_thread_queue_clear(struct uc_threadqueue *queue,
|
||||||
|
uc_thread_queue_walk_func free_func,
|
||||||
|
void *cookie);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -32,7 +32,9 @@ int uc_ticket_lock_init(struct UCTicketLock *lock);
|
|||||||
*
|
*
|
||||||
* @return 0 on success, errno value on failure
|
* @return 0 on success, errno value on failure
|
||||||
*/
|
*/
|
||||||
int uc_ticket_lock_init_ex(struct UCTicketLock *lock, pthread_mutexattr_t *mattr, pthread_condattr_t *cattr);
|
int uc_ticket_lock_init_ex(struct UCTicketLock *lock,
|
||||||
|
pthread_mutexattr_t *mattr,
|
||||||
|
pthread_condattr_t *cattr);
|
||||||
|
|
||||||
/** Acquire the lock
|
/** Acquire the lock
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -59,17 +59,17 @@ struct timespec *uc_tssub(struct timespec *dst, const struct timespec *a, const
|
|||||||
*/
|
*/
|
||||||
int uc_tscmp(const struct timespec *a, const struct timespec *b);
|
int uc_tscmp(const struct timespec *a, const struct timespec *b);
|
||||||
|
|
||||||
static inline uint64_t uc_tv2msec(const struct timeval *t)
|
static inline uint64_t uc_tv2milisec(const struct timeval *t)
|
||||||
{
|
{
|
||||||
return t->tv_sec * 1000 + t->tv_usec / 1000;
|
return t->tv_sec * 1000 + t->tv_usec / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint64_t uc_ts2msec(const struct timespec *t)
|
static inline uint64_t uc_ts2milisec(const struct timespec *t)
|
||||||
{
|
{
|
||||||
return t->tv_sec * 1000 + t->tv_nsec / 10000000;
|
return t->tv_sec * 1000 + t->tv_nsec / 10000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint64_t uc_ts2nsec(const struct timespec *t)
|
static inline uint64_t uc_ts2nanosec(const struct timespec *t)
|
||||||
{
|
{
|
||||||
return t->tv_sec * 1000000000ULL + t->tv_nsec;
|
return t->tv_sec * 1000000000ULL + t->tv_nsec;
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-9
@@ -46,8 +46,9 @@ typedef void (*uc_timer_cb)(struct UCTimers *timers, struct UCTimer *timer);
|
|||||||
struct UCTimer {
|
struct UCTimer {
|
||||||
//Internal members
|
//Internal members
|
||||||
RBNode rb_node; //the RBNode will hold a data pointer to the
|
RBNode rb_node; //the RBNode will hold a data pointer to the
|
||||||
//the UCTimer it's a member of. We might get rid of that member, and use CONTAINER_OF
|
//the UCTimer it's a member of. We might get rid of that
|
||||||
//to find the UCTimer from a RBNode (Or just cast it, it's the 1. member..)
|
//member, and use CONTAINER_OF to find the UCTimer from
|
||||||
|
//a RBNode (Or just cast it, it's the 1. member..)
|
||||||
|
|
||||||
//absolute time when the timer should be fired
|
//absolute time when the timer should be fired
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
@@ -73,7 +74,8 @@ struct UCTimers {
|
|||||||
RBTree timer_tree;
|
RBTree timer_tree;
|
||||||
struct UCoreClock *uclock;
|
struct UCoreClock *uclock;
|
||||||
size_t seq; //used to generate unique timers
|
size_t seq; //used to generate unique timers
|
||||||
TAILQ_HEAD(, UCTimer) ready_list; //pending timers to be fired while inside uc_timers_run
|
TAILQ_HEAD(, UCTimer) ready_list; //pending timers to be fired while
|
||||||
|
//inside uc_timers_run
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Initialize a timer engine for use.
|
/** Initialize a timer engine for use.
|
||||||
@@ -103,8 +105,8 @@ void uc_timers_init_ex(struct UCTimers *t, struct UCoreClock *uclock);
|
|||||||
void uc_timers_add(struct UCTimers *timers, struct UCTimer *timer, int sec, int usec);
|
void uc_timers_add(struct UCTimers *timers, struct UCTimer *timer, int sec, int usec);
|
||||||
|
|
||||||
/** Remove a timer.
|
/** Remove a timer.
|
||||||
* Note, the timer memory must have been zeroed out or the timer must have been added at least once
|
* Note, the timer memory must have been zeroed out or the timer must have been
|
||||||
* before uc_timers_remove can be called on a UCTimer.
|
* added at least once before uc_timers_remove can be called on a UCTimer.
|
||||||
* uc_timers_remove does nothing if the timer has expired.
|
* uc_timers_remove does nothing if the timer has expired.
|
||||||
*
|
*
|
||||||
* @param timers timer engine to remove from
|
* @param timers timer engine to remove from
|
||||||
@@ -131,7 +133,8 @@ size_t uc_timers_count(const struct UCTimers *timers);
|
|||||||
/** Check if a timer is running (i.e. hasn't expired and fired)
|
/** Check if a timer is running (i.e. hasn't expired and fired)
|
||||||
*
|
*
|
||||||
* @param timer timer to query
|
* @param timer timer to query
|
||||||
* @return 0 if the timer has expired (or was never added) non-0 if it's running (active or pending)
|
* @return 0 if the timer has expired (or was never added) non-0 if it's
|
||||||
|
* running (active or pending)
|
||||||
*/
|
*/
|
||||||
int uc_timer_running(const struct UCTimer *timer);
|
int uc_timer_running(const struct UCTimer *timer);
|
||||||
|
|
||||||
@@ -141,8 +144,8 @@ int uc_timer_running(const struct UCTimer *timer);
|
|||||||
* @param timers timer engine to run
|
* @param timers timer engine to run
|
||||||
* @param now The curent time. The engine will fire all timers whose expiry time is
|
* @param now The curent time. The engine will fire all timers whose expiry time is
|
||||||
* prior to this value.
|
* prior to this value.
|
||||||
* @return the number of timers fired, or negative if an error occured(presently no errors
|
* @return the number of timers fired, or negative if an error occured(presently
|
||||||
* are possible and the return value is always >= 0
|
* no errors are possible and the return value is always >= 0
|
||||||
**/
|
**/
|
||||||
int uc_timers_run(struct UCTimers *timers);
|
int uc_timers_run(struct UCTimers *timers);
|
||||||
|
|
||||||
@@ -152,5 +155,5 @@ int uc_timers_run(struct UCTimers *timers);
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** @{ (addtogroup) */
|
/** @} (addtogroup) */
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+12
-1
@@ -2,7 +2,6 @@
|
|||||||
#define UC_UTILS_H_
|
#define UC_UTILS_H_
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
//Gnerate a compiler error if the compile time
|
//Gnerate a compiler error if the compile time
|
||||||
//constant expression fails
|
//constant expression fails
|
||||||
@@ -74,6 +73,7 @@ const typeof( ((const type *)0)->member ) *__mptr = (ptr); \
|
|||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
//include <stdio.h> if using the TRACEF() macro
|
||||||
#define TRACEF(fmt, ...)\
|
#define TRACEF(fmt, ...)\
|
||||||
do { \
|
do { \
|
||||||
fprintf(stdout, "%s (%s)\t" fmt, UC_SRC_LOCATION, __FUNCTION__, ##__VA_ARGS__);\
|
fprintf(stdout, "%s (%s)\t" fmt, UC_SRC_LOCATION, __FUNCTION__, ##__VA_ARGS__);\
|
||||||
@@ -120,5 +120,16 @@ const typeof( ((const type *)0)->member ) *__mptr = (ptr); \
|
|||||||
*/
|
*/
|
||||||
#define UC_UNUSED(x) x __attribute__((unused))
|
#define UC_UNUSED(x) x __attribute__((unused))
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
# ifdef __clang__
|
||||||
|
# define UC_INLINE inline __attribute__((always_inline))
|
||||||
|
# else
|
||||||
|
# define UC_INLINE inline __attribute__((always_inline,flatten))
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define UC_INLINE inline
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+5
-3
@@ -13,9 +13,11 @@ sources = ucore_env.Glob('*.c')
|
|||||||
#print 'sources:', sources[len(sources)-2]
|
#print 'sources:', sources[len(sources)-2]
|
||||||
|
|
||||||
#Build library
|
#Build library
|
||||||
ucore_lib = ucore_env.StaticLibrary(target='ucore' + lib_suffix , source=sources)
|
ucore_staticlib = ucore_env.StaticLibrary(target='ucore' + lib_suffix , source=sources)
|
||||||
|
ucore_sharedlib = ucore_env.SharedLibrary(target='ucore' + lib_suffix , source=sources)
|
||||||
|
|
||||||
#install targets
|
#install targets
|
||||||
ucore_env.Alias('install',
|
ucore_env.Alias('install',
|
||||||
ucore_env.Install(os.path.join(prefix, 'lib'), ucore_lib))
|
ucore_env.Install(os.path.join(prefix, 'lib'), [ucore_staticlib]))
|
||||||
|
ucore_env.Alias('install',
|
||||||
|
ucore_env.InstallVersionedLib(os.path.join(prefix, 'lib'), [ucore_sharedlib]))
|
||||||
|
|||||||
+1
-1
@@ -63,7 +63,7 @@ void uc_bv_set_bit(struct UCBitVec *v,int b)
|
|||||||
v->vec[bit_index(b)] |= 1UL << (bit_offset(b));
|
v->vec[bit_index(b)] |= 1UL << (bit_offset(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
void uc_bv_set_bits_from_array(struct UCBitVec *v,char *array,size_t array_len)
|
void uc_bv_set_bits_from_array(struct UCBitVec *v,const char *array,size_t array_len)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
|
|||||||
+8
-8
@@ -7,12 +7,12 @@
|
|||||||
#define UNUSED
|
#define UNUSED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void uc_timeofday_now(struct UCoreClock *uclock UNUSED, struct timeval *tv)
|
static void uc_timeofday_now(const struct UCoreClock *uclock UNUSED, struct timeval *tv)
|
||||||
{
|
{
|
||||||
gettimeofday(tv, NULL);
|
gettimeofday(tv, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uc_time_now(struct UCoreClock *uclock UNUSED, struct timeval *tv)
|
static void uc_time_now(const struct UCoreClock *uclock UNUSED, struct timeval *tv)
|
||||||
{
|
{
|
||||||
tv->tv_sec = time(NULL);
|
tv->tv_sec = time(NULL);
|
||||||
tv->tv_usec = 0;
|
tv->tv_usec = 0;
|
||||||
@@ -28,11 +28,11 @@ struct UCoreClock uc_time_clock = {
|
|||||||
.now = uc_time_now,
|
.now = uc_time_now,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void uc_cached_clock_now(struct UCoreClock *uclock,
|
static void uc_cached_clock_now(const struct UCoreClock *uclock,
|
||||||
struct timeval *tv)
|
struct timeval *tv)
|
||||||
{
|
{
|
||||||
struct UCoreCachedClock *cached_clock;
|
const struct UCoreCachedClock *cached_clock;
|
||||||
cached_clock = UC_CONTAINER_OF(uclock, struct UCoreCachedClock, clock),
|
cached_clock = UC_CONST_CONTAINER_OF(uclock, const struct UCoreCachedClock, clock),
|
||||||
|
|
||||||
*tv = cached_clock->cache;
|
*tv = cached_clock->cache;
|
||||||
}
|
}
|
||||||
@@ -52,10 +52,10 @@ void uc_cached_clock_update(struct UCoreCachedClock *uclock)
|
|||||||
uclock->real_clock->now(&uclock->clock, &uclock->cache);
|
uclock->real_clock->now(&uclock->clock, &uclock->cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uc_settable_clock_now(struct UCoreClock *uclock, struct timeval *tv)
|
static void uc_settable_clock_now(const struct UCoreClock *uclock, struct timeval *tv)
|
||||||
{
|
{
|
||||||
struct UCoreSettableClock *cached_clock;
|
const struct UCoreSettableClock *cached_clock;
|
||||||
cached_clock = UC_CONTAINER_OF(uclock, struct UCoreSettableClock, clock),
|
cached_clock = UC_CONST_CONTAINER_OF(uclock, const struct UCoreSettableClock, clock),
|
||||||
|
|
||||||
*tv = cached_clock->now;
|
*tv = cached_clock->now;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
enum UCCmdRc {
|
||||||
|
/**Executed ok */
|
||||||
|
UC_CMD_OK,
|
||||||
|
/**Executed with warning */
|
||||||
|
UC_CMD_WARNING,
|
||||||
|
/*Not executed, incomplete command */
|
||||||
|
UC_CMD_INCOMPLETE,
|
||||||
|
/*Not executed, generic error */
|
||||||
|
UC_CMD_ERROR,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum UCCmdRc (*uc_cmd_handler)(int narg, char *args[]);
|
||||||
|
typedef void (*uc_cmd_write_cfg)(void);
|
||||||
|
|
||||||
|
#define UC_CMD_FL_HIDDEN (1 << 0)
|
||||||
|
|
||||||
|
struct UCCmdNode;
|
||||||
|
struct UCCmdDef;
|
||||||
|
|
||||||
|
struct UCCmdSettings {
|
||||||
|
const char *name;
|
||||||
|
const char *version;
|
||||||
|
const char *boot_cfg_file;
|
||||||
|
|
||||||
|
struct UCCmdNode *initial_node;
|
||||||
|
struct UCCmdNode *node_head;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UCCmdNode {
|
||||||
|
int id;
|
||||||
|
uc_cmd_write_cfg write_func;
|
||||||
|
struct UCCmdDef *cmd_head; //linked list of UCCmdDef
|
||||||
|
struct UCCmdNode *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UCCmdDef {
|
||||||
|
const char *cmd;
|
||||||
|
const char **help;
|
||||||
|
size_t cmd_len;
|
||||||
|
uc_cmd_handler cb;
|
||||||
|
uint32_t flags;
|
||||||
|
|
||||||
|
struct UCCmdDef *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void uc_cmd_init(const char *app_name, const char *version);
|
||||||
|
int uc_cmd_read_config(const char *filename);
|
||||||
|
void uc_cmd_set_configfile(const char *filename);
|
||||||
|
void uc_cmd_add_cmd(struct UCCmdDef *cmd, int parent_node_id);
|
||||||
|
void uc_cmd_set_default_node(int node_id);
|
||||||
|
|
||||||
+1
-1
@@ -176,7 +176,7 @@ void uc_dstr_own(struct DStr *str, char *restrict s)
|
|||||||
size_t len = strlen(s);
|
size_t len = strlen(s);
|
||||||
|
|
||||||
if (str->str) {
|
if (str->str) {
|
||||||
free(str);
|
free(str->str);
|
||||||
}
|
}
|
||||||
|
|
||||||
str->len = len;
|
str->len = len;
|
||||||
|
|||||||
+2
-2
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
uc_sift(unsigned char *base, size_t start, size_t count, size_t width,
|
uc_sift(unsigned char *base, size_t start, size_t count, size_t width,
|
||||||
uc_hs_cmp cmp, uc_hs_swp swap, void *cookie)
|
uc_hs_cmp cmp, uc_hs_swp swap, void *cookie)
|
||||||
{
|
{
|
||||||
size_t root = start, child;
|
size_t root = start, child;
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ uc_sift(unsigned char *base, size_t start, size_t count, size_t width,
|
|||||||
|
|
||||||
void
|
void
|
||||||
uc_heapsort(void *base_, size_t count, size_t width,
|
uc_heapsort(void *base_, size_t count, size_t width,
|
||||||
uc_hs_cmp cmp, uc_hs_swp swap, void *cookie)
|
uc_hs_cmp cmp, uc_hs_swp swap, void *cookie)
|
||||||
{
|
{
|
||||||
long start;
|
long start;
|
||||||
long end;
|
long end;
|
||||||
|
|||||||
@@ -28,7 +28,10 @@ uc_hex_encode(const uint8_t *restrict in, size_t len, char *restrict out)
|
|||||||
}
|
}
|
||||||
|
|
||||||
char*
|
char*
|
||||||
uc_hex_encode_delim(const uint8_t *restrict in, size_t inlen, char *restrict out, int outlen, const char *restrict delim)
|
uc_hex_encode_delim(
|
||||||
|
const uint8_t *restrict in, size_t inlen,
|
||||||
|
char *restrict out, int outlen,
|
||||||
|
const char *restrict delim)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
char *outp = out;
|
char *outp = out;
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <string.h>
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "ucore/clock.h"
|
#include "ucore/clock.h"
|
||||||
#include "ucore/backtrace.h"
|
#include "ucore/backtrace.h"
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ struct IOMux {
|
|||||||
/* Used by mux implementations to hold their own data/instance */
|
/* Used by mux implementations to hold their own data/instance */
|
||||||
void *instance;
|
void *instance;
|
||||||
};
|
};
|
||||||
|
//TODO - have iomux_xx_init embed struct IOMux and get rid of IOMux.instance
|
||||||
|
//for better cache friendiness
|
||||||
|
|
||||||
int iomux_select_init(struct IOMux *mux);
|
int iomux_select_init(struct IOMux *mux);
|
||||||
int iomux_epoll_init(struct IOMux *mux);
|
int iomux_epoll_init(struct IOMux *mux);
|
||||||
|
|||||||
+43
-63
@@ -14,53 +14,26 @@ struct IOMuxSelect {
|
|||||||
fd_set master_read_set;
|
fd_set master_read_set;
|
||||||
fd_set master_write_set;
|
fd_set master_write_set;
|
||||||
|
|
||||||
struct IOMuxFD **descriptors; // array of pointers to the user IOMuxFD's
|
struct IOMuxFD *descriptors[FD_SETSIZE]; // array of pointers to the user IOMuxFD's
|
||||||
size_t alloc_descriptors; //allocated descriptors in 'descriptors'
|
size_t alloc_descriptors; //allocated descriptors in 'descriptors'
|
||||||
size_t num_descriptors; //number of descriptors we're watching
|
size_t num_descriptors; //number of descriptors we're watching
|
||||||
size_t deleted_cnt; //used to rebuild the descriptors array
|
int recalc_max;
|
||||||
int max_fd; //keeps track of the max fd for select()
|
int max_fd; //keeps track of the max fd for select()
|
||||||
};
|
};
|
||||||
|
|
||||||
static int iomux_select_update_events(struct IOMux *mux_, struct IOMuxFD *fd);
|
static int iomux_select_update_events(struct IOMux *mux_, struct IOMuxFD *fd);
|
||||||
|
|
||||||
//grows the descriptor array. We never shrink it.
|
|
||||||
static int iomux_select_grow(struct IOMuxSelect *mux)
|
|
||||||
{
|
|
||||||
void *tmp = realloc(mux->descriptors, (mux->num_descriptors + IOMUX_GROW_CHUNK) * sizeof *mux->descriptors);
|
|
||||||
assert(tmp != NULL);
|
|
||||||
if (tmp == NULL)
|
|
||||||
return ENOMEM;
|
|
||||||
|
|
||||||
mux->alloc_descriptors += IOMUX_GROW_CHUNK;
|
static void iomux_select_recalc_max(struct IOMuxSelect *mux)
|
||||||
mux->descriptors = tmp;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void iomux_select_remove(struct IOMuxSelect *mux, size_t idx)
|
|
||||||
{
|
|
||||||
if (mux->num_descriptors > 1) {
|
|
||||||
//move last element into the empty slot
|
|
||||||
size_t last_idx = mux->num_descriptors - 1;
|
|
||||||
mux->descriptors[idx] = mux->descriptors[last_idx];
|
|
||||||
mux->descriptors[last_idx] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
mux->num_descriptors--;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void iomux_select_rebuild(struct IOMuxSelect *mux)
|
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
size_t n;
|
||||||
mux->max_fd = -1;
|
mux->max_fd = -1;
|
||||||
for (i = 0; i < mux->num_descriptors; ) {
|
|
||||||
if (mux->descriptors[i] == NULL) {
|
for (i = 0, n = 0; i < FD_SETSIZE && n < mux->num_descriptors; i++) {
|
||||||
iomux_select_remove(mux, i);
|
if (mux->descriptors[i] != NULL) {
|
||||||
//a deleted fd slot needs to be rechecked, no i++ here
|
|
||||||
} else {
|
|
||||||
mux->max_fd = UC_MAX(mux->descriptors[i]->fd, mux->max_fd);
|
mux->max_fd = UC_MAX(mux->descriptors[i]->fd, mux->max_fd);
|
||||||
i++;
|
n++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -70,6 +43,10 @@ static int iomux_select_update_events(struct IOMux *mux_, struct IOMuxFD *fd)
|
|||||||
{
|
{
|
||||||
struct IOMuxSelect *mux = mux_->instance;
|
struct IOMuxSelect *mux = mux_->instance;
|
||||||
|
|
||||||
|
if (fd->fd < 0 || fd->fd >= FD_SETSIZE) {
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (fd->what & MUX_EV_READ)
|
if (fd->what & MUX_EV_READ)
|
||||||
FD_SET(fd->fd, &mux->master_read_set);
|
FD_SET(fd->fd, &mux->master_read_set);
|
||||||
else
|
else
|
||||||
@@ -86,18 +63,19 @@ static int iomux_select_update_events(struct IOMux *mux_, struct IOMuxFD *fd)
|
|||||||
static int iomux_select_register_fd(struct IOMux *mux_, struct IOMuxFD *fd)
|
static int iomux_select_register_fd(struct IOMux *mux_, struct IOMuxFD *fd)
|
||||||
{
|
{
|
||||||
struct IOMuxSelect *mux = mux_->instance;
|
struct IOMuxSelect *mux = mux_->instance;
|
||||||
if (fd->what == 0 || fd->callback == NULL)
|
int rc;
|
||||||
|
|
||||||
|
if ((fd->what & MUX_EV_MASK) == 0 || fd->callback == NULL)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
if (mux->num_descriptors == mux->alloc_descriptors) {
|
rc = iomux_select_update_events(mux_, fd);
|
||||||
if (iomux_select_grow(mux) != 0)
|
if (rc != 0) {
|
||||||
return ENOMEM;
|
return ENFILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
mux->descriptors[mux->num_descriptors] = fd;
|
mux->descriptors[fd->fd] = fd;
|
||||||
mux->num_descriptors++;
|
mux->num_descriptors++;
|
||||||
|
|
||||||
iomux_select_update_events(mux_, fd);
|
|
||||||
|
|
||||||
mux->max_fd = UC_MAX(fd->fd, mux->max_fd);
|
mux->max_fd = UC_MAX(fd->fd, mux->max_fd);
|
||||||
|
|
||||||
@@ -109,18 +87,21 @@ static int iomux_select_unregister_fd(struct IOMux *mux_, struct IOMuxFD *fd)
|
|||||||
struct IOMuxSelect *mux = mux_->instance;
|
struct IOMuxSelect *mux = mux_->instance;
|
||||||
int rc = ENOENT;
|
int rc = ENOENT;
|
||||||
|
|
||||||
size_t i;
|
if (fd->fd < 0 || fd->fd >= FD_SETSIZE) {
|
||||||
for (i = 0; i < mux->num_descriptors; i++) {
|
return ENFILE;
|
||||||
if (fd == mux->descriptors[i]) {
|
}
|
||||||
unsigned int what = fd->what; //make sure we don't alter 'what' as seen from the user
|
|
||||||
fd->what &= ~MUX_EV_MASK;
|
if (mux->descriptors[fd->fd] != NULL) {
|
||||||
iomux_select_update_events(mux_, fd);
|
unsigned int what = fd->what; //make sure we don't alter 'what' as seen from the user
|
||||||
mux->descriptors[i] = NULL; //set the slot to NULL, the event loop needs to rebuild it.
|
|
||||||
mux->deleted_cnt++;
|
fd->what = 0;
|
||||||
fd->what = what;
|
iomux_select_update_events(mux_, fd);
|
||||||
rc = 0;
|
mux->descriptors[fd->fd] = NULL;
|
||||||
break;
|
mux->recalc_max = 1;
|
||||||
}
|
fd->what = what;
|
||||||
|
|
||||||
|
rc = 0;
|
||||||
|
mux->num_descriptors--;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
@@ -136,9 +117,9 @@ static int iomux_select_run(struct IOMux *mux_, struct timeval *timeout)
|
|||||||
fd_set read_set;
|
fd_set read_set;
|
||||||
fd_set write_set;
|
fd_set write_set;
|
||||||
|
|
||||||
if (mux->deleted_cnt) {
|
if (mux->recalc_max) {
|
||||||
iomux_select_rebuild(mux);
|
iomux_select_recalc_max(mux);
|
||||||
mux->deleted_cnt = 0;
|
mux->recalc_max = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mux->max_fd == -1 && timeout == NULL)
|
if (mux->max_fd == -1 && timeout == NULL)
|
||||||
@@ -161,8 +142,8 @@ static int iomux_select_run(struct IOMux *mux_, struct timeval *timeout)
|
|||||||
if (rc == 0) //no fd's were ready, no more work to do
|
if (rc == 0) //no fd's were ready, no more work to do
|
||||||
return event_cnt;
|
return event_cnt;
|
||||||
|
|
||||||
for (i = 0; rc > 0 && i < mux->num_descriptors; i++) {
|
for (i = 0; rc > 0 && i < FD_SETSIZE; i++) {
|
||||||
unsigned int events = 0;
|
int had_event = 0;
|
||||||
|
|
||||||
//deliver only one event at a time , to simplify application
|
//deliver only one event at a time , to simplify application
|
||||||
//programming
|
//programming
|
||||||
@@ -171,7 +152,7 @@ static int iomux_select_run(struct IOMux *mux_, struct timeval *timeout)
|
|||||||
rc--;
|
rc--;
|
||||||
assert(mux->descriptors[i]->callback != NULL);
|
assert(mux->descriptors[i]->callback != NULL);
|
||||||
mux->descriptors[i]->callback(mux_, mux->descriptors[i], MUX_EV_READ);
|
mux->descriptors[i]->callback(mux_, mux->descriptors[i], MUX_EV_READ);
|
||||||
events = 1;
|
had_event = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//need to re-check in case the callback deleted the IOMuxFD
|
//need to re-check in case the callback deleted the IOMuxFD
|
||||||
@@ -180,10 +161,11 @@ static int iomux_select_run(struct IOMux *mux_, struct timeval *timeout)
|
|||||||
rc--;
|
rc--;
|
||||||
assert(mux->descriptors[i]->callback != NULL);
|
assert(mux->descriptors[i]->callback != NULL);
|
||||||
mux->descriptors[i]->callback(mux_, mux->descriptors[i], MUX_EV_WRITE);
|
mux->descriptors[i]->callback(mux_, mux->descriptors[i], MUX_EV_WRITE);
|
||||||
events = 1;
|
had_event = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
event_cnt += events;
|
event_cnt += had_event;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return event_cnt;
|
return event_cnt;
|
||||||
@@ -193,8 +175,6 @@ static void iomux_select_delete(struct IOMux *mux)
|
|||||||
{
|
{
|
||||||
if (mux != NULL && mux->instance != NULL) {
|
if (mux != NULL && mux->instance != NULL) {
|
||||||
struct IOMuxSelect *mux_select = mux->instance;
|
struct IOMuxSelect *mux_select = mux->instance;
|
||||||
free(mux_select->descriptors);
|
|
||||||
mux_select->descriptors = NULL;
|
|
||||||
free(mux_select);
|
free(mux_select);
|
||||||
mux->instance = NULL;
|
mux->instance = NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
+44
-39
@@ -30,18 +30,21 @@ enum UC_LOG_DESTINATION {
|
|||||||
#define UC_MAX_RENAME_CNT (128)
|
#define UC_MAX_RENAME_CNT (128)
|
||||||
|
|
||||||
//used to realise per destination settings
|
//used to realise per destination settings
|
||||||
struct UCLogModule_setting {
|
struct UCLogModuleSetting {
|
||||||
int log_level;
|
enum UC_LOG_LEVEL log_level;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct UCLogArgs;
|
||||||
|
typedef void (*uc_vlog_func)(const struct UCLogArgs *args, const char *fmt, va_list ap);
|
||||||
|
|
||||||
struct UCLogDestination {
|
struct UCLogDestination {
|
||||||
struct TailQ entry;
|
struct TailQ entry;
|
||||||
enum UC_LOG_DESTINATION dest_type;
|
enum UC_LOG_DESTINATION dest_type;
|
||||||
//log level for this destination
|
//log level for this destination
|
||||||
int log_level;
|
enum UC_LOG_LEVEL log_level;
|
||||||
//Whether to log the source file name and line number
|
//Whether to log the source file name and line number
|
||||||
int log_location;
|
int log_location;
|
||||||
struct UCLogModule_setting *module_settings;
|
struct UCLogModuleSetting *module_settings;
|
||||||
union {
|
union {
|
||||||
//for syslog openlog()
|
//for syslog openlog()
|
||||||
struct {
|
struct {
|
||||||
@@ -57,13 +60,15 @@ struct UCLogDestination {
|
|||||||
struct UCLogRotateSettings rotate;
|
struct UCLogRotateSettings rotate;
|
||||||
} file;
|
} file;
|
||||||
} type;
|
} type;
|
||||||
|
|
||||||
|
uc_vlog_func log_func;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Helper struct for arguments to our main logging function */
|
/* Helper struct for arguments to our main logging function */
|
||||||
struct UCLogArgs {
|
struct UCLogArgs {
|
||||||
struct UCLogDestination *dest;
|
struct UCLogDestination *dest;
|
||||||
const struct UCLogModule *module;
|
const struct UCLogModule *module;
|
||||||
int log_level;
|
enum UC_LOG_LEVEL log_level;
|
||||||
const char *location;
|
const char *location;
|
||||||
int raw;
|
int raw;
|
||||||
};
|
};
|
||||||
@@ -87,6 +92,9 @@ static const struct UCLogModule g_unknown_module = {
|
|||||||
//this list an anything contained within it.
|
//this list an anything contained within it.
|
||||||
static UC_TAILQ_HEAD(g_destinations);
|
static UC_TAILQ_HEAD(g_destinations);
|
||||||
static int uc_log_reopen_file(struct UCLogDestination *dest);
|
static int uc_log_reopen_file(struct UCLogDestination *dest);
|
||||||
|
static inline void uc_log_file_rotate_if_neeed(struct UCLogDestination *dest, time_t tstamp);
|
||||||
|
static void uc_vlog_file(const struct UCLogArgs *args, const char *fmt, va_list ap);
|
||||||
|
static void uc_vlog_syslog(const struct UCLogArgs *args, const char *fmt, va_list ap);
|
||||||
//Uses enum UC_LOG_LEVEL as index
|
//Uses enum UC_LOG_LEVEL as index
|
||||||
static const char *const g_log_levels[] = {
|
static const char *const g_log_levels[] = {
|
||||||
"UNKNOWN_0",
|
"UNKNOWN_0",
|
||||||
@@ -168,7 +176,7 @@ static int uc_log_init_common(struct UCLogDestination *dest)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UCLogDestination *uc_log_new_stderr(int log_level, int log_location)
|
struct UCLogDestination *uc_log_new_stderr(enum UC_LOG_LEVEL log_level, int log_location)
|
||||||
{
|
{
|
||||||
struct UCLogDestination *dest = calloc(1, sizeof *dest);
|
struct UCLogDestination *dest = calloc(1, sizeof *dest);
|
||||||
|
|
||||||
@@ -185,11 +193,15 @@ struct UCLogDestination *uc_log_new_stderr(int log_level, int log_location)
|
|||||||
dest->type.file.size = 0;
|
dest->type.file.size = 0;
|
||||||
dest->log_level = log_level;;
|
dest->log_level = log_level;;
|
||||||
dest->log_location = log_location;
|
dest->log_location = log_location;
|
||||||
|
dest->log_func = uc_vlog_file;
|
||||||
|
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UCLogDestination *uc_log_new_syslog(const char *ident, int facility, int log_level, int log_location)
|
struct UCLogDestination *uc_log_new_syslog(const char *ident,
|
||||||
|
int facility,
|
||||||
|
enum UC_LOG_LEVEL log_level,
|
||||||
|
int log_location)
|
||||||
{
|
{
|
||||||
struct UCLogDestination *dest = calloc(1, sizeof *dest);
|
struct UCLogDestination *dest = calloc(1, sizeof *dest);
|
||||||
char *id;
|
char *id;
|
||||||
@@ -217,11 +229,12 @@ struct UCLogDestination *uc_log_new_syslog(const char *ident, int facility, int
|
|||||||
dest->type.syslog.facility = facility;
|
dest->type.syslog.facility = facility;
|
||||||
dest->log_level = log_level;;
|
dest->log_level = log_level;;
|
||||||
dest->log_location = log_location;
|
dest->log_location = log_location;
|
||||||
|
dest->log_func = uc_vlog_syslog;
|
||||||
|
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UCLogDestination *uc_log_new_file(const char *filename, int log_level, int log_location)
|
struct UCLogDestination *uc_log_new_file(const char *filename, enum UC_LOG_LEVEL log_level, int log_location)
|
||||||
{
|
{
|
||||||
struct UCLogDestination *dest = calloc(1, sizeof *dest);
|
struct UCLogDestination *dest = calloc(1, sizeof *dest);
|
||||||
FILE *f;
|
FILE *f;
|
||||||
@@ -261,6 +274,8 @@ struct UCLogDestination *uc_log_new_file(const char *filename, int log_level, in
|
|||||||
|
|
||||||
dest->type.file.rotate.policy = UC_LOG_ROTATE_NONE;
|
dest->type.file.rotate.policy = UC_LOG_ROTATE_NONE;
|
||||||
|
|
||||||
|
dest->log_func = uc_vlog_file;
|
||||||
|
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -435,10 +450,12 @@ int uc_log_reopen_files(void)
|
|||||||
UC_TAILQ_FOREACH_CONTAINER(dest, entry, &g_destinations) {
|
UC_TAILQ_FOREACH_CONTAINER(dest, entry, &g_destinations) {
|
||||||
|
|
||||||
if (dest->dest_type == UC_LDEST_FILE) {
|
if (dest->dest_type == UC_LDEST_FILE) {
|
||||||
rc = uc_log_reopen_file(dest);
|
int r_rc;
|
||||||
if (rc == 0) {
|
r_rc = uc_log_reopen_file(dest);
|
||||||
dest->type.file.size = 0;
|
if (r_rc != 0) {
|
||||||
|
rc = r_rc;
|
||||||
}
|
}
|
||||||
|
dest->type.file.size = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -447,22 +464,25 @@ int uc_log_reopen_files(void)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uc_log_init(struct UCLogModules *user_modules)
|
void uc_log_init(const struct UCLogModules *user_modules)
|
||||||
{
|
{
|
||||||
g_modules = *user_modules;
|
g_modules = *user_modules;
|
||||||
}
|
}
|
||||||
|
|
||||||
//hold g_log_lock while calling this
|
//hold g_log_lock while calling this
|
||||||
static inline void uc_vlog_file(const struct UCLogArgs *args, time_t tstamp, const char *fmt, va_list ap)
|
static void uc_vlog_file(const struct UCLogArgs *args, const char *fmt, va_list ap)
|
||||||
{
|
{
|
||||||
struct UCLogDestination *dest = args->dest;
|
struct UCLogDestination *dest = args->dest;
|
||||||
char time_buf[48];
|
char time_buf[48];
|
||||||
struct tm t;
|
struct tm t;
|
||||||
|
time_t tstamp;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (dest->type.file.file == NULL)
|
if (dest->type.file.file == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
tstamp = time(NULL);
|
||||||
|
|
||||||
localtime_r(&tstamp, &t);
|
localtime_r(&tstamp, &t);
|
||||||
if (!args->raw) {
|
if (!args->raw) {
|
||||||
snprintf(time_buf, sizeof time_buf, "%04d-%02d-%02d %02d:%02d:%02d",
|
snprintf(time_buf, sizeof time_buf, "%04d-%02d-%02d %02d:%02d:%02d",
|
||||||
@@ -495,10 +515,12 @@ static inline void uc_vlog_file(const struct UCLogArgs *args, time_t tstamp, con
|
|||||||
rc = fflush(dest->type.file.file); //strictly not needed for stderr
|
rc = fflush(dest->type.file.file); //strictly not needed for stderr
|
||||||
// though stderr could be redirected to a file
|
// though stderr could be redirected to a file
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uc_log_file_rotate_if_neeed(dest, tstamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
//hold g_log_lock while calling this
|
//hold g_log_lock while calling this
|
||||||
static inline void uc_vlog_syslog(const struct UCLogArgs *args, const char *fmt, va_list ap)
|
static void uc_vlog_syslog(const struct UCLogArgs *args, const char *fmt, va_list ap)
|
||||||
{
|
{
|
||||||
struct UCLogDestination *dest = args->dest;
|
struct UCLogDestination *dest = args->dest;
|
||||||
|
|
||||||
@@ -616,7 +638,6 @@ static void uc_log_file_rotate_size(struct UCLogDestination *dest)
|
|||||||
char new_filename[_POSIX_PATH_MAX * 2];
|
char new_filename[_POSIX_PATH_MAX * 2];
|
||||||
char old_filename[_POSIX_PATH_MAX * 2];
|
char old_filename[_POSIX_PATH_MAX * 2];
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (dest->type.file.file_name == NULL) {
|
if (dest->type.file.file_name == NULL) {
|
||||||
return;
|
return;
|
||||||
@@ -625,8 +646,8 @@ static void uc_log_file_rotate_size(struct UCLogDestination *dest)
|
|||||||
//rotate existing .num files
|
//rotate existing .num files
|
||||||
i = dest->type.file.rotate.size_settings.num_files -1;
|
i = dest->type.file.rotate.size_settings.num_files -1;
|
||||||
while (i > 0) {
|
while (i > 0) {
|
||||||
snprintf(new_filename, sizeof new_filename, "%s.%d", dest->type.file.file_name, i);
|
snprintf(new_filename, sizeof new_filename, "%s.%u", dest->type.file.file_name, i);
|
||||||
snprintf(old_filename, sizeof old_filename, "%s.%d", dest->type.file.file_name, i - 1);
|
snprintf(old_filename, sizeof old_filename, "%s.%u", dest->type.file.file_name, i - 1);
|
||||||
rename(old_filename, new_filename);
|
rename(old_filename, new_filename);
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
@@ -636,10 +657,8 @@ static void uc_log_file_rotate_size(struct UCLogDestination *dest)
|
|||||||
rename(dest->type.file.file_name, new_filename);
|
rename(dest->type.file.file_name, new_filename);
|
||||||
|
|
||||||
//re-open current file
|
//re-open current file
|
||||||
rc = uc_log_reopen_file(dest);
|
uc_log_reopen_file(dest);
|
||||||
if (rc == 0) {
|
dest->type.file.size = 0;
|
||||||
dest->type.file.size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -662,7 +681,7 @@ static inline void uc_log_file_rotate_if_neeed(struct UCLogDestination *dest, ti
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void uc_logf(int log_level, int module, int raw,
|
void uc_logf(enum UC_LOG_LEVEL log_level, int module, int raw,
|
||||||
const char *location, const char *fmt, ...)
|
const char *location, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
@@ -676,7 +695,7 @@ void uc_logf(int log_level, int module, int raw,
|
|||||||
UC_TAILQ_FOREACH_CONTAINER(dest, entry, &g_destinations) {
|
UC_TAILQ_FOREACH_CONTAINER(dest, entry, &g_destinations) {
|
||||||
const struct UCLogModule *log_module;
|
const struct UCLogModule *log_module;
|
||||||
va_list apc;
|
va_list apc;
|
||||||
int module_log_level;
|
enum UC_LOG_LEVEL module_log_level;
|
||||||
|
|
||||||
|
|
||||||
//destnation level
|
//destnation level
|
||||||
@@ -705,25 +724,11 @@ void uc_logf(int log_level, int module, int raw,
|
|||||||
.raw = raw
|
.raw = raw
|
||||||
};
|
};
|
||||||
|
|
||||||
time_t tstamp;
|
//log_func will mess with the va_list,
|
||||||
//log func will mess with the va_list,
|
|
||||||
//so make a copy
|
//so make a copy
|
||||||
va_copy(apc, ap);
|
va_copy(apc, ap);
|
||||||
|
|
||||||
switch (dest->dest_type) {
|
dest->log_func(&args, fmt, apc);
|
||||||
case UC_LDEST_SYSLOG:
|
|
||||||
uc_vlog_syslog(&args, fmt, apc);
|
|
||||||
break;
|
|
||||||
case UC_LDEST_STDERR:
|
|
||||||
tstamp = time(NULL);
|
|
||||||
uc_vlog_file(&args, tstamp,fmt, apc);
|
|
||||||
break;
|
|
||||||
case UC_LDEST_FILE:
|
|
||||||
tstamp = time(NULL);
|
|
||||||
uc_vlog_file(&args, tstamp, fmt, apc);
|
|
||||||
uc_log_file_rotate_if_neeed(dest, tstamp);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
va_end(apc);
|
va_end(apc);
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-1
@@ -40,7 +40,11 @@ uint8_t *uc_mbuf_pull(struct MBuf *mbuf, uint32_t size)
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uc_mbuf_init(struct MBuf *mbuf, uint8_t *restrict buf, uint32_t len, uint32_t headroom, uint32_t flags)
|
void uc_mbuf_init(struct MBuf *mbuf,
|
||||||
|
uint8_t *restrict buf,
|
||||||
|
uint32_t len,
|
||||||
|
uint32_t headroom,
|
||||||
|
uint32_t flags)
|
||||||
{
|
{
|
||||||
mbuf->bufstart = buf;
|
mbuf->bufstart = buf;
|
||||||
mbuf->p1 = mbuf->p2 = mbuf->p3 = mbuf->p4 = NULL;
|
mbuf->p1 = mbuf->p2 = mbuf->p3 = mbuf->p4 = NULL;
|
||||||
@@ -199,3 +203,21 @@ int uc_mbuf_extend_tailroom(struct MBuf *mbuf, uint32_t len)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void uc_mbuf_enqueue(struct MBuf *mbuf, struct TailQ *head)
|
||||||
|
{
|
||||||
|
uc_tailq_insert_tail(head, &mbuf->entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MBuf *uc_mbuf_dequeue(struct TailQ *head)
|
||||||
|
{
|
||||||
|
struct TailQ *q;
|
||||||
|
|
||||||
|
if (uc_tailq_empty(head)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
q = UC_TAILQ_FIRST(head);
|
||||||
|
uc_tailq_remove(q);
|
||||||
|
|
||||||
|
return UC_TAILQ_CONTAINER(q, struct MBuf, entry);
|
||||||
|
}
|
||||||
|
|||||||
+100
@@ -0,0 +1,100 @@
|
|||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
|
static int uc_mkdir(const char *full_path, mode_t mode)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = stat(full_path, &st);
|
||||||
|
if (rc == -1 && errno == ENOENT) {
|
||||||
|
rc = mkdir(full_path, mode);
|
||||||
|
if (rc == -1 && errno != EEXIST) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else if (rc == 0) {
|
||||||
|
if (!S_ISDIR(st.st_mode)) {
|
||||||
|
errno = ENOTDIR;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uc_mkdir_p(const char *full_path, mode_t mode)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
int rc;
|
||||||
|
char *path;
|
||||||
|
char *p;
|
||||||
|
int create_final = 1;
|
||||||
|
|
||||||
|
if (full_path == NULL || full_path[0] == 0) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = stat(full_path, &st);
|
||||||
|
if (rc == 0) { //already exists
|
||||||
|
if (!S_ISDIR(st.st_mode)) {
|
||||||
|
errno = ENOTDIR;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
path = strdup(full_path);
|
||||||
|
if (path == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//skip leading /
|
||||||
|
for (p = path; *p == '/'; p++)
|
||||||
|
;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
p = strchr(p, '/');
|
||||||
|
if (p == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*p = 0;
|
||||||
|
|
||||||
|
rc = uc_mkdir(path, mode);
|
||||||
|
if (rc != 0) {
|
||||||
|
free(path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*p = '/';
|
||||||
|
//in case of multiple / , e.g. foo//bar
|
||||||
|
for (; *p == '/'; p++)
|
||||||
|
;
|
||||||
|
|
||||||
|
if (*p == 0) {
|
||||||
|
create_final = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//last part, in case full_path does not end with a /
|
||||||
|
if (create_final) {
|
||||||
|
rc = uc_mkdir(path, mode);
|
||||||
|
} else {
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(path);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -20,8 +20,7 @@ static UCRCResult uc_restart_counter_lock(int fd)
|
|||||||
return UC_RC_OK;
|
return UC_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
UCRCResult uc_restart_counter_init(
|
UCRCResult uc_restart_counter_init(struct UCRestartCounter *counter,
|
||||||
struct UCRestartCounter *counter,
|
|
||||||
const char *filename,
|
const char *filename,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#include "ucore/hash.h"
|
||||||
|
|
||||||
unsigned long
|
unsigned long
|
||||||
uc_sdbmhash(const unsigned char *str)
|
uc_sdbmhash(const unsigned char *str)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "ucore/string.h"
|
||||||
|
|
||||||
size_t uc_strlcpy(char *restrict dst, const char *restrict src, size_t max)
|
size_t uc_strlcpy(char *restrict dst, const char *restrict src, size_t max)
|
||||||
{
|
{
|
||||||
|
|||||||
+11
-5
@@ -8,6 +8,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include "ucore/supervisor.h"
|
||||||
|
|
||||||
|
|
||||||
#define CLEAN_EXIT 11
|
#define CLEAN_EXIT 11
|
||||||
@@ -65,18 +66,22 @@ again:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (WIFSIGNALED(status)) {
|
if (WIFSIGNALED(status)) {
|
||||||
syslog(LOG_ERR, "supervised process(pid %ld) exited cause of signal %d, status = 0x%X", (long)pid, WTERMSIG(status), status);
|
syslog(LOG_ERR, "supervised process(pid %ld) exited cause of signal %d, status = 0x%X",
|
||||||
|
(long)pid, WTERMSIG(status), status);
|
||||||
return RESTART;
|
return RESTART;
|
||||||
} else if (WIFEXITED(status)) {
|
} else if (WIFEXITED(status)) {
|
||||||
syslog(LOG_ERR, "supervised process(pid %ld) exited with code %d, status = 0x%X", (long)pid, WTERMSIG(status), status);
|
syslog(LOG_ERR, "supervised process(pid %ld) exited with code %d, status = 0x%X",
|
||||||
|
(long)pid, WTERMSIG(status), status);
|
||||||
return RESTART;
|
return RESTART;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ok, can we ever get here ? */
|
/* Ok, can we ever get here ? */
|
||||||
|
|
||||||
syslog(LOG_ERR, "waitpid of supervised process(pid %ld) status = 0x%X", (long)pid, status);
|
syslog(LOG_ERR, "waitpid of supervised process(pid %ld) status = 0x%X",
|
||||||
|
(long)pid, status);
|
||||||
if (kill(pid, 0) == 0) {
|
if (kill(pid, 0) == 0) {
|
||||||
syslog(LOG_ERR, "supervised process(pid %ld) seems to still be alive, not restarting", (long)pid);
|
syslog(LOG_ERR, "supervised process(pid %ld) seems to still be alive, not restarting",
|
||||||
|
(long)pid);
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,7 +138,8 @@ int uc_supervise(void)
|
|||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
|
|
||||||
case CLEAN_EXIT:
|
case CLEAN_EXIT:
|
||||||
syslog(LOG_INFO, "Terminating supervised pid %lu", (unsigned long)pid);
|
syslog(LOG_INFO, "Terminating supervised pid %lu",
|
||||||
|
(unsigned long)pid);
|
||||||
kill_supervised_process(pid);
|
kill_supervised_process(pid);
|
||||||
wait(NULL);
|
wait(NULL);
|
||||||
syslog(LOG_INFO, "Exiting");
|
syslog(LOG_INFO, "Exiting");
|
||||||
|
|||||||
+4
-4
@@ -270,7 +270,7 @@ unsigned int uc_thread_queue_length(struct uc_threadqueue *queue)
|
|||||||
unsigned int length;
|
unsigned int length;
|
||||||
|
|
||||||
if (queue == NULL ) {
|
if (queue == NULL ) {
|
||||||
return -EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
// get the length properly
|
// get the length properly
|
||||||
pthread_mutex_lock(&queue->mutex);
|
pthread_mutex_lock(&queue->mutex);
|
||||||
@@ -281,11 +281,11 @@ unsigned int uc_thread_queue_length(struct uc_threadqueue *queue)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int uc_thread_queue_clear(struct uc_threadqueue *queue,
|
int uc_thread_queue_clear(struct uc_threadqueue *queue,
|
||||||
uc_thread_queue_walk_func free_func,
|
uc_thread_queue_walk_func free_func,
|
||||||
void *cookie)
|
void *cookie)
|
||||||
{
|
{
|
||||||
if (queue == NULL) {
|
if (queue == NULL) {
|
||||||
return -EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&queue->mutex);
|
pthread_mutex_lock(&queue->mutex);
|
||||||
|
|||||||
+3
-1
@@ -13,7 +13,9 @@ int uc_ticket_lock_init(struct UCTicketLock *lock)
|
|||||||
return uc_ticket_lock_init_ex(lock, NULL, NULL);
|
return uc_ticket_lock_init_ex(lock, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int uc_ticket_lock_init_ex(struct UCTicketLock *lock, pthread_mutexattr_t *mattr, pthread_condattr_t *cattr)
|
int uc_ticket_lock_init_ex(struct UCTicketLock *lock,
|
||||||
|
pthread_mutexattr_t *mattr,
|
||||||
|
pthread_condattr_t *cattr)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
lock->queue_head = 0;
|
lock->queue_head = 0;
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ test_executable = 'test_runner'
|
|||||||
if test_xml:
|
if test_xml:
|
||||||
test_executable += ' -x'
|
test_executable += ' -x'
|
||||||
|
|
||||||
|
#rpath to shared lib, so test_runner can actually be executed
|
||||||
|
test_env.Append(LINKFLAGS = ['-Wl,-rpath,\\$$ORIGIN/../src'])
|
||||||
|
|
||||||
prog = test_env.Program('test_runner', tests)
|
prog = test_env.Program('test_runner', tests)
|
||||||
cmd = test_env.Command(target='test_phony' ,
|
cmd = test_env.Command(target='test_phony' ,
|
||||||
source = None,
|
source = None,
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "ucore/atomic.h"
|
#include "ucore/atomic.h"
|
||||||
UC_ATOMIC(unsigned int) i;
|
UC_ATOMIC(unsigned int) i;
|
||||||
|
|
||||||
@@ -48,3 +50,20 @@ unsigned int get_i_compbar()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
printf("i: %u\n", get_i());
|
||||||
|
inc_i();
|
||||||
|
printf("i: %u\n", get_i());
|
||||||
|
inc_i();
|
||||||
|
dec_i();
|
||||||
|
printf("i: %u\n", get_i());
|
||||||
|
add_i(100);
|
||||||
|
printf("i: %u\n", get_i());
|
||||||
|
sub_i(50);
|
||||||
|
printf("i: %u\n", get_i_membar());
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-12
@@ -49,27 +49,27 @@ int main(int argc, char *argv[])
|
|||||||
uc_log_add_destination(dest);
|
uc_log_add_destination(dest);
|
||||||
dest = uc_log_new_stderr(UC_LL_INFO, 0);
|
dest = uc_log_new_stderr(UC_LL_INFO, 0);
|
||||||
uc_log_add_destination(dest);
|
uc_log_add_destination(dest);
|
||||||
UC_LOGF( UC_LL_INFO, CC, "Test cc info %d\n", 2);
|
UC_LOGF( UC_LL_INFO, CC, "Test cc info %d", 2);
|
||||||
UC_LOGF( UC_LL_INFO, CC, "Test cc info %d\n", 3);
|
UC_LOGF( UC_LL_INFO, CC, "Test cc info %d", 3);
|
||||||
UC_LOGF( UC_LL_INFO, CC, "Test cc info %d\n", 4);
|
UC_LOGF( UC_LL_INFO, CC, "Test cc info %d", 4);
|
||||||
UC_LOGF( UC_LL_INFO, CC, "Test cc info %d\n", 5);
|
UC_LOGF( UC_LL_INFO, CC, "Test cc info %d", 5);
|
||||||
UC_LOGF( UC_LL_WARNING, HO, "Test HO warning%d\n", 2);
|
UC_LOGF( UC_LL_WARNING, HO, "Test HO warning%d", 2);
|
||||||
UC_LOGF( UC_LL_INFO, MAIN, "Test MAIN info \n" );
|
UC_LOGF( UC_LL_INFO, MAIN, "Test MAIN info " );
|
||||||
UC_LOGF( UC_LL_WARNING, MAIN, "Test MAIN warning\n" );
|
UC_LOGF( UC_LL_WARNING, MAIN, "Test MAIN warning" );
|
||||||
|
|
||||||
uc_log_destination_set_module_loglevel(dest, MAIN, UC_LL_INFO);
|
uc_log_destination_set_module_loglevel(dest, MAIN, UC_LL_INFO);
|
||||||
UC_LOGF( UC_LL_INFO, MAIN, "Test MAIN INFO 2\n" );
|
UC_LOGF( UC_LL_INFO, MAIN, "Test MAIN INFO 2" );
|
||||||
|
|
||||||
UC_LOGFR(UC_LL_INFO, MAIN, "Test RAW logging 1\n" );
|
UC_LOGFR(UC_LL_INFO, MAIN, "Test RAW logging 1" );
|
||||||
|
|
||||||
uc_log_destination_set_module_loglevel(dest,MAIN, UC_LL_WARNING);
|
uc_log_destination_set_module_loglevel(dest,MAIN, UC_LL_WARNING);
|
||||||
UC_LOGF( UC_LL_INFO, MAIN, "Test MAIN INFO 3\n" );
|
UC_LOGF( UC_LL_INFO, MAIN, "Test MAIN INFO 3" );
|
||||||
|
|
||||||
uc_log_destination_set_loglevel(dest, UC_LL_DEBUG);
|
uc_log_destination_set_loglevel(dest, UC_LL_DEBUG);
|
||||||
UC_LOGF( UC_LL_DEBUG, MAIN, "Test MAIN DEBUG SHOULD NOT SHOW\n" );
|
UC_LOGF( UC_LL_DEBUG, MAIN, "Test MAIN DEBUG SHOULD NOT SHOW" );
|
||||||
//uc_log_destination_set_module_loglevel(dest, MAIN, UC_LL_INFO);
|
//uc_log_destination_set_module_loglevel(dest, MAIN, UC_LL_INFO);
|
||||||
uc_log_destination_set_mask(dest, "HO=ERROR:MAIN=DEBUG:HO=DEBUG");
|
uc_log_destination_set_mask(dest, "HO=ERROR:MAIN=DEBUG:HO=DEBUG");
|
||||||
UC_LOGF( UC_LL_DEBUG, MAIN, "Test MAIN DEBUG SHOULD SHOW\n" );
|
UC_LOGF( UC_LL_DEBUG, MAIN, "Test MAIN DEBUG SHOULD SHOW" );
|
||||||
|
|
||||||
uc_log_delete_destination(dest);
|
uc_log_delete_destination(dest);
|
||||||
|
|
||||||
|
|||||||
@@ -83,12 +83,90 @@ START_TEST (test_dbuf_take_fail)
|
|||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
|
||||||
|
START_TEST (test_dbuf_take_all)
|
||||||
|
DBuf buf;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = uc_dbuf_init(&buf, 10);
|
||||||
|
|
||||||
|
fail_if(rc != 0);
|
||||||
|
fail_if(uc_dbuf_buflen(&buf) != 10);
|
||||||
|
fail_if(uc_dbuf_remaining(&buf) != 10);
|
||||||
|
|
||||||
|
strcpy((char *)buf.end, "12345679");
|
||||||
|
uc_dbuf_added(&buf, 10);
|
||||||
|
fail_if(uc_dbuf_len(&buf) != 10);
|
||||||
|
fail_if(uc_dbuf_remaining(&buf) != 0);
|
||||||
|
|
||||||
|
rc = uc_dbuf_take(&buf, 10);
|
||||||
|
fail_if(rc != 0);
|
||||||
|
fail_if(uc_dbuf_len(&buf) != 0);
|
||||||
|
fail_if(uc_dbuf_remaining(&buf) != 10);
|
||||||
|
|
||||||
|
uc_dbuf_free(&buf);
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST (test_dbuf_add_ensure_take)
|
||||||
|
DBuf *buf;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
buf = malloc(sizeof *buf);
|
||||||
|
fail_if(buf == NULL);
|
||||||
|
|
||||||
|
|
||||||
|
rc = uc_dbuf_init(buf, 10);
|
||||||
|
|
||||||
|
fail_if(rc != 0);
|
||||||
|
fail_if(uc_dbuf_buflen(buf) != 10);
|
||||||
|
fail_if(uc_dbuf_remaining(buf) != 10);
|
||||||
|
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
rc = uc_dbuf_ensure(buf,10);
|
||||||
|
fail_if(rc != 0);
|
||||||
|
|
||||||
|
uc_dbuf_added(buf, 2);
|
||||||
|
fail_if(uc_dbuf_len(buf) != 2);
|
||||||
|
fail_if(uc_dbuf_remaining(buf) != 8);
|
||||||
|
|
||||||
|
uc_dbuf_added(buf, 8);
|
||||||
|
fail_if(uc_dbuf_len(buf) != 10);
|
||||||
|
fail_if(uc_dbuf_remaining(buf) != 0);
|
||||||
|
|
||||||
|
rc = uc_dbuf_take(buf, 5);
|
||||||
|
fail_if(rc != 0);
|
||||||
|
fail_if(uc_dbuf_len(buf) != 5);
|
||||||
|
|
||||||
|
rc = uc_dbuf_take(buf, 5);
|
||||||
|
fail_if(rc != 0);
|
||||||
|
fail_if(uc_dbuf_len(buf) != 0);
|
||||||
|
fail_if(uc_dbuf_remaining(buf) != 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = uc_dbuf_ensure(buf,90);
|
||||||
|
fail_if(rc != 0);
|
||||||
|
//ok, dbuf adds the ensured capacity to the existing buflen
|
||||||
|
//so it becomes 100, not 90 even though the buffer is already empty
|
||||||
|
fail_if(uc_dbuf_remaining(buf) != 100, "remaining %zu", (uc_dbuf_remaining(buf)));
|
||||||
|
fail_if(uc_dbuf_buflen(buf) != 100);
|
||||||
|
memset(buf->end, 0xDE, 90);
|
||||||
|
uc_dbuf_added(buf, 90);
|
||||||
|
fail_if(uc_dbuf_remaining(buf) != 10);
|
||||||
|
|
||||||
|
uc_dbuf_free(buf);
|
||||||
|
free(buf);
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
|
||||||
Suite *dbuf_suite(void)
|
Suite *dbuf_suite(void)
|
||||||
{
|
{
|
||||||
Suite *s = suite_create("dbuf");
|
Suite *s = suite_create("dbuf");
|
||||||
TCase *tc = tcase_create("dbuf tests");
|
TCase *tc = tcase_create("dbuf tests");
|
||||||
tcase_add_test(tc, test_dbuf);
|
tcase_add_test(tc, test_dbuf);
|
||||||
|
|
||||||
|
tcase_add_test(tc, test_dbuf_take_all);
|
||||||
|
tcase_add_test(tc, test_dbuf_add_ensure_take);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
tcase_add_test_raise_signal(tc, test_dbuf_take_fail, SIGABRT);
|
tcase_add_test_raise_signal(tc, test_dbuf_take_fail, SIGABRT);
|
||||||
#else
|
#else
|
||||||
|
|||||||
+13
-1
@@ -63,9 +63,20 @@ START_TEST (test_dstr_init)
|
|||||||
ck_assert_int_eq(rc, 0);
|
ck_assert_int_eq(rc, 0);
|
||||||
ck_assert_int_eq(str.len, 2);
|
ck_assert_int_eq(str.len, 2);
|
||||||
ck_assert_str_eq(uc_dstr_str(&str), "He");
|
ck_assert_str_eq(uc_dstr_str(&str), "He");
|
||||||
|
uc_dstr_destroy(&str);
|
||||||
|
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST (test_dstr_own)
|
||||||
|
struct DStr str;
|
||||||
|
|
||||||
|
uc_dstr_init_str(&str, "init");
|
||||||
|
uc_dstr_own(&str, strdup("Hello !"));
|
||||||
|
ck_assert_int_eq(str.len, 7);
|
||||||
|
ck_assert_str_eq(uc_dstr_str(&str), "Hello !");
|
||||||
|
|
||||||
|
uc_dstr_destroy(&str);
|
||||||
|
END_TEST
|
||||||
START_TEST (test_dstr_own_steal)
|
START_TEST (test_dstr_own_steal)
|
||||||
struct DStr str;
|
struct DStr str;
|
||||||
char *s;
|
char *s;
|
||||||
@@ -85,7 +96,7 @@ START_TEST (test_dstr_own_steal)
|
|||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
START_TEST (test_dstr_trim)
|
START_TEST (test_dstr_trim)
|
||||||
struct DStr str = UC_DSTR_STATIC_INIT;
|
struct DStr str = UC_DSTR_INITIALIZER;
|
||||||
|
|
||||||
uc_dstr_append_str(&str, " \t \nHello !\r\n");
|
uc_dstr_append_str(&str, " \t \nHello !\r\n");
|
||||||
uc_dstr_trim(&str);
|
uc_dstr_trim(&str);
|
||||||
@@ -192,6 +203,7 @@ Suite *dstr_suite(void)
|
|||||||
TCase *tc = tcase_create("dstr tests");
|
TCase *tc = tcase_create("dstr tests");
|
||||||
tcase_add_test(tc, test_dstr_basics);
|
tcase_add_test(tc, test_dstr_basics);
|
||||||
tcase_add_test(tc, test_dstr_init);
|
tcase_add_test(tc, test_dstr_init);
|
||||||
|
tcase_add_test(tc, test_dstr_own);
|
||||||
tcase_add_test(tc, test_dstr_own_steal);
|
tcase_add_test(tc, test_dstr_own_steal);
|
||||||
tcase_add_test(tc, test_dstr_trim);
|
tcase_add_test(tc, test_dstr_trim);
|
||||||
tcase_add_test(tc, test_dstr_replace);
|
tcase_add_test(tc, test_dstr_replace);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <check.h>
|
#include <check.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include "ucore/utils.h"
|
#include "ucore/utils.h"
|
||||||
#include "ucore/heapsort.h"
|
#include "ucore/heapsort.h"
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,127 @@
|
|||||||
|
#include <check.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "ucore/timers.h"
|
||||||
|
#include "ucore/iomux.h"
|
||||||
|
#include "ucore/clock.h"
|
||||||
|
|
||||||
|
|
||||||
|
static enum IOMUX_TYPE g_iomux_type = IOMUX_TYPE_DEFAULT;
|
||||||
|
|
||||||
|
void set_iomux_type_select(void)
|
||||||
|
{
|
||||||
|
g_iomux_type = IOMUX_TYPE_SELECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_iomux_type_epoll(void)
|
||||||
|
{
|
||||||
|
g_iomux_type = IOMUX_TYPE_EPOLL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void simple_rcb(struct IOMux *mux, struct IOMuxFD *fd, unsigned int event)
|
||||||
|
{
|
||||||
|
char buf[64];
|
||||||
|
ssize_t r;
|
||||||
|
|
||||||
|
/** we should get here 2 times. first for reading the string,
|
||||||
|
* then for reading that the pipe has closed */
|
||||||
|
|
||||||
|
ck_assert_int_le(fd->cookie_int, 2);
|
||||||
|
fd->cookie_int++;
|
||||||
|
|
||||||
|
r = read(fd->fd, buf, sizeof buf);
|
||||||
|
ck_assert(r >= 0);
|
||||||
|
|
||||||
|
if (r > 0) {
|
||||||
|
ck_assert_int_eq(r, 5);
|
||||||
|
ck_assert(strncmp(buf, "Hello", 5) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r == 0) {
|
||||||
|
int rc;
|
||||||
|
rc = iomux_unregister_fd(mux, fd);
|
||||||
|
ck_assert_int_eq(rc, 0);
|
||||||
|
close(fd->fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void simple_wcb(struct IOMux *mux, struct IOMuxFD *fd, unsigned int event)
|
||||||
|
{
|
||||||
|
ssize_t written;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
ck_assert_int_eq(fd->cookie_int, 0);
|
||||||
|
fd->cookie_int = 1;
|
||||||
|
|
||||||
|
written = write(fd->fd, "Hello", 5);
|
||||||
|
ck_assert_int_eq(written, 5);
|
||||||
|
|
||||||
|
rc = iomux_unregister_fd(mux, fd);
|
||||||
|
ck_assert_int_eq(rc, 0);
|
||||||
|
|
||||||
|
close(fd->fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
START_TEST (test_iomux_pipe_simple)
|
||||||
|
struct IOMux *mux;
|
||||||
|
struct IOMuxFD rfd;
|
||||||
|
struct IOMuxFD wfd;
|
||||||
|
/**
|
||||||
|
* Simple test that writes a small string to a pipe
|
||||||
|
* and reads it back. This assumes the small write/read
|
||||||
|
* can be done with just 1 write/read call.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pipefd[2];
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
mux = iomux_create(g_iomux_type);
|
||||||
|
|
||||||
|
rc = pipe(pipefd);
|
||||||
|
ck_assert_int_eq(rc, 0);
|
||||||
|
|
||||||
|
memset(&rfd, 0, sizeof rfd);
|
||||||
|
memset(&wfd, 0, sizeof wfd);
|
||||||
|
|
||||||
|
rfd.fd = pipefd[0];
|
||||||
|
rfd.what = MUX_EV_READ;
|
||||||
|
rfd.callback = simple_rcb;
|
||||||
|
|
||||||
|
wfd.fd = pipefd[1];
|
||||||
|
wfd.what = MUX_EV_WRITE;
|
||||||
|
wfd.callback = simple_wcb;
|
||||||
|
|
||||||
|
rc = iomux_register_fd(mux, &rfd);
|
||||||
|
ck_assert_int_eq(rc, 0);
|
||||||
|
|
||||||
|
rc = iomux_register_fd(mux, &wfd);
|
||||||
|
ck_assert_int_eq(rc, 0);
|
||||||
|
|
||||||
|
rc = iomux_run(mux);
|
||||||
|
ck_assert_int_eq(rc, 0);
|
||||||
|
|
||||||
|
iomux_delete(mux);
|
||||||
|
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
|
||||||
|
Suite *iomux_suite(void)
|
||||||
|
{
|
||||||
|
Suite *s = suite_create("iomux");
|
||||||
|
TCase *select_tc = tcase_create("iomux select tests");
|
||||||
|
TCase *epoll_tc = tcase_create("iomux epoll tests");
|
||||||
|
|
||||||
|
tcase_add_test(select_tc, test_iomux_pipe_simple);
|
||||||
|
tcase_add_test(epoll_tc, test_iomux_pipe_simple);
|
||||||
|
|
||||||
|
tcase_add_checked_fixture(select_tc, set_iomux_type_select, NULL);
|
||||||
|
|
||||||
|
tcase_add_checked_fixture(epoll_tc, set_iomux_type_epoll, NULL);
|
||||||
|
|
||||||
|
suite_add_tcase(s, select_tc);
|
||||||
|
suite_add_tcase(s, epoll_tc);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
+70
-70
@@ -53,15 +53,15 @@ START_TEST (test_logfile_location)
|
|||||||
uc_log_add_destination(dest);
|
uc_log_add_destination(dest);
|
||||||
uc_log_add_destination(dest); //adding this twice should do nothing
|
uc_log_add_destination(dest); //adding this twice should do nothing
|
||||||
|
|
||||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson 2\n");
|
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson 2");
|
||||||
UC_LOGF(UC_LL_INFO, 0, "Lorum ipson 3\n");
|
UC_LOGF(UC_LL_INFO, 0, "Lorum ipson 3");
|
||||||
UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson 4\n");
|
UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson 4");
|
||||||
UC_LOGF(UC_LL_ERROR, 0, "Lorum ipson 5\n");
|
UC_LOGF(UC_LL_ERROR, 0, "Lorum ipson 5");
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
|
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
||||||
fail_if(st.st_size != 380, "was %ld\n", (long)st.st_size);
|
fail_if(st.st_size != 380, "was %ld", (long)st.st_size);
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
START_TEST (test_logfile_delete_destination)
|
START_TEST (test_logfile_delete_destination)
|
||||||
@@ -87,28 +87,28 @@ START_TEST (test_logfile_delete_destination)
|
|||||||
uc_log_add_destination(dest);
|
uc_log_add_destination(dest);
|
||||||
uc_log_add_destination(dest); //adding this twice should do nothing
|
uc_log_add_destination(dest); //adding this twice should do nothing
|
||||||
|
|
||||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson 2\n");
|
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson 2");
|
||||||
UC_LOGF(UC_LL_INFO, 0, "Lorum ipson 3\n");
|
UC_LOGF(UC_LL_INFO, 0, "Lorum ipson 3");
|
||||||
UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson 4\n");
|
UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson 4");
|
||||||
UC_LOGF(UC_LL_ERROR, 0, "Lorum ipson 5\n");
|
UC_LOGF(UC_LL_ERROR, 0, "Lorum ipson 5");
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
|
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
||||||
fail_if(st.st_size != 380, "was %ld\n", (long)st.st_size);
|
fail_if(st.st_size != 380, "was %ld", (long)st.st_size);
|
||||||
|
|
||||||
uc_log_delete_destination(dest);
|
uc_log_delete_destination(dest);
|
||||||
|
|
||||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson 2\n");
|
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson 2");
|
||||||
UC_LOGF(UC_LL_INFO, 0, "Lorum ipson 3\n");
|
UC_LOGF(UC_LL_INFO, 0, "Lorum ipson 3");
|
||||||
UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson 4\n");
|
UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson 4");
|
||||||
UC_LOGF(UC_LL_ERROR, 0, "Lorum ipson 5\n");
|
UC_LOGF(UC_LL_ERROR, 0, "Lorum ipson 5");
|
||||||
|
|
||||||
//since we deleted destinatiion, no more logging should appear in the file
|
//since we deleted destinatiion, no more logging should appear in the file
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
|
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
||||||
fail_if(st.st_size != 380, "was %ld\n", (long)st.st_size);
|
fail_if(st.st_size != 380, "was %ld", (long)st.st_size);
|
||||||
|
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -134,12 +134,12 @@ START_TEST (test_logfile_no_location)
|
|||||||
fail_if(dest == NULL);
|
fail_if(dest == NULL);
|
||||||
uc_log_add_destination(dest);
|
uc_log_add_destination(dest);
|
||||||
|
|
||||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
|
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
||||||
fail_if(st.st_size != 52*2, "was %ld\n", (long)st.st_size);
|
fail_if(st.st_size != 52*2, "was %ld", (long)st.st_size);
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
START_TEST (test_logfile_loglevel_surpressed_dest)
|
START_TEST (test_logfile_loglevel_surpressed_dest)
|
||||||
@@ -169,9 +169,9 @@ START_TEST (test_logfile_loglevel_surpressed_dest)
|
|||||||
UC_LOGF(UC_LL_INFO, 1, "Lorum ipson %d", 1);
|
UC_LOGF(UC_LL_INFO, 1, "Lorum ipson %d", 1);
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
|
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
||||||
|
|
||||||
fail_if(st.st_size != 0, "was %ld\n", (long)st.st_size);
|
fail_if(st.st_size != 0, "was %ld", (long)st.st_size);
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
START_TEST (test_logfile_loglevel_surpressed_module)
|
START_TEST (test_logfile_loglevel_surpressed_module)
|
||||||
@@ -201,9 +201,9 @@ START_TEST (test_logfile_loglevel_surpressed_module)
|
|||||||
UC_LOGF(UC_LL_INFO, 0, "Lorum ipson %d", 100);
|
UC_LOGF(UC_LL_INFO, 0, "Lorum ipson %d", 100);
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
|
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
||||||
|
|
||||||
fail_if(st.st_size != 0, "was %ld\n", (long)st.st_size);
|
fail_if(st.st_size != 0, "was %ld", (long)st.st_size);
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
START_TEST (test_logfile_reopen_files)
|
START_TEST (test_logfile_reopen_files)
|
||||||
@@ -228,24 +228,24 @@ START_TEST (test_logfile_reopen_files)
|
|||||||
fail_if(dest == NULL);
|
fail_if(dest == NULL);
|
||||||
uc_log_add_destination(dest);
|
uc_log_add_destination(dest);
|
||||||
|
|
||||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
|
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
||||||
fail_if(st.st_size != 77*2, "was %ld\n", (long)st.st_size);
|
fail_if(st.st_size != 77*2, "was %ld", (long)st.st_size);
|
||||||
|
|
||||||
rc = remove(FILE_NAME);
|
rc = remove(FILE_NAME);
|
||||||
fail_if(rc != 0, "Remove failed %s\n", strerror(errno));
|
fail_if(rc != 0, "Remove failed %s", strerror(errno));
|
||||||
|
|
||||||
rc = uc_log_reopen_files();
|
rc = uc_log_reopen_files();
|
||||||
fail_if(rc != 0, "uc_log_reopen_files failed: %d\n", rc);
|
fail_if(rc != 0, "uc_log_reopen_files failed: %d", rc);
|
||||||
|
|
||||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "2. stat failed: %s\n", strerror(errno));
|
fail_if(rc != 0, "2. stat failed: %s", strerror(errno));
|
||||||
fail_if(st.st_size != 77, "was %ld\n", (long)st.st_size);//should only one line there now
|
fail_if(st.st_size != 77, "was %ld", (long)st.st_size);//should only one line there now
|
||||||
|
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -277,29 +277,29 @@ START_TEST (test_logfile_remove_dest)
|
|||||||
uc_log_add_destination(dest1);
|
uc_log_add_destination(dest1);
|
||||||
uc_log_add_destination(dest2);
|
uc_log_add_destination(dest2);
|
||||||
|
|
||||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
|
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
||||||
fail_if(st.st_size != 77*2, "was %ld\n", (long)st.st_size);
|
fail_if(st.st_size != 77*2, "was %ld", (long)st.st_size);
|
||||||
|
|
||||||
uc_log_remove_destination(dest1);
|
uc_log_remove_destination(dest1);
|
||||||
|
|
||||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1); //should not be logged now
|
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); //should not be logged now
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "2. stat failed: %s\n", strerror(errno));
|
fail_if(rc != 0, "2. stat failed: %s", strerror(errno));
|
||||||
fail_if(st.st_size != 77*2, "was %ld\n", (long)st.st_size);//should be same size
|
fail_if(st.st_size != 77*2, "was %ld", (long)st.st_size);//should be same size
|
||||||
|
|
||||||
//removing the last destination should be fine too
|
//removing the last destination should be fine too
|
||||||
uc_log_remove_destination(dest2);
|
uc_log_remove_destination(dest2);
|
||||||
|
|
||||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "2. stat failed: %s\n", strerror(errno));
|
fail_if(rc != 0, "2. stat failed: %s", strerror(errno));
|
||||||
fail_if(st.st_size != 77*2, "was %ld\n", (long)st.st_size);//should be same size
|
fail_if(st.st_size != 77*2, "was %ld", (long)st.st_size);//should be same size
|
||||||
|
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -326,9 +326,9 @@ START_TEST (test_logfile_full_filesystem)
|
|||||||
uc_log_add_destination(dest);
|
uc_log_add_destination(dest);
|
||||||
|
|
||||||
for (i = 0; i < 1024; i++) {
|
for (i = 0; i < 1024; i++) {
|
||||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||||
UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson %d\n", 1);
|
UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson %d", 1);
|
||||||
UC_LOGF(UC_LL_INFO, 0, "Lorum ipson %d\n", 1);
|
UC_LOGF(UC_LL_INFO, 0, "Lorum ipson %d", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
END_TEST
|
END_TEST
|
||||||
@@ -370,7 +370,7 @@ START_TEST (test_logfile_invalid_file_after_reopen)
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
uc_log_init(&mods);
|
uc_log_init(&mods);
|
||||||
printf("SUBDIR_FILE_NAME= " SUBDIR_FILE_NAME " \n");
|
printf("SUBDIR_FILE_NAME= " SUBDIR_FILE_NAME " ");
|
||||||
|
|
||||||
dest = uc_log_new_file(SUBDIR_FILE_NAME, UC_LL_DEBUG, 1);
|
dest = uc_log_new_file(SUBDIR_FILE_NAME, UC_LL_DEBUG, 1);
|
||||||
fail_if(dest == NULL);
|
fail_if(dest == NULL);
|
||||||
@@ -378,18 +378,18 @@ START_TEST (test_logfile_invalid_file_after_reopen)
|
|||||||
logging_rm_subdir();
|
logging_rm_subdir();
|
||||||
|
|
||||||
rc = access(SUBDIR_FILE_NAME, W_OK);
|
rc = access(SUBDIR_FILE_NAME, W_OK);
|
||||||
fail_if(rc == 0, "Test setup is wrong. Can still access" SUBDIR_FILE_NAME "\n");
|
fail_if(rc == 0, "Test setup is wrong. Can still access" SUBDIR_FILE_NAME "");
|
||||||
|
|
||||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||||
UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson %d\n", 1);
|
UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson %d", 1);
|
||||||
UC_LOGF(UC_LL_INFO, 0, "Lorum ipson %d\n", 1);
|
UC_LOGF(UC_LL_INFO, 0, "Lorum ipson %d", 1);
|
||||||
|
|
||||||
uc_log_reopen_files();
|
uc_log_reopen_files();
|
||||||
|
|
||||||
//this should not crash now.
|
//this should not crash now.
|
||||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||||
UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson %d\n", 1);
|
UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson %d", 1);
|
||||||
UC_LOGF(UC_LL_INFO, 0, "Lorum ipson %d\n", 1);
|
UC_LOGF(UC_LL_INFO, 0, "Lorum ipson %d", 1);
|
||||||
|
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -419,8 +419,8 @@ START_TEST (test_logfile_raw)
|
|||||||
UC_LOGFR(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
UC_LOGFR(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
|
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
||||||
fail_if(st.st_size != 14*2, "was %ld\n", (long)st.st_size);
|
fail_if(st.st_size != 14*2, "was %ld", (long)st.st_size);
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
START_TEST (test_logfile_dest_mask)
|
START_TEST (test_logfile_dest_mask)
|
||||||
@@ -454,19 +454,19 @@ START_TEST (test_logfile_dest_mask)
|
|||||||
uc_log_add_destination(dest);
|
uc_log_add_destination(dest);
|
||||||
|
|
||||||
UC_LOGFR(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
UC_LOGFR(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
||||||
UC_LOGFR(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
UC_LOGFR(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
|
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
||||||
fail_if(st.st_size != 0, "was %ld\n", (long)st.st_size);
|
fail_if(st.st_size != 0, "was %ld", (long)st.st_size);
|
||||||
|
|
||||||
uc_log_destination_set_mask(dest, "MOD1=DEBUG:mod2=Debug");
|
uc_log_destination_set_mask(dest, "MOD1=DEBUG:mod2=Debug");
|
||||||
UC_LOGFR(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
UC_LOGFR(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
||||||
UC_LOGFR(UC_LL_DEBUG, 1, "Lorum ipson %d\n", 1);
|
UC_LOGFR(UC_LL_DEBUG, 1, "Lorum ipson %d\n", 1);
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
|
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
||||||
fail_if(st.st_size != 14*2, "was %ld\n", (long)st.st_size);
|
fail_if(st.st_size != 14*2, "was %ld", (long)st.st_size);
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
START_TEST (test_loglevel_module_none)
|
START_TEST (test_loglevel_module_none)
|
||||||
@@ -494,8 +494,8 @@ START_TEST (test_loglevel_module_none)
|
|||||||
UC_LOGFR(UC_LL_ERROR, 0, "Lorum ipson %d\n", 1);
|
UC_LOGFR(UC_LL_ERROR, 0, "Lorum ipson %d\n", 1);
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
|
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
||||||
fail_if(st.st_size != 0, "was %ld\n", (long)st.st_size);
|
fail_if(st.st_size != 0, "was %ld", (long)st.st_size);
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
START_TEST (test_loglevel_dest_none)
|
START_TEST (test_loglevel_dest_none)
|
||||||
@@ -523,8 +523,8 @@ START_TEST (test_loglevel_dest_none)
|
|||||||
UC_LOGFR(UC_LL_WARNING, 0, "Lorum ipson %d\n", 1);
|
UC_LOGFR(UC_LL_WARNING, 0, "Lorum ipson %d\n", 1);
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
|
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
||||||
fail_if(st.st_size != 0, "was %ld\n", (long)st.st_size);
|
fail_if(st.st_size != 0, "was %ld", (long)st.st_size);
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+51
-1
@@ -221,6 +221,7 @@ START_TEST (test_mbuf_static)
|
|||||||
|
|
||||||
uint8_t data[1024];
|
uint8_t data[1024];
|
||||||
struct MBuf mbuf;
|
struct MBuf mbuf;
|
||||||
|
uint8_t *p;
|
||||||
|
|
||||||
uc_mbuf_init(&mbuf, data, 1000, 24, UC_MBUF_FL_STATIC);
|
uc_mbuf_init(&mbuf, data, 1000, 24, UC_MBUF_FL_STATIC);
|
||||||
|
|
||||||
@@ -234,6 +235,13 @@ START_TEST (test_mbuf_static)
|
|||||||
fail_if(mbuf.cookie != NULL);
|
fail_if(mbuf.cookie != NULL);
|
||||||
fail_if(mbuf.head != mbuf.tail);
|
fail_if(mbuf.head != mbuf.tail);
|
||||||
fail_if(mbuf.head != &data[24]);
|
fail_if(mbuf.head != &data[24]);
|
||||||
|
p = uc_mbuf_put(&mbuf, 1000);
|
||||||
|
fail_if(p == NULL);
|
||||||
|
memset(p, 0xcc, 1000);
|
||||||
|
fail_if(uc_mbuf_len(&mbuf) != 1000);
|
||||||
|
p = uc_mbuf_put(&mbuf, 1);
|
||||||
|
fail_if(p != NULL);
|
||||||
|
|
||||||
|
|
||||||
uc_mbuf_free(&mbuf);
|
uc_mbuf_free(&mbuf);
|
||||||
|
|
||||||
@@ -289,11 +297,52 @@ START_TEST (test_mbuf_extend_tailroom_wrong_type)
|
|||||||
|
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST (test_mbuf_queue)
|
||||||
|
struct MBuf *m1;
|
||||||
|
struct MBuf *m2;
|
||||||
|
struct MBuf *q;
|
||||||
|
uint8_t *data1;
|
||||||
|
UC_TAILQ_HEAD(head);
|
||||||
|
|
||||||
|
m1 = uc_mbuf_new_inline(10);
|
||||||
|
fail_if(m1 == NULL);
|
||||||
|
|
||||||
|
data1 = uc_mbuf_put(m1, 10);
|
||||||
|
fail_if(data1 == NULL);
|
||||||
|
|
||||||
|
strcpy((char*)data1, "123456789");
|
||||||
|
|
||||||
|
m2 = uc_mbuf_new_inline(10);
|
||||||
|
fail_if(m2 == NULL);
|
||||||
|
|
||||||
|
data1 = uc_mbuf_put(m2, 10);
|
||||||
|
fail_if(data1 == NULL);
|
||||||
|
|
||||||
|
strcpy((char*)data1, "987654321");
|
||||||
|
|
||||||
|
uc_mbuf_enqueue(m1, &head);
|
||||||
|
uc_mbuf_enqueue(m2, &head);
|
||||||
|
|
||||||
|
q = uc_mbuf_dequeue(&head);
|
||||||
|
fail_if(strcmp((char*)uc_mbuf_head(q), "123456789") != 0);
|
||||||
|
|
||||||
|
q = uc_mbuf_dequeue(&head);
|
||||||
|
fail_if(strcmp((char*)uc_mbuf_head(q), "987654321") != 0);
|
||||||
|
|
||||||
|
fail_if(!uc_tailq_empty(&head));
|
||||||
|
|
||||||
|
q = uc_mbuf_dequeue(&head);
|
||||||
|
fail_if(q != NULL);
|
||||||
|
|
||||||
|
uc_mbuf_free(m1);
|
||||||
|
uc_mbuf_free(m2);
|
||||||
|
|
||||||
|
END_TEST
|
||||||
|
|
||||||
Suite *mbuf_suite(void)
|
Suite *mbuf_suite(void)
|
||||||
{
|
{
|
||||||
Suite *s = suite_create("mbuf");
|
Suite *s = suite_create("mbuf");
|
||||||
TCase *tc = tcase_create("mbuf tests");
|
TCase *tc = tcase_create("mbuf tests");
|
||||||
tcase_add_test(tc, test_mbuf_new);
|
tcase_add_test(tc, test_mbuf_new);
|
||||||
tcase_add_test(tc, test_mbuf_new_inline);
|
tcase_add_test(tc, test_mbuf_new_inline);
|
||||||
tcase_add_test(tc, test_mbuf_new_headroom);
|
tcase_add_test(tc, test_mbuf_new_headroom);
|
||||||
@@ -308,6 +357,7 @@ Suite *mbuf_suite(void)
|
|||||||
tcase_add_test(tc, test_mbuf_static);
|
tcase_add_test(tc, test_mbuf_static);
|
||||||
tcase_add_test(tc, test_mbuf_extend_tailroom);
|
tcase_add_test(tc, test_mbuf_extend_tailroom);
|
||||||
tcase_add_test(tc, test_mbuf_extend_tailroom_wrong_type);
|
tcase_add_test(tc, test_mbuf_extend_tailroom_wrong_type);
|
||||||
|
tcase_add_test(tc, test_mbuf_queue);
|
||||||
|
|
||||||
suite_add_tcase(s, tc);
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
|
|||||||
+20
-4
@@ -32,6 +32,7 @@ extern Suite *dstr_suite(void);
|
|||||||
extern Suite *val_str_suite(void);
|
extern Suite *val_str_suite(void);
|
||||||
extern Suite *ticket_lock_suite(void);
|
extern Suite *ticket_lock_suite(void);
|
||||||
extern Suite *restart_counter_suite(void);
|
extern Suite *restart_counter_suite(void);
|
||||||
|
extern Suite *iomux_suite(void);
|
||||||
|
|
||||||
static suite_func suites[] = {
|
static suite_func suites[] = {
|
||||||
bitvec_suite,
|
bitvec_suite,
|
||||||
@@ -58,9 +59,19 @@ static suite_func suites[] = {
|
|||||||
dstr_suite,
|
dstr_suite,
|
||||||
val_str_suite,
|
val_str_suite,
|
||||||
ticket_lock_suite,
|
ticket_lock_suite,
|
||||||
restart_counter_suite
|
restart_counter_suite,
|
||||||
|
iomux_suite
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
usage(const char *progname)
|
||||||
|
{
|
||||||
|
printf("Usage: %s [-h] [-k testcase] [-x]\n", progname);
|
||||||
|
puts("\t-h This help");
|
||||||
|
puts("\t-k testcase Run the given testcase");
|
||||||
|
puts("\t-x Ouput results in XML to the file result.xml");
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@@ -68,7 +79,7 @@ main (int argc, char *argv[])
|
|||||||
int c;
|
int c;
|
||||||
const char *test_case = NULL;
|
const char *test_case = NULL;
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "xk:")) != -1) {
|
while ((c = getopt(argc, argv, "xk:h")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'x':
|
case 'x':
|
||||||
xml_output = 1;
|
xml_output = 1;
|
||||||
@@ -77,8 +88,11 @@ main (int argc, char *argv[])
|
|||||||
test_case = optarg;
|
test_case = optarg;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("Ignoring unknown option %c\n", c);
|
printf("Unknown option %c\n", c);
|
||||||
break;
|
/*fallthrough*/
|
||||||
|
case 'h':
|
||||||
|
usage(argv[0]);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,6 +105,8 @@ main (int argc, char *argv[])
|
|||||||
if (xml_output)
|
if (xml_output)
|
||||||
srunner_set_xml(sr, "result.xml");
|
srunner_set_xml(sr, "result.xml");
|
||||||
|
|
||||||
|
//set the environment variable CK_FORK=no which means don't fork().
|
||||||
|
//anything else means to fork()
|
||||||
srunner_set_fork_status(sr, CK_FORK_GETENV);
|
srunner_set_fork_status(sr, CK_FORK_GETENV);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -390,7 +390,7 @@ Suite *threadqueue_suite(void)
|
|||||||
tcase_add_test(tc1, test_thread_queue_clear);
|
tcase_add_test(tc1, test_thread_queue_clear);
|
||||||
|
|
||||||
//lets start with this:
|
//lets start with this:
|
||||||
tcase_set_timeout(tc1, 15);
|
tcase_set_timeout(tc1, 25);
|
||||||
|
|
||||||
suite_add_tcase(s, tc1);
|
suite_add_tcase(s, tc1);
|
||||||
|
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ void peer_add_addr(struct HBContext *ctx, const struct sockaddr_in *addr)
|
|||||||
int usec;
|
int usec;
|
||||||
|
|
||||||
if (peer != NULL) {
|
if (peer != NULL) {
|
||||||
UC_LOGF(UC_LL_INFO, LMAIN, "Ignoring adding existing peer %s:%u\n",
|
UC_LOGF(UC_LL_INFO, LMAIN, "Ignoring adding existing peer %s:%u",
|
||||||
inet_ntoa(addr->sin_addr), addr->sin_port);
|
inet_ntoa(addr->sin_addr), addr->sin_port);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -169,12 +169,12 @@ void peer_do_state(struct HBPeer *peer, enum PeerEvent event)
|
|||||||
{
|
{
|
||||||
if (peer->state == PeerUnknown || peer->state == PeerDead) {
|
if (peer->state == PeerUnknown || peer->state == PeerDead) {
|
||||||
if (event == PeerReceived) {
|
if (event == PeerReceived) {
|
||||||
UC_LOGF(UC_LL_INFO, LMAIN, "Peer is now alive\n");
|
UC_LOGF(UC_LL_INFO, LMAIN, "Peer is now alive");
|
||||||
peer->state = PeerAlive;
|
peer->state = PeerAlive;
|
||||||
}
|
}
|
||||||
} else if (peer->state == PeerAlive) {
|
} else if (peer->state == PeerAlive) {
|
||||||
if (event == PeerTimedout) {
|
if (event == PeerTimedout) {
|
||||||
UC_LOGF(UC_LL_INFO, LMAIN, "Peer is dead !\n");
|
UC_LOGF(UC_LL_INFO, LMAIN, "Peer is dead !");
|
||||||
peer->state = PeerDead;
|
peer->state = PeerDead;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -206,7 +206,7 @@ void hb_read(struct IOMux *mux, struct IOMuxFD *fd, unsigned int event)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UC_LOGF(UC_LL_INFO, LMAIN, "Message from %s:%u\n", inet_ntoa(peer_addr.sin_addr),
|
UC_LOGF(UC_LL_INFO, LMAIN, "Message from %s:%u", inet_ntoa(peer_addr.sin_addr),
|
||||||
ntohs(peer_addr.sin_port));
|
ntohs(peer_addr.sin_port));
|
||||||
|
|
||||||
if (rc < 4) {
|
if (rc < 4) {
|
||||||
@@ -216,13 +216,13 @@ void hb_read(struct IOMux *mux, struct IOMuxFD *fd, unsigned int event)
|
|||||||
|
|
||||||
magic = uc_unpack_32_be(buf);
|
magic = uc_unpack_32_be(buf);
|
||||||
if (magic != HB_MAGIX) {
|
if (magic != HB_MAGIX) {
|
||||||
UC_LOGF(UC_LL_WARNING, LMAIN, "Received unknown message, magic = 0x%X\n", magic);
|
UC_LOGF(UC_LL_WARNING, LMAIN, "Received unknown message, magic = 0x%X", magic);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
peer = hb_peer_find(ctx, &peer_addr);
|
peer = hb_peer_find(ctx, &peer_addr);
|
||||||
if (peer == NULL) {
|
if (peer == NULL) {
|
||||||
UC_LOGF(UC_LL_WARNING, LMAIN, "Found no peer\n");
|
UC_LOGF(UC_LL_WARNING, LMAIN, "Found no peer");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,13 +241,13 @@ void init_hb_context(struct HBContext *ctx, uint16_t local_port)
|
|||||||
|
|
||||||
sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
if (sock_fd == -1) {
|
if (sock_fd == -1) {
|
||||||
UC_LOGF(UC_LL_ERROR, LMAIN, "socket failed : %s\n", strerror(errno));
|
UC_LOGF(UC_LL_ERROR, LMAIN, "socket failed : %s", strerror(errno));
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bind(sock_fd, (struct sockaddr*)&addr, sizeof addr) != 0) {
|
if (bind(sock_fd, (struct sockaddr*)&addr, sizeof addr) != 0) {
|
||||||
UC_LOGF(UC_LL_ERROR, LMAIN, "Cannot bind socket to port %u : %s\n",
|
UC_LOGF(UC_LL_ERROR, LMAIN, "Cannot bind socket to port %u : %s",
|
||||||
local_port, strerror(errno));
|
local_port, strerror(errno));
|
||||||
close(sock_fd);
|
close(sock_fd);
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user