diff --git a/.gitignore b/.gitignore index bd5cecc..603593c 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ tags doc/ log_subdir/ coverage/ +install/ +libucore-* diff --git a/Doxyfile b/Doxyfile index fc825f1..df415e7 100644 --- a/Doxyfile +++ b/Doxyfile @@ -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 diff --git a/README b/README index 6ae1c57..396f3e9 100644 --- a/README +++ b/README @@ -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. + + diff --git a/SConstruct b/SConstruct index f0fc4bb..d52dec5 100644 --- a/SConstruct +++ b/SConstruct @@ -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') diff --git a/include/ucore/bitvec.h b/include/ucore/bitvec.h index a3e224b..bb5dfe1 100644 --- a/include/ucore/bitvec.h +++ b/include/ucore/bitvec.h @@ -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 diff --git a/include/ucore/clock.h b/include/ucore/clock.h index 7014c63..1f0ea52 100644 --- a/include/ucore/clock.h +++ b/include/ucore/clock.h @@ -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 } diff --git a/include/ucore/cmd/cmd.h b/include/ucore/cmd/cmd.h new file mode 100644 index 0000000..8c9880a --- /dev/null +++ b/include/ucore/cmd/cmd.h @@ -0,0 +1,48 @@ +#ifndef UC_CMD_H_ +#define UC_CMD_H_ + +#include + +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 +/ diff --git a/include/ucore/dstr.h b/include/ucore/dstr.h index 1ee79ee..c1295a6 100644 --- a/include/ucore/dstr.h +++ b/include/ucore/dstr.h @@ -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 diff --git a/include/ucore/hash.h b/include/ucore/hash.h index 750b446..3c185d8 100644 --- a/include/ucore/hash.h +++ b/include/ucore/hash.h @@ -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 diff --git a/include/ucore/htable.h b/include/ucore/htable.h index 46e4168..5d9fa2c 100644 --- a/include/ucore/htable.h +++ b/include/ucore/htable.h @@ -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); diff --git a/include/ucore/iomux.h b/include/ucore/iomux.h index 414ce21..efcc3a1 100644 --- a/include/ucore/iomux.h +++ b/include/ucore/iomux.h @@ -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 diff --git a/include/ucore/logging.h b/include/ucore/logging.h index 37234dd..21402f4 100644 --- a/include/ucore/logging.h +++ b/include/ucore/logging.h @@ -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__) diff --git a/include/ucore/mbuf.h b/include/ucore/mbuf.h index 27cc959..7939504 100644 --- a/include/ucore/mbuf.h +++ b/include/ucore/mbuf.h @@ -4,17 +4,6 @@ #include #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 diff --git a/include/ucore/pack.h b/include/ucore/pack.h index 6553b7e..7c02a41 100644 --- a/include/ucore/pack.h +++ b/include/ucore/pack.h @@ -2,18 +2,7 @@ #define UC_PACK_H_ #include - -#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 diff --git a/include/ucore/read_file.h b/include/ucore/read_file.h index e105b45..9d83a46 100644 --- a/include/ucore/read_file.h +++ b/include/ucore/read_file.h @@ -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); diff --git a/include/ucore/restart_counter.h b/include/ucore/restart_counter.h index 806251e..502931f 100644 --- a/include/ucore/restart_counter.h +++ b/include/ucore/restart_counter.h @@ -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); diff --git a/include/ucore/string.h b/include/ucore/string.h index f1269fb..ccdb53d 100644 --- a/include/ucore/string.h +++ b/include/ucore/string.h @@ -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 diff --git a/include/ucore/strvec.h b/include/ucore/strvec.h index f4be722..4bbe887 100644 --- a/include/ucore/strvec.h +++ b/include/ucore/strvec.h @@ -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 */ diff --git a/include/ucore/tailq.h b/include/ucore/tailq.h index 7ae9768..c002ed3 100644 --- a/include/ucore/tailq.h +++ b/include/ucore/tailq.h @@ -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 diff --git a/include/ucore/threadqueue.h b/include/ucore/threadqueue.h index eacf9ab..9fd60fd 100644 --- a/include/ucore/threadqueue.h +++ b/include/ucore/threadqueue.h @@ -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); /** diff --git a/include/ucore/ticket_lock.h b/include/ucore/ticket_lock.h index f68c0a2..c7beb5a 100644 --- a/include/ucore/ticket_lock.h +++ b/include/ucore/ticket_lock.h @@ -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 */ diff --git a/include/ucore/time.h b/include/ucore/time.h index 607bd44..e643f12 100644 --- a/include/ucore/time.h +++ b/include/ucore/time.h @@ -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; } diff --git a/include/ucore/timers.h b/include/ucore/timers.h index c202cb0..4385298 100644 --- a/include/ucore/timers.h +++ b/include/ucore/timers.h @@ -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 diff --git a/include/ucore/utils.h b/include/ucore/utils.h index 44511ff..614b6bc 100644 --- a/include/ucore/utils.h +++ b/include/ucore/utils.h @@ -2,7 +2,6 @@ #define UC_UTILS_H_ #include -#include //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 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 diff --git a/src/SConscript b/src/SConscript index 1367097..7d060a3 100644 --- a/src/SConscript +++ b/src/SConscript @@ -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])) diff --git a/src/bitvec.c b/src/bitvec.c index 8286d36..cd73536 100644 --- a/src/bitvec.c +++ b/src/bitvec.c @@ -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; diff --git a/src/clock.c b/src/clock.c index aeb0538..bfdbcb7 100644 --- a/src/clock.c +++ b/src/clock.c @@ -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; } diff --git a/src/cmd/cmd.c b/src/cmd/cmd.c new file mode 100644 index 0000000..9459958 --- /dev/null +++ b/src/cmd/cmd.c @@ -0,0 +1,54 @@ +#include + +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); + diff --git a/src/dstr.c b/src/dstr.c index 90e49bc..a5ae33f 100644 --- a/src/dstr.c +++ b/src/dstr.c @@ -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; diff --git a/src/heapsort.c b/src/heapsort.c index 45a56e5..8580a73 100644 --- a/src/heapsort.c +++ b/src/heapsort.c @@ -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; diff --git a/src/hex.c b/src/hex.c index 1b01ad9..24d2b1f 100644 --- a/src/hex.c +++ b/src/hex.c @@ -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; diff --git a/src/iomux_impl.c b/src/iomux_impl.c index 6f60744..a577b5b 100644 --- a/src/iomux_impl.c +++ b/src/iomux_impl.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include "ucore/clock.h" #include "ucore/backtrace.h" diff --git a/src/iomux_impl.h b/src/iomux_impl.h index ea51873..83dfeb5 100644 --- a/src/iomux_impl.h +++ b/src/iomux_impl.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); diff --git a/src/iomux_select.c b/src/iomux_select.c index f680d60..bdf0029 100644 --- a/src/iomux_select.c +++ b/src/iomux_select.c @@ -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; } diff --git a/src/logging.c b/src/logging.c index 567696a..fa716d7 100644 --- a/src/logging.c +++ b/src/logging.c @@ -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); } diff --git a/src/mbuf.c b/src/mbuf.c index b4ab023..4b729fb 100644 --- a/src/mbuf.c +++ b/src/mbuf.c @@ -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); +} diff --git a/src/mkdirp.c b/src/mkdirp.c new file mode 100644 index 0000000..93313e7 --- /dev/null +++ b/src/mkdirp.c @@ -0,0 +1,100 @@ +#include +#include +#include +#include +#include +#include + + +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; +} + diff --git a/src/restart_counter.c b/src/restart_counter.c index b785844..b70c1d7 100644 --- a/src/restart_counter.c +++ b/src/restart_counter.c @@ -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) { diff --git a/src/sdmhash.c b/src/sdmhash.c index da7d0fb..6fde471 100644 --- a/src/sdmhash.c +++ b/src/sdmhash.c @@ -1,3 +1,5 @@ +#include "ucore/hash.h" + unsigned long uc_sdbmhash(const unsigned char *str) { diff --git a/src/strlcpy.c b/src/strlcpy.c index 6f9682a..36c3e6b 100644 --- a/src/strlcpy.c +++ b/src/strlcpy.c @@ -1,4 +1,5 @@ #include +#include "ucore/string.h" size_t uc_strlcpy(char *restrict dst, const char *restrict src, size_t max) { diff --git a/src/supervisor.c b/src/supervisor.c index b5f41d8..5efa924 100644 --- a/src/supervisor.c +++ b/src/supervisor.c @@ -8,6 +8,7 @@ #include #include #include +#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"); diff --git a/src/threadqueue.c b/src/threadqueue.c index e7a13c1..95fe07e 100644 --- a/src/threadqueue.c +++ b/src/threadqueue.c @@ -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); diff --git a/src/ticket_lock.c b/src/ticket_lock.c index a5d5bfa..a58ab1f 100644 --- a/src/ticket_lock.c +++ b/src/ticket_lock.c @@ -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; diff --git a/test/SConscript b/test/SConscript index 30a17fa..2e42446 100644 --- a/test/SConscript +++ b/test/SConscript @@ -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, diff --git a/test/atomic.c b/test/atomic.c index 6232ae0..ecec137 100644 --- a/test/atomic.c +++ b/test/atomic.c @@ -1,3 +1,5 @@ +#include + #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; +} + diff --git a/test/logging.c b/test/logging.c index a083807..fbce752 100644 --- a/test/logging.c +++ b/test/logging.c @@ -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); diff --git a/test/test_dbuf.c b/test/test_dbuf.c index d0b6bc1..317f2ba 100644 --- a/test/test_dbuf.c +++ b/test/test_dbuf.c @@ -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 diff --git a/test/test_dstr.c b/test/test_dstr.c index ff9cc33..1c5e1a1 100644 --- a/test/test_dstr.c +++ b/test/test_dstr.c @@ -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); diff --git a/test/test_heapsort.c b/test/test_heapsort.c index 0f23e10..3668593 100644 --- a/test/test_heapsort.c +++ b/test/test_heapsort.c @@ -1,4 +1,5 @@ #include +#include #include "ucore/utils.h" #include "ucore/heapsort.h" diff --git a/test/test_iomux.c b/test/test_iomux.c new file mode 100644 index 0000000..ed4f10b --- /dev/null +++ b/test/test_iomux.c @@ -0,0 +1,127 @@ +#include +#include +#include +#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; +} + diff --git a/test/test_logging.c b/test/test_logging.c index 14a2ffc..d6a8a28 100644 --- a/test/test_logging.c +++ b/test/test_logging.c @@ -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 diff --git a/test/test_mbuf.c b/test/test_mbuf.c index 598779a..fc37e43 100644 --- a/test/test_mbuf.c +++ b/test/test_mbuf.c @@ -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); diff --git a/test/test_runner.c b/test/test_runner.c index 33b1ad4..f95502c 100644 --- a/test/test_runner.c +++ b/test/test_runner.c @@ -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); diff --git a/test/test_threadqueue.c b/test/test_threadqueue.c index b08792c..a8d5db0 100644 --- a/test/test_threadqueue.c +++ b/test/test_threadqueue.c @@ -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); diff --git a/test/udp_heartbeat.c b/test/udp_heartbeat.c index 66bb717..f313b07 100644 --- a/test/udp_heartbeat.c +++ b/test/udp_heartbeat.c @@ -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;