Merge branch 'dev'
This commit is contained in:
@@ -6,3 +6,5 @@ tags
|
||||
doc/
|
||||
log_subdir/
|
||||
coverage/
|
||||
install/
|
||||
libucore-*
|
||||
|
||||
@@ -298,7 +298,7 @@ SUBGROUPING = YES
|
||||
# @ingroup) instead of on a separate page (for HTML and Man pages) or
|
||||
# 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
|
||||
# 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:
|
||||
|
||||
* scons
|
||||
* scons 2.3.0 or later
|
||||
* check
|
||||
|
||||
Run scons --help to see the various options for building the library
|
||||
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_patch': 0 ,
|
||||
'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_major'],
|
||||
@@ -86,7 +89,7 @@ def InstallPerm(env, dest, files, perm):
|
||||
return obj
|
||||
|
||||
|
||||
env = Environment(tools = ['default', 'textfile'])
|
||||
env = Environment(tools = ['default', 'textfile', 'packaging'])
|
||||
|
||||
#allow shell environment to override compiler
|
||||
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(CPPDEFINES = ['_FILE_OFFSET_BITS=64'])
|
||||
env.Append(CPPPATH = ['#include'])
|
||||
env.Append(SHLIBVERSION = version_info['version_abi'])
|
||||
|
||||
if GetOption('force32bit'):
|
||||
env.Append(CFLAGS = ['-m32'])
|
||||
@@ -146,6 +150,18 @@ 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')
|
||||
|
||||
@@ -71,7 +71,7 @@ void uc_bv_set_all(struct UCBitVec *v);
|
||||
* int a[] = {0,1,1,1,0};
|
||||
* 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
|
||||
|
||||
@@ -26,7 +26,7 @@ struct UCoreClock {
|
||||
* Wrapper for getting the current time.
|
||||
* @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
|
||||
|
||||
@@ -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
|
||||
/
|
||||
+13
-6
@@ -8,16 +8,22 @@
|
||||
extern "C" {
|
||||
#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,
|
||||
* Normally, use uc_dstr_str() to retreive the managed string
|
||||
* instead of accessing ->str directly.
|
||||
* The .str member might not always be nul terminated, and should not be
|
||||
* accessed directly. Instead use uc_dstr_str() to retreive the managed string
|
||||
* which will always ensure the string is nul terminated
|
||||
*
|
||||
* Normally, let the DSTR manage the nul terminator as manually adding
|
||||
* a nul byte and potintially adding more data to the DStr would append
|
||||
* 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 {
|
||||
/** Length of the managed string.*/
|
||||
size_t len;
|
||||
@@ -27,10 +33,11 @@ struct DStr {
|
||||
char *str;
|
||||
};
|
||||
|
||||
#define UC_DSTR_STATIC_INIT {0, 0, NULL}
|
||||
#define UC_DSTR_INITIALIZER {0, 0, NULL}
|
||||
|
||||
/** Initialize a DStr.
|
||||
* 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);
|
||||
@@ -94,7 +101,7 @@ void uc_dstr_terminate(struct DStr *str);
|
||||
char *uc_dstr_str(struct DStr *str);
|
||||
|
||||
/** 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.
|
||||
*
|
||||
* @param len bytes to reseve
|
||||
|
||||
@@ -28,6 +28,8 @@ uc_pjwhash(const char *str,size_t len);
|
||||
uint32_t
|
||||
uc_sax_hash(void *key, size_t len);
|
||||
|
||||
unsigned long
|
||||
uc_sdbmhash(const unsigned char *str);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -73,7 +73,8 @@ static inline size_t uc_htable_bucket(const struct UHTable *table, size_t hash)
|
||||
* @param table table
|
||||
* @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);
|
||||
|
||||
|
||||
@@ -137,6 +137,13 @@ struct UCTimers *iomux_get_timers(struct IOMux *mux);
|
||||
* or indirectly by the UCTimers provieded in a timer callback handler.
|
||||
*/
|
||||
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
|
||||
}
|
||||
#endif
|
||||
|
||||
+25
-13
@@ -100,15 +100,18 @@ struct UCLogModule {
|
||||
int id;
|
||||
|
||||
/** A short name for the module.
|
||||
* (must point to static storage)
|
||||
* This will appear in log messages */
|
||||
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;
|
||||
/** The log level of this module. Only
|
||||
* log statements with a level >= the log_level
|
||||
* are actually logged, but the log_level of a destination
|
||||
* can restrict the logging further*/
|
||||
int log_level;
|
||||
enum UC_LOG_LEVEL log_level;
|
||||
};
|
||||
|
||||
/* 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
|
||||
* 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
|
||||
*
|
||||
@@ -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
|
||||
* 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.
|
||||
*
|
||||
@@ -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
|
||||
* 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.
|
||||
*
|
||||
@@ -213,7 +222,8 @@ void uc_log_remove_destination(struct UCLogDestination *dest);
|
||||
* @param dest destination for which to set the 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
|
||||
* 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 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.
|
||||
* 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.
|
||||
*/
|
||||
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, ...)
|
||||
__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
|
||||
#if defined(DEBUG) || defined(UC_DEBUG_ALWAYS)
|
||||
# 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, ...)\
|
||||
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
|
||||
# define UC_DEBUGF(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,
|
||||
* 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 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
|
||||
*/
|
||||
#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
|
||||
* data, not timestamp, log level etc.
|
||||
* data, not timestamp, log level, newline, etc.
|
||||
*/
|
||||
#define UC_LOGFR(lvl, mod, fmt, ...) \
|
||||
uc_logf(lvl, mod, 1, UC_SRC_LOCATION, fmt, ## __VA_ARGS__)
|
||||
|
||||
+26
-22
@@ -4,17 +4,6 @@
|
||||
#include <stddef.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
|
||||
* mbuf - A managed message/memory buffer.
|
||||
@@ -35,16 +24,17 @@
|
||||
@endverbatim
|
||||
*
|
||||
* 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 tail points one past the allocated space, there is no
|
||||
* tailroom (the buffer is full)
|
||||
*
|
||||
* 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)
|
||||
* pull - remove data from the beginning of the message.
|
||||
* pull - remove data from the beginning of the data
|
||||
* (move head to the right)
|
||||
* put - Add data to the buffer.
|
||||
* (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*/
|
||||
#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);
|
||||
|
||||
/** 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,
|
||||
* 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
|
||||
* whose memory is already allocated.
|
||||
*
|
||||
* The whole buffer must have len + headroom available data
|
||||
* whose memory is already allocated. * The whole buffer must have len + headroom available data
|
||||
*
|
||||
* @param mbuf to initialise
|
||||
* @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 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
|
||||
*/
|
||||
@@ -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
|
||||
* 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
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
#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
|
||||
|
||||
+1
-17
@@ -2,18 +2,7 @@
|
||||
#define UC_PACK_H_
|
||||
|
||||
#include <stdint.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
|
||||
#include "utils.h"
|
||||
|
||||
/** @file
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#undef UC_INLINE
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@ uc_read_file(const char *file_name, size_t *length, size_t max);
|
||||
* @see uc_read_file
|
||||
* This is similar but reads from a file descriptor,
|
||||
* of any type as long as it supports the read() call.
|
||||
*
|
||||
* uc_read_fd close() the fd in all cases before it returns
|
||||
*/
|
||||
char *
|
||||
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 flags one of UC_RC_FL_XX
|
||||
*/
|
||||
UCRCResult uc_restart_counter_init(
|
||||
struct UCRestartCounter *counter,
|
||||
UCRCResult uc_restart_counter_init(struct UCRestartCounter *counter,
|
||||
const char *filename,
|
||||
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
|
||||
* 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.
|
||||
@@ -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.
|
||||
* @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.
|
||||
* 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
|
||||
* @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
|
||||
* 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
|
||||
* unusable after this call
|
||||
* unusable after this call until it is initialized again.
|
||||
* (strv itself is not free'd)
|
||||
*
|
||||
* @param strv UCStrv to destroy
|
||||
*/
|
||||
|
||||
+2
-13
@@ -1,17 +1,8 @@
|
||||
#ifndef UC_TAILQ_H_
|
||||
#define UC_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
|
||||
#include "utils.h"
|
||||
|
||||
/**
|
||||
* Doubly Linked List.
|
||||
* 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),\
|
||||
(prv) = UC_TAILQ_CONTAINER(UC_TAILQ_NEXT(&(ptr)->member), typeof(*ptr), member))
|
||||
|
||||
#undef UC_INLINE
|
||||
|
||||
#endif
|
||||
|
||||
@@ -153,6 +153,7 @@ int uc_thread_queue_init(struct uc_threadqueue *queue, unsigned int max_elements
|
||||
* Adds a message to a 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
|
||||
* struct uc_threadmsg.
|
||||
* 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.
|
||||
*
|
||||
* @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".
|
||||
* @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.
|
||||
*/
|
||||
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.
|
||||
* @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);
|
||||
}
|
||||
@@ -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
|
||||
*/
|
||||
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
|
||||
* to become available
|
||||
* @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);
|
||||
}
|
||||
@@ -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
|
||||
* @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
|
||||
@@ -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.
|
||||
* @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
|
||||
* @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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
+12
-9
@@ -46,8 +46,9 @@ typedef void (*uc_timer_cb)(struct UCTimers *timers, struct UCTimer *timer);
|
||||
struct UCTimer {
|
||||
//Internal members
|
||||
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
|
||||
//to find the UCTimer from a RBNode (Or just cast it, it's the 1. member..)
|
||||
//the UCTimer it's a member of. We might get rid of that
|
||||
//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
|
||||
struct timeval timeout;
|
||||
@@ -73,7 +74,8 @@ struct UCTimers {
|
||||
RBTree timer_tree;
|
||||
struct UCoreClock *uclock;
|
||||
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.
|
||||
@@ -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);
|
||||
|
||||
/** Remove a timer.
|
||||
* Note, the timer memory must have been zeroed out or the timer must have been added at least once
|
||||
* before uc_timers_remove can be called on a UCTimer.
|
||||
* Note, the timer memory must have been zeroed out or the timer must have been
|
||||
* added at least once before uc_timers_remove can be called on a UCTimer.
|
||||
* uc_timers_remove does nothing if the timer has expired.
|
||||
*
|
||||
* @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)
|
||||
*
|
||||
* @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);
|
||||
|
||||
@@ -141,8 +144,8 @@ int uc_timer_running(const struct UCTimer *timer);
|
||||
* @param timers timer engine to run
|
||||
* @param now The curent time. The engine will fire all timers whose expiry time is
|
||||
* prior to this value.
|
||||
* @return the number of timers fired, or negative if an error occured(presently no errors
|
||||
* are possible and the return value is always >= 0
|
||||
* @return the number of timers fired, or negative if an error occured(presently
|
||||
* no errors are possible and the return value is always >= 0
|
||||
**/
|
||||
int uc_timers_run(struct UCTimers *timers);
|
||||
|
||||
@@ -152,5 +155,5 @@ int uc_timers_run(struct UCTimers *timers);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @{ (addtogroup) */
|
||||
/** @} (addtogroup) */
|
||||
#endif
|
||||
|
||||
+12
-1
@@ -2,7 +2,6 @@
|
||||
#define UC_UTILS_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
//Gnerate a compiler error if the compile time
|
||||
//constant expression fails
|
||||
@@ -74,6 +73,7 @@ const typeof( ((const type *)0)->member ) *__mptr = (ptr); \
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
//include <stdio.h> if using the TRACEF() macro
|
||||
#define TRACEF(fmt, ...)\
|
||||
do { \
|
||||
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))
|
||||
|
||||
|
||||
#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
|
||||
|
||||
|
||||
+5
-3
@@ -13,9 +13,11 @@ sources = ucore_env.Glob('*.c')
|
||||
#print 'sources:', sources[len(sources)-2]
|
||||
|
||||
#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
|
||||
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));
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
||||
+8
-8
@@ -7,12 +7,12 @@
|
||||
#define UNUSED
|
||||
#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);
|
||||
}
|
||||
|
||||
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_usec = 0;
|
||||
@@ -28,11 +28,11 @@ struct UCoreClock uc_time_clock = {
|
||||
.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 UCoreCachedClock *cached_clock;
|
||||
cached_clock = UC_CONTAINER_OF(uclock, struct UCoreCachedClock, clock),
|
||||
const struct UCoreCachedClock *cached_clock;
|
||||
cached_clock = UC_CONST_CONTAINER_OF(uclock, const struct UCoreCachedClock, clock),
|
||||
|
||||
*tv = cached_clock->cache;
|
||||
}
|
||||
@@ -52,10 +52,10 @@ void uc_cached_clock_update(struct UCoreCachedClock *uclock)
|
||||
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;
|
||||
cached_clock = UC_CONTAINER_OF(uclock, struct UCoreSettableClock, clock),
|
||||
const struct UCoreSettableClock *cached_clock;
|
||||
cached_clock = UC_CONST_CONTAINER_OF(uclock, const struct UCoreSettableClock, clock),
|
||||
|
||||
*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);
|
||||
|
||||
if (str->str) {
|
||||
free(str);
|
||||
free(str->str);
|
||||
}
|
||||
|
||||
str->len = len;
|
||||
|
||||
@@ -28,7 +28,10 @@ uc_hex_encode(const uint8_t *restrict in, size_t len, char *restrict out)
|
||||
}
|
||||
|
||||
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;
|
||||
char *outp = out;
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "ucore/clock.h"
|
||||
#include "ucore/backtrace.h"
|
||||
|
||||
@@ -43,6 +43,8 @@ struct IOMux {
|
||||
/* Used by mux implementations to hold their own data/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_epoll_init(struct IOMux *mux);
|
||||
|
||||
+42
-62
@@ -14,53 +14,26 @@ struct IOMuxSelect {
|
||||
fd_set master_read_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 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()
|
||||
};
|
||||
|
||||
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;
|
||||
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)
|
||||
static void iomux_select_recalc_max(struct IOMuxSelect *mux)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
size_t n;
|
||||
mux->max_fd = -1;
|
||||
for (i = 0; i < mux->num_descriptors; ) {
|
||||
if (mux->descriptors[i] == NULL) {
|
||||
iomux_select_remove(mux, i);
|
||||
//a deleted fd slot needs to be rechecked, no i++ here
|
||||
} else {
|
||||
|
||||
for (i = 0, n = 0; i < FD_SETSIZE && n < mux->num_descriptors; i++) {
|
||||
if (mux->descriptors[i] != NULL) {
|
||||
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;
|
||||
|
||||
if (fd->fd < 0 || fd->fd >= FD_SETSIZE) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (fd->what & MUX_EV_READ)
|
||||
FD_SET(fd->fd, &mux->master_read_set);
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
if (mux->num_descriptors == mux->alloc_descriptors) {
|
||||
if (iomux_select_grow(mux) != 0)
|
||||
return ENOMEM;
|
||||
rc = iomux_select_update_events(mux_, fd);
|
||||
if (rc != 0) {
|
||||
return ENFILE;
|
||||
}
|
||||
|
||||
mux->descriptors[mux->num_descriptors] = fd;
|
||||
mux->descriptors[fd->fd] = fd;
|
||||
mux->num_descriptors++;
|
||||
|
||||
iomux_select_update_events(mux_, 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;
|
||||
int rc = ENOENT;
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < mux->num_descriptors; i++) {
|
||||
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;
|
||||
iomux_select_update_events(mux_, fd);
|
||||
mux->descriptors[i] = NULL; //set the slot to NULL, the event loop needs to rebuild it.
|
||||
mux->deleted_cnt++;
|
||||
fd->what = what;
|
||||
rc = 0;
|
||||
break;
|
||||
if (fd->fd < 0 || fd->fd >= FD_SETSIZE) {
|
||||
return ENFILE;
|
||||
}
|
||||
|
||||
if (mux->descriptors[fd->fd] != NULL) {
|
||||
unsigned int what = fd->what; //make sure we don't alter 'what' as seen from the user
|
||||
|
||||
fd->what = 0;
|
||||
iomux_select_update_events(mux_, fd);
|
||||
mux->descriptors[fd->fd] = NULL;
|
||||
mux->recalc_max = 1;
|
||||
fd->what = what;
|
||||
|
||||
rc = 0;
|
||||
mux->num_descriptors--;
|
||||
}
|
||||
|
||||
return rc;
|
||||
@@ -136,9 +117,9 @@ static int iomux_select_run(struct IOMux *mux_, struct timeval *timeout)
|
||||
fd_set read_set;
|
||||
fd_set write_set;
|
||||
|
||||
if (mux->deleted_cnt) {
|
||||
iomux_select_rebuild(mux);
|
||||
mux->deleted_cnt = 0;
|
||||
if (mux->recalc_max) {
|
||||
iomux_select_recalc_max(mux);
|
||||
mux->recalc_max = 0;
|
||||
}
|
||||
|
||||
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
|
||||
return event_cnt;
|
||||
|
||||
for (i = 0; rc > 0 && i < mux->num_descriptors; i++) {
|
||||
unsigned int events = 0;
|
||||
for (i = 0; rc > 0 && i < FD_SETSIZE; i++) {
|
||||
int had_event = 0;
|
||||
|
||||
//deliver only one event at a time , to simplify application
|
||||
//programming
|
||||
@@ -171,7 +152,7 @@ static int iomux_select_run(struct IOMux *mux_, struct timeval *timeout)
|
||||
rc--;
|
||||
assert(mux->descriptors[i]->callback != NULL);
|
||||
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
|
||||
@@ -180,10 +161,11 @@ static int iomux_select_run(struct IOMux *mux_, struct timeval *timeout)
|
||||
rc--;
|
||||
assert(mux->descriptors[i]->callback != NULL);
|
||||
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;
|
||||
@@ -193,8 +175,6 @@ static void iomux_select_delete(struct IOMux *mux)
|
||||
{
|
||||
if (mux != NULL && mux->instance != NULL) {
|
||||
struct IOMuxSelect *mux_select = mux->instance;
|
||||
free(mux_select->descriptors);
|
||||
mux_select->descriptors = NULL;
|
||||
free(mux_select);
|
||||
mux->instance = NULL;
|
||||
}
|
||||
|
||||
+43
-38
@@ -30,18 +30,21 @@ enum UC_LOG_DESTINATION {
|
||||
#define UC_MAX_RENAME_CNT (128)
|
||||
|
||||
//used to realise per destination settings
|
||||
struct UCLogModule_setting {
|
||||
int log_level;
|
||||
struct UCLogModuleSetting {
|
||||
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 TailQ entry;
|
||||
enum UC_LOG_DESTINATION dest_type;
|
||||
//log level for this destination
|
||||
int log_level;
|
||||
enum UC_LOG_LEVEL log_level;
|
||||
//Whether to log the source file name and line number
|
||||
int log_location;
|
||||
struct UCLogModule_setting *module_settings;
|
||||
struct UCLogModuleSetting *module_settings;
|
||||
union {
|
||||
//for syslog openlog()
|
||||
struct {
|
||||
@@ -57,13 +60,15 @@ struct UCLogDestination {
|
||||
struct UCLogRotateSettings rotate;
|
||||
} file;
|
||||
} type;
|
||||
|
||||
uc_vlog_func log_func;
|
||||
};
|
||||
|
||||
/* Helper struct for arguments to our main logging function */
|
||||
struct UCLogArgs {
|
||||
struct UCLogDestination *dest;
|
||||
const struct UCLogModule *module;
|
||||
int log_level;
|
||||
enum UC_LOG_LEVEL log_level;
|
||||
const char *location;
|
||||
int raw;
|
||||
};
|
||||
@@ -87,6 +92,9 @@ static const struct UCLogModule g_unknown_module = {
|
||||
//this list an anything contained within it.
|
||||
static UC_TAILQ_HEAD(g_destinations);
|
||||
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
|
||||
static const char *const g_log_levels[] = {
|
||||
"UNKNOWN_0",
|
||||
@@ -168,7 +176,7 @@ static int uc_log_init_common(struct UCLogDestination *dest)
|
||||
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);
|
||||
|
||||
@@ -185,11 +193,15 @@ struct UCLogDestination *uc_log_new_stderr(int log_level, int log_location)
|
||||
dest->type.file.size = 0;
|
||||
dest->log_level = log_level;;
|
||||
dest->log_location = log_location;
|
||||
dest->log_func = uc_vlog_file;
|
||||
|
||||
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);
|
||||
char *id;
|
||||
@@ -217,11 +229,12 @@ struct UCLogDestination *uc_log_new_syslog(const char *ident, int facility, int
|
||||
dest->type.syslog.facility = facility;
|
||||
dest->log_level = log_level;;
|
||||
dest->log_location = log_location;
|
||||
dest->log_func = uc_vlog_syslog;
|
||||
|
||||
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);
|
||||
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->log_func = uc_vlog_file;
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
@@ -435,10 +450,12 @@ int uc_log_reopen_files(void)
|
||||
UC_TAILQ_FOREACH_CONTAINER(dest, entry, &g_destinations) {
|
||||
|
||||
if (dest->dest_type == UC_LDEST_FILE) {
|
||||
rc = uc_log_reopen_file(dest);
|
||||
if (rc == 0) {
|
||||
dest->type.file.size = 0;
|
||||
int r_rc;
|
||||
r_rc = uc_log_reopen_file(dest);
|
||||
if (r_rc != 0) {
|
||||
rc = r_rc;
|
||||
}
|
||||
dest->type.file.size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,22 +464,25 @@ int uc_log_reopen_files(void)
|
||||
return rc;
|
||||
}
|
||||
|
||||
void uc_log_init(struct UCLogModules *user_modules)
|
||||
void uc_log_init(const struct UCLogModules *user_modules)
|
||||
{
|
||||
g_modules = *user_modules;
|
||||
}
|
||||
|
||||
//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;
|
||||
char time_buf[48];
|
||||
struct tm t;
|
||||
time_t tstamp;
|
||||
int rc = 0;
|
||||
|
||||
if (dest->type.file.file == NULL)
|
||||
return;
|
||||
|
||||
tstamp = time(NULL);
|
||||
|
||||
localtime_r(&tstamp, &t);
|
||||
if (!args->raw) {
|
||||
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
|
||||
// though stderr could be redirected to a file
|
||||
}
|
||||
|
||||
uc_log_file_rotate_if_neeed(dest, tstamp);
|
||||
}
|
||||
|
||||
//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;
|
||||
|
||||
@@ -616,7 +638,6 @@ static void uc_log_file_rotate_size(struct UCLogDestination *dest)
|
||||
char new_filename[_POSIX_PATH_MAX * 2];
|
||||
char old_filename[_POSIX_PATH_MAX * 2];
|
||||
unsigned int i;
|
||||
int rc;
|
||||
|
||||
if (dest->type.file.file_name == NULL) {
|
||||
return;
|
||||
@@ -625,8 +646,8 @@ static void uc_log_file_rotate_size(struct UCLogDestination *dest)
|
||||
//rotate existing .num files
|
||||
i = dest->type.file.rotate.size_settings.num_files -1;
|
||||
while (i > 0) {
|
||||
snprintf(new_filename, sizeof new_filename, "%s.%d", dest->type.file.file_name, i);
|
||||
snprintf(old_filename, sizeof old_filename, "%s.%d", dest->type.file.file_name, i - 1);
|
||||
snprintf(new_filename, sizeof new_filename, "%s.%u", dest->type.file.file_name, i);
|
||||
snprintf(old_filename, sizeof old_filename, "%s.%u", dest->type.file.file_name, i - 1);
|
||||
rename(old_filename, new_filename);
|
||||
i--;
|
||||
}
|
||||
@@ -636,10 +657,8 @@ static void uc_log_file_rotate_size(struct UCLogDestination *dest)
|
||||
rename(dest->type.file.file_name, new_filename);
|
||||
|
||||
//re-open current file
|
||||
rc = uc_log_reopen_file(dest);
|
||||
if (rc == 0) {
|
||||
uc_log_reopen_file(dest);
|
||||
dest->type.file.size = 0;
|
||||
}
|
||||
|
||||
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, ...)
|
||||
{
|
||||
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) {
|
||||
const struct UCLogModule *log_module;
|
||||
va_list apc;
|
||||
int module_log_level;
|
||||
enum UC_LOG_LEVEL module_log_level;
|
||||
|
||||
|
||||
//destnation level
|
||||
@@ -705,25 +724,11 @@ void uc_logf(int log_level, int module, int 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
|
||||
va_copy(apc, ap);
|
||||
|
||||
switch (dest->dest_type) {
|
||||
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;
|
||||
}
|
||||
dest->log_func(&args, fmt, apc);
|
||||
|
||||
va_end(apc);
|
||||
}
|
||||
|
||||
+23
-1
@@ -40,7 +40,11 @@ uint8_t *uc_mbuf_pull(struct MBuf *mbuf, uint32_t size)
|
||||
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->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;
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
UCRCResult uc_restart_counter_init(
|
||||
struct UCRestartCounter *counter,
|
||||
UCRCResult uc_restart_counter_init(struct UCRestartCounter *counter,
|
||||
const char *filename,
|
||||
unsigned int flags)
|
||||
{
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#include "ucore/hash.h"
|
||||
|
||||
unsigned long
|
||||
uc_sdbmhash(const unsigned char *str)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <string.h>
|
||||
#include "ucore/string.h"
|
||||
|
||||
size_t uc_strlcpy(char *restrict dst, const char *restrict src, size_t max)
|
||||
{
|
||||
|
||||
+11
-5
@@ -8,6 +8,7 @@
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include "ucore/supervisor.h"
|
||||
|
||||
|
||||
#define CLEAN_EXIT 11
|
||||
@@ -65,18 +66,22 @@ again:
|
||||
}
|
||||
|
||||
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;
|
||||
} 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;
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -133,7 +138,8 @@ int uc_supervise(void)
|
||||
switch (cmd) {
|
||||
|
||||
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);
|
||||
wait(NULL);
|
||||
syslog(LOG_INFO, "Exiting");
|
||||
|
||||
+2
-2
@@ -270,7 +270,7 @@ unsigned int uc_thread_queue_length(struct uc_threadqueue *queue)
|
||||
unsigned int length;
|
||||
|
||||
if (queue == NULL ) {
|
||||
return -EINVAL;
|
||||
return EINVAL;
|
||||
}
|
||||
// get the length properly
|
||||
pthread_mutex_lock(&queue->mutex);
|
||||
@@ -285,7 +285,7 @@ int uc_thread_queue_clear(struct uc_threadqueue *queue,
|
||||
void *cookie)
|
||||
{
|
||||
if (queue == NULL) {
|
||||
return -EINVAL;
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
lock->queue_head = 0;
|
||||
|
||||
@@ -23,6 +23,9 @@ test_executable = 'test_runner'
|
||||
if test_xml:
|
||||
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)
|
||||
cmd = test_env.Command(target='test_phony' ,
|
||||
source = None,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ucore/atomic.h"
|
||||
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);
|
||||
dest = uc_log_new_stderr(UC_LL_INFO, 0);
|
||||
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\n", 3);
|
||||
UC_LOGF( UC_LL_INFO, CC, "Test cc info %d\n", 4);
|
||||
UC_LOGF( UC_LL_INFO, CC, "Test cc info %d\n", 5);
|
||||
UC_LOGF( UC_LL_WARNING, HO, "Test HO warning%d\n", 2);
|
||||
UC_LOGF( UC_LL_INFO, MAIN, "Test MAIN info \n" );
|
||||
UC_LOGF( UC_LL_WARNING, MAIN, "Test MAIN warning\n" );
|
||||
UC_LOGF( UC_LL_INFO, CC, "Test cc info %d", 2);
|
||||
UC_LOGF( UC_LL_INFO, CC, "Test cc info %d", 3);
|
||||
UC_LOGF( UC_LL_INFO, CC, "Test cc info %d", 4);
|
||||
UC_LOGF( UC_LL_INFO, CC, "Test cc info %d", 5);
|
||||
UC_LOGF( UC_LL_WARNING, HO, "Test HO warning%d", 2);
|
||||
UC_LOGF( UC_LL_INFO, MAIN, "Test MAIN info " );
|
||||
UC_LOGF( UC_LL_WARNING, MAIN, "Test MAIN warning" );
|
||||
|
||||
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_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_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_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);
|
||||
|
||||
|
||||
@@ -83,12 +83,90 @@ START_TEST (test_dbuf_take_fail)
|
||||
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 *s = suite_create("dbuf");
|
||||
TCase *tc = tcase_create("dbuf tests");
|
||||
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
|
||||
tcase_add_test_raise_signal(tc, test_dbuf_take_fail, SIGABRT);
|
||||
#else
|
||||
|
||||
+13
-1
@@ -63,9 +63,20 @@ START_TEST (test_dstr_init)
|
||||
ck_assert_int_eq(rc, 0);
|
||||
ck_assert_int_eq(str.len, 2);
|
||||
ck_assert_str_eq(uc_dstr_str(&str), "He");
|
||||
uc_dstr_destroy(&str);
|
||||
|
||||
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)
|
||||
struct DStr str;
|
||||
char *s;
|
||||
@@ -85,7 +96,7 @@ START_TEST (test_dstr_own_steal)
|
||||
END_TEST
|
||||
|
||||
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_trim(&str);
|
||||
@@ -192,6 +203,7 @@ Suite *dstr_suite(void)
|
||||
TCase *tc = tcase_create("dstr tests");
|
||||
tcase_add_test(tc, test_dstr_basics);
|
||||
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_trim);
|
||||
tcase_add_test(tc, test_dstr_replace);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <check.h>
|
||||
#include <stdio.h>
|
||||
#include "ucore/utils.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); //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 2\n");
|
||||
UC_LOGF(UC_LL_INFO, 0, "Lorum ipson 3\n");
|
||||
UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson 4\n");
|
||||
UC_LOGF(UC_LL_ERROR, 0, "Lorum ipson 5\n");
|
||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson 2");
|
||||
UC_LOGF(UC_LL_INFO, 0, "Lorum ipson 3");
|
||||
UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson 4");
|
||||
UC_LOGF(UC_LL_ERROR, 0, "Lorum ipson 5");
|
||||
|
||||
rc = stat(FILE_NAME, &st);
|
||||
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
|
||||
fail_if(st.st_size != 380, "was %ld\n", (long)st.st_size);
|
||||
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
||||
fail_if(st.st_size != 380, "was %ld", (long)st.st_size);
|
||||
END_TEST
|
||||
|
||||
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); //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 2\n");
|
||||
UC_LOGF(UC_LL_INFO, 0, "Lorum ipson 3\n");
|
||||
UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson 4\n");
|
||||
UC_LOGF(UC_LL_ERROR, 0, "Lorum ipson 5\n");
|
||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson 2");
|
||||
UC_LOGF(UC_LL_INFO, 0, "Lorum ipson 3");
|
||||
UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson 4");
|
||||
UC_LOGF(UC_LL_ERROR, 0, "Lorum ipson 5");
|
||||
|
||||
rc = stat(FILE_NAME, &st);
|
||||
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
|
||||
fail_if(st.st_size != 380, "was %ld\n", (long)st.st_size);
|
||||
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
||||
fail_if(st.st_size != 380, "was %ld", (long)st.st_size);
|
||||
|
||||
uc_log_delete_destination(dest);
|
||||
|
||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson 2\n");
|
||||
UC_LOGF(UC_LL_INFO, 0, "Lorum ipson 3\n");
|
||||
UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson 4\n");
|
||||
UC_LOGF(UC_LL_ERROR, 0, "Lorum ipson 5\n");
|
||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson 2");
|
||||
UC_LOGF(UC_LL_INFO, 0, "Lorum ipson 3");
|
||||
UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson 4");
|
||||
UC_LOGF(UC_LL_ERROR, 0, "Lorum ipson 5");
|
||||
|
||||
//since we deleted destinatiion, no more logging should appear in the file
|
||||
rc = stat(FILE_NAME, &st);
|
||||
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
|
||||
fail_if(st.st_size != 380, "was %ld\n", (long)st.st_size);
|
||||
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
||||
fail_if(st.st_size != 380, "was %ld", (long)st.st_size);
|
||||
|
||||
END_TEST
|
||||
|
||||
@@ -134,12 +134,12 @@ START_TEST (test_logfile_no_location)
|
||||
fail_if(dest == NULL);
|
||||
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\n", 1);
|
||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||
|
||||
rc = stat(FILE_NAME, &st);
|
||||
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
|
||||
fail_if(st.st_size != 52*2, "was %ld\n", (long)st.st_size);
|
||||
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
||||
fail_if(st.st_size != 52*2, "was %ld", (long)st.st_size);
|
||||
END_TEST
|
||||
|
||||
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);
|
||||
|
||||
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
|
||||
|
||||
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);
|
||||
|
||||
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
|
||||
|
||||
START_TEST (test_logfile_reopen_files)
|
||||
@@ -228,24 +228,24 @@ START_TEST (test_logfile_reopen_files)
|
||||
fail_if(dest == NULL);
|
||||
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\n", 1);
|
||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||
|
||||
rc = stat(FILE_NAME, &st);
|
||||
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
|
||||
fail_if(st.st_size != 77*2, "was %ld\n", (long)st.st_size);
|
||||
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
||||
fail_if(st.st_size != 77*2, "was %ld", (long)st.st_size);
|
||||
|
||||
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();
|
||||
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);
|
||||
fail_if(rc != 0, "2. stat failed: %s\n", strerror(errno));
|
||||
fail_if(st.st_size != 77, "was %ld\n", (long)st.st_size);//should only one line there now
|
||||
fail_if(rc != 0, "2. stat failed: %s", strerror(errno));
|
||||
fail_if(st.st_size != 77, "was %ld", (long)st.st_size);//should only one line there now
|
||||
|
||||
END_TEST
|
||||
|
||||
@@ -277,29 +277,29 @@ START_TEST (test_logfile_remove_dest)
|
||||
uc_log_add_destination(dest1);
|
||||
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\n", 1);
|
||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||
|
||||
rc = stat(FILE_NAME, &st);
|
||||
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
|
||||
fail_if(st.st_size != 77*2, "was %ld\n", (long)st.st_size);
|
||||
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
||||
fail_if(st.st_size != 77*2, "was %ld", (long)st.st_size);
|
||||
|
||||
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);
|
||||
fail_if(rc != 0, "2. stat failed: %s\n", strerror(errno));
|
||||
fail_if(st.st_size != 77*2, "was %ld\n", (long)st.st_size);//should be same size
|
||||
fail_if(rc != 0, "2. stat failed: %s", strerror(errno));
|
||||
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
|
||||
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);
|
||||
fail_if(rc != 0, "2. stat failed: %s\n", strerror(errno));
|
||||
fail_if(st.st_size != 77*2, "was %ld\n", (long)st.st_size);//should be same size
|
||||
fail_if(rc != 0, "2. stat failed: %s", strerror(errno));
|
||||
fail_if(st.st_size != 77*2, "was %ld", (long)st.st_size);//should be same size
|
||||
|
||||
END_TEST
|
||||
|
||||
@@ -326,9 +326,9 @@ START_TEST (test_logfile_full_filesystem)
|
||||
uc_log_add_destination(dest);
|
||||
|
||||
for (i = 0; i < 1024; i++) {
|
||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
||||
UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson %d\n", 1);
|
||||
UC_LOGF(UC_LL_INFO, 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", 1);
|
||||
UC_LOGF(UC_LL_INFO, 0, "Lorum ipson %d", 1);
|
||||
}
|
||||
|
||||
END_TEST
|
||||
@@ -370,7 +370,7 @@ START_TEST (test_logfile_invalid_file_after_reopen)
|
||||
int rc;
|
||||
|
||||
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);
|
||||
fail_if(dest == NULL);
|
||||
@@ -378,18 +378,18 @@ START_TEST (test_logfile_invalid_file_after_reopen)
|
||||
logging_rm_subdir();
|
||||
|
||||
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_WARNING, 0, "Lorum ipson %d\n", 1);
|
||||
UC_LOGF(UC_LL_INFO, 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", 1);
|
||||
UC_LOGF(UC_LL_INFO, 0, "Lorum ipson %d", 1);
|
||||
|
||||
uc_log_reopen_files();
|
||||
|
||||
//this should not crash now.
|
||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
||||
UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson %d\n", 1);
|
||||
UC_LOGF(UC_LL_INFO, 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", 1);
|
||||
UC_LOGF(UC_LL_INFO, 0, "Lorum ipson %d", 1);
|
||||
|
||||
END_TEST
|
||||
|
||||
@@ -419,8 +419,8 @@ START_TEST (test_logfile_raw)
|
||||
UC_LOGFR(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
||||
|
||||
rc = stat(FILE_NAME, &st);
|
||||
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
|
||||
fail_if(st.st_size != 14*2, "was %ld\n", (long)st.st_size);
|
||||
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
||||
fail_if(st.st_size != 14*2, "was %ld", (long)st.st_size);
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_logfile_dest_mask)
|
||||
@@ -454,19 +454,19 @@ START_TEST (test_logfile_dest_mask)
|
||||
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", 1);
|
||||
|
||||
rc = stat(FILE_NAME, &st);
|
||||
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
|
||||
fail_if(st.st_size != 0, "was %ld\n", (long)st.st_size);
|
||||
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
||||
fail_if(st.st_size != 0, "was %ld", (long)st.st_size);
|
||||
|
||||
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, 1, "Lorum ipson %d\n", 1);
|
||||
|
||||
rc = stat(FILE_NAME, &st);
|
||||
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
|
||||
fail_if(st.st_size != 14*2, "was %ld\n", (long)st.st_size);
|
||||
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
||||
fail_if(st.st_size != 14*2, "was %ld", (long)st.st_size);
|
||||
END_TEST
|
||||
|
||||
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);
|
||||
|
||||
rc = stat(FILE_NAME, &st);
|
||||
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
|
||||
fail_if(st.st_size != 0, "was %ld\n", (long)st.st_size);
|
||||
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
||||
fail_if(st.st_size != 0, "was %ld", (long)st.st_size);
|
||||
END_TEST
|
||||
|
||||
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);
|
||||
|
||||
rc = stat(FILE_NAME, &st);
|
||||
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
|
||||
fail_if(st.st_size != 0, "was %ld\n", (long)st.st_size);
|
||||
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
||||
fail_if(st.st_size != 0, "was %ld", (long)st.st_size);
|
||||
END_TEST
|
||||
|
||||
|
||||
|
||||
@@ -221,6 +221,7 @@ START_TEST (test_mbuf_static)
|
||||
|
||||
uint8_t data[1024];
|
||||
struct MBuf mbuf;
|
||||
uint8_t *p;
|
||||
|
||||
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.head != mbuf.tail);
|
||||
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);
|
||||
|
||||
@@ -289,6 +297,47 @@ START_TEST (test_mbuf_extend_tailroom_wrong_type)
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -308,6 +357,7 @@ Suite *mbuf_suite(void)
|
||||
tcase_add_test(tc, test_mbuf_static);
|
||||
tcase_add_test(tc, test_mbuf_extend_tailroom);
|
||||
tcase_add_test(tc, test_mbuf_extend_tailroom_wrong_type);
|
||||
tcase_add_test(tc, test_mbuf_queue);
|
||||
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
|
||||
+20
-4
@@ -32,6 +32,7 @@ extern Suite *dstr_suite(void);
|
||||
extern Suite *val_str_suite(void);
|
||||
extern Suite *ticket_lock_suite(void);
|
||||
extern Suite *restart_counter_suite(void);
|
||||
extern Suite *iomux_suite(void);
|
||||
|
||||
static suite_func suites[] = {
|
||||
bitvec_suite,
|
||||
@@ -58,9 +59,19 @@ static suite_func suites[] = {
|
||||
dstr_suite,
|
||||
val_str_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
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@@ -68,7 +79,7 @@ main (int argc, char *argv[])
|
||||
int c;
|
||||
const char *test_case = NULL;
|
||||
|
||||
while ((c = getopt(argc, argv, "xk:")) != -1) {
|
||||
while ((c = getopt(argc, argv, "xk:h")) != -1) {
|
||||
switch (c) {
|
||||
case 'x':
|
||||
xml_output = 1;
|
||||
@@ -77,8 +88,11 @@ main (int argc, char *argv[])
|
||||
test_case = optarg;
|
||||
break;
|
||||
default:
|
||||
printf("Ignoring unknown option %c\n", c);
|
||||
break;
|
||||
printf("Unknown option %c\n", c);
|
||||
/*fallthrough*/
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +105,8 @@ main (int argc, char *argv[])
|
||||
if (xml_output)
|
||||
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);
|
||||
|
||||
|
||||
|
||||
@@ -390,7 +390,7 @@ Suite *threadqueue_suite(void)
|
||||
tcase_add_test(tc1, test_thread_queue_clear);
|
||||
|
||||
//lets start with this:
|
||||
tcase_set_timeout(tc1, 15);
|
||||
tcase_set_timeout(tc1, 25);
|
||||
|
||||
suite_add_tcase(s, tc1);
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ void peer_add_addr(struct HBContext *ctx, const struct sockaddr_in *addr)
|
||||
int usec;
|
||||
|
||||
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);
|
||||
return;
|
||||
}
|
||||
@@ -169,12 +169,12 @@ void peer_do_state(struct HBPeer *peer, enum PeerEvent event)
|
||||
{
|
||||
if (peer->state == PeerUnknown || peer->state == PeerDead) {
|
||||
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;
|
||||
}
|
||||
} else if (peer->state == PeerAlive) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -206,7 +206,7 @@ void hb_read(struct IOMux *mux, struct IOMuxFD *fd, unsigned int event)
|
||||
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));
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
peer = hb_peer_find(ctx, &peer_addr);
|
||||
if (peer == NULL) {
|
||||
UC_LOGF(UC_LL_WARNING, LMAIN, "Found no peer\n");
|
||||
UC_LOGF(UC_LL_WARNING, LMAIN, "Found no peer");
|
||||
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);
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
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));
|
||||
close(sock_fd);
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user