Merge branch 'dev'

This commit is contained in:
Nils O. Selåsdal
2015-05-11 23:41:59 +02:00
55 changed files with 937 additions and 339 deletions
+2
View File
@@ -6,3 +6,5 @@ tags
doc/
log_subdir/
coverage/
install/
libucore-*
+1 -1
View File
@@ -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
+5 -1
View File
@@ -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
View File
@@ -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')
+1 -1
View File
@@ -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
+4 -4
View File
@@ -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
@@ -82,7 +82,7 @@ extern struct UCoreClock uc_time_clock;
*
*/
void uc_cached_clock_init(struct UCoreCachedClock *uclock,
struct UCoreClock *real_clock);
struct UCoreClock *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
**/
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
@@ -114,7 +114,7 @@ void uc_settable_clock_set_tv(struct UCoreSettableClock *uclock,
* @param usecs microseconds portion of the clock to set.
**/
void uc_settable_clock_set(struct UCoreSettableClock *uclock,
time_t secs, suseconds_t usecs);
time_t secs, suseconds_t usecs);
#ifdef __cplusplus
}
+48
View File
@@ -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
View File
@@ -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
* 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
+2
View File
@@ -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
+2 -1
View File
@@ -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);
+7
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+2
View File
@@ -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);
+1 -2
View File
@@ -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);
+9 -3
View File
@@ -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
+2 -1
View File
@@ -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
View File
@@ -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
+22 -8
View File
@@ -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);
/**
+3 -1
View File
@@ -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
*/
+3 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
+54
View File
@@ -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
View File
@@ -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;
+2 -2
View File
@@ -3,7 +3,7 @@
static void
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;
@@ -27,7 +27,7 @@ uc_sift(unsigned char *base, size_t start, size_t count, size_t width,
void
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 end;
+4 -1
View File
@@ -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
View File
@@ -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"
+2
View File
@@ -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);
+43 -63
View File
@@ -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;
}
+44 -39
View File
@@ -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) {
dest->type.file.size = 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
View File
@@ -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
View File
@@ -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;
}
+1 -2
View File
@@ -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)
{
+2
View File
@@ -1,3 +1,5 @@
#include "ucore/hash.h"
unsigned long
uc_sdbmhash(const unsigned char *str)
{
+1
View File
@@ -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
View File
@@ -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");
+4 -4
View File
@@ -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);
@@ -281,11 +281,11 @@ unsigned int uc_thread_queue_length(struct uc_threadqueue *queue)
}
int uc_thread_queue_clear(struct uc_threadqueue *queue,
uc_thread_queue_walk_func free_func,
void *cookie)
uc_thread_queue_walk_func free_func,
void *cookie)
{
if (queue == NULL) {
return -EINVAL;
return EINVAL;
}
pthread_mutex_lock(&queue->mutex);
+3 -1
View File
@@ -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;
+3
View File
@@ -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,
+19
View File
@@ -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
View File
@@ -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);
+78
View File
@@ -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
View File
@@ -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
View File
@@ -1,4 +1,5 @@
#include <check.h>
#include <stdio.h>
#include "ucore/utils.h"
#include "ucore/heapsort.h"
+127
View File
@@ -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
View File
@@ -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
+51 -1
View File
@@ -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,11 +297,52 @@ 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)
{
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_inline);
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_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
View File
@@ -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);
+1 -1
View File
@@ -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);
+8 -8
View File
@@ -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;