From e1834c22b196e4fff8c522b8bf43b316d0aea98c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Sun, 23 Jun 2013 23:04:23 +0200 Subject: [PATCH 01/12] Dop inline on uc_ll_2_str to avoid clang warning --- src/logging.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/logging.c b/src/logging.c index cdf086a..85146e8 100644 --- a/src/logging.c +++ b/src/logging.c @@ -79,7 +79,7 @@ static const char *const g_log_levels[] = { "NONE" }; -inline const char *uc_ll_2_str(enum UC_LOG_LEVEL l) +const char *uc_ll_2_str(enum UC_LOG_LEVEL l) { if (l < ARRAY_SIZE(g_log_levels)) { return g_log_levels[l]; From 9e919c1cde77f017ee5759c2d225bf2ee046f80d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Fri, 13 Sep 2013 21:42:32 +0200 Subject: [PATCH 02/12] Add mbuf documentation. have mbuf_free handle NULL pointer --- include/ucore/mbuf.h | 120 +++++++++++++++++++++++++++++++++++++++++-- src/mbuf.c | 12 +++-- 2 files changed, 124 insertions(+), 8 deletions(-) diff --git a/include/ucore/mbuf.h b/include/ucore/mbuf.h index 406f951..723d575 100644 --- a/include/ucore/mbuf.h +++ b/include/ucore/mbuf.h @@ -17,57 +17,171 @@ enum UC_MBUF_FLAGS { }; struct MBuf { + /** next pointer, user can use this for a linked list*/ struct MBuf *next; + /** Pointers the user can use to remember spots in + * the data. (these must either be NULL pointers or point into + * something in the buffer*/ uint8_t *p1; uint8_t *p2; uint8_t *p3; uint8_t *p4; + /**Arbitary pointer user can associate with the mbuf*/ void *cookie; + uint32_t flags; + /** Total no of bytes from bufstart*/ uint32_t allocated; + /** Start of the buffer*/ uint8_t *bufstart; + /** Start of the data in the buffer*/ uint8_t *head; + /** End of the buffer (one byte past the data) */ uint8_t *tail; + /** Internal data, if we allocate it inline */ uint8_t inline_data[0]; }; -/* Conventions: +/** + * Concept: + * <--------- allocated -----------> + * <--- len --> + * +--------------------------------+ + * |Headroom| Data |Tailroom | + * +--------------------------------+ + * ^ ^ ^ + * | | | + * | | tail + * | head + * bufstart + * + * Initially when empty, head == tail, and the length is 0. + * Data is added to the 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) + * (move head to the left) * pull - remove data from the beginning of the message. + * (move head to the right) * put - Add data to the buffer. + * (move tail to the right) + */ + +/** Allocate an mbuf with a length and headroom, + * the buffer will have the flag UC_MBUF_FL_MALLOC + * The total length of the buffer will be length+headroom + * + * @param len the initial length of the mbuf + * @param the initial headroom of the mbuf + * @return NULL if the allocation fails */ struct MBuf *uc_mbuf_new_hr(uint32_t len, uint32_t headroom); + +/** As uc_mbuf_new_hr, but without any headroom*/ #define uc_mbuf_new(len) uc_mbuf_new_hr((len), 0) + +/** Allocate an mbuf with a length and headroom, + * the buffer will have the flag UC_MBUF_FL_MALLOC_INLINE + * The total length of the buffer will be length+headroom + * + * @param len the initial length of the mbuf + * @param the initial headroom of the mbuf + * @return NULL if the allocation fails + */ 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)*/ void uc_mbuf_free(struct MBuf *mbuf); + +/** Create a new mbuf, with a copy of the data from the given + * mbuf. The new mbuf will have the same headroom as the old one. + * + * @param mbuf mbuf to copy + */ 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 + * + * @param mbuf to initialise + * @param buf start of the buffer + * @param len length of the buffer (not including the headroom) + * @param headroom the headroom in the buffer + * @param flags The appropriate UC_MBUF_FLAGS + */ void uc_mbuf_init(struct MBuf *mbuf, uint8_t *buf, uint32_t len, uint32_t headroom, uint32_t flags); -void uc_mbuf_zero(struct MBuf *mbuf); -void uc_mbuf_reset(struct MBuf *mbuf); +/** Zero out all the data in this mbuf, including the headroom + * + * @param mbuf mbuf to zero out + */ +void uc_mbuf_zero(struct MBuf *mbuf); + +/** + * @return the length of the data in this mbuf + */ static UC_INLINE uint32_t uc_mbuf_len(struct MBuf *mbuf) { return (uint32_t)(mbuf->tail - mbuf->head); } +/** + * @return the length of the tailroom in this mbuf + */ static UC_INLINE uint32_t uc_mbuf_tailroom(struct MBuf *mbuf) { return mbuf->allocated - (uint32_t)(mbuf->tail - mbuf->bufstart); } +/** + * @return the length of the headroom in this mbuf + */ static inline uint32_t uc_mbuf_headroom(struct MBuf *mbuf) { return (uint32_t)(mbuf->head - mbuf->bufstart); } + +/** Append data data to this buffer + * The returned pointer points at the end of the current + * data in the buffer, advancing the tail be size bytes . + * You need to insert the size bytes at in the returned pointer. + * + * @param size bytes to put in the buffer + * @return NULL if the mbuf does not have room for the given size + */ uint8_t *uc_mbuf_put(struct MBuf *mbuf, uint32_t size); +/** Prepend data to the buffer. The buffer needs to have enough + * headroom to allow this. + * The returned pointer points size bytes in front if the current + * 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 + * @return NULL if the mbuf does not have enough headroom + */ uint8_t *uc_mbuf_push(struct MBuf *mbuf, uint32_t size); +/** Remove data from the buffer ("read" data from it) + * The returned pointer is the beginning of the data in the + * buffer, advancing the head by size bytes. + * + * @param size number of bytes to pull + * @return NULL if the buffer does not have at least size bytes + **/ uint8_t *uc_mbuf_pull(struct MBuf *mbuf, uint32_t size); #undef UC_INLINE diff --git a/src/mbuf.c b/src/mbuf.c index 6d735ab..865612a 100644 --- a/src/mbuf.c +++ b/src/mbuf.c @@ -86,11 +86,13 @@ struct MBuf *uc_mbuf_new_inline_hr(uint32_t len, uint32_t headroom) void uc_mbuf_free(struct MBuf *mbuf) { - if (mbuf->flags & (UC_MBUF_FL_MALLOC | UC_MBUF_FL_MALLOC_BUF)) - free(mbuf->bufstart); - - if (mbuf->flags & (UC_MBUF_FL_MALLOC | UC_MBUF_FL_MALLOC_INLINE)) - free(mbuf); + if (mbuf != NULL) { + if (mbuf->flags & (UC_MBUF_FL_MALLOC | UC_MBUF_FL_MALLOC_BUF)) + free(mbuf->bufstart); + + if (mbuf->flags & (UC_MBUF_FL_MALLOC | UC_MBUF_FL_MALLOC_INLINE)) + free(mbuf); + } } void uc_mbuf_zero(struct MBuf *mbuf) From 499517c2dd69450b15842b35c03472096689c684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Sun, 15 Sep 2013 00:00:39 +0200 Subject: [PATCH 03/12] Move long runnign test to the end of the tests --- test/test_runner.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/test_runner.c b/test/test_runner.c index 3c38f59..73cf4c1 100644 --- a/test/test_runner.c +++ b/test/test_runner.c @@ -33,9 +33,7 @@ static suite_func suites[] = { read_file_suite, pack_suite, logging_suite, - threadqueue_suite, buffer_suite, - clock_suite, seq_suite, sat_math_suite, timers_suite, @@ -43,7 +41,9 @@ static suite_func suites[] = { human_bytesz_suite, dbuf_suite, sprintb_suite, - strv_suite + strv_suite, + clock_suite, + threadqueue_suite }; int From 03d700595bc198c2cba57f0fdded85613899080f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Sun, 15 Sep 2013 00:01:08 +0200 Subject: [PATCH 04/12] Improve docus --- include/ucore/mbuf.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/ucore/mbuf.h b/include/ucore/mbuf.h index 723d575..3cf45cd 100644 --- a/include/ucore/mbuf.h +++ b/include/ucore/mbuf.h @@ -102,7 +102,8 @@ struct MBuf *uc_mbuf_new_inline_hr(uint32_t len, uint32_t headroom); void uc_mbuf_free(struct MBuf *mbuf); /** Create a new mbuf, with a copy of the data from the given - * mbuf. The new mbuf will have the same headroom as the old one. + * mbuf. The new mbuf will have the same headroom as the old one, + * but no tailroom. * * @param mbuf mbuf to copy */ From 9988d8f4c0f44f41b9f70bcbe84eddaa132c0308 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Sun, 15 Sep 2013 00:01:19 +0200 Subject: [PATCH 05/12] Add uc_str_append_all function --- include/ucore/strvec.h | 12 ++++++++++ src/strvec.c | 25 +++++++++++++++++++++ test/test_strv.c | 51 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+) diff --git a/include/ucore/strvec.h b/include/ucore/strvec.h index 3789d78..79fd641 100644 --- a/include/ucore/strvec.h +++ b/include/ucore/strvec.h @@ -83,6 +83,18 @@ void uc_strv_clear(struct UCStrv *strv); */ void uc_strv_destroy(struct UCStrv *strv); +/** + * Append all the elments from b to a + * If copy is 1, the appended elements will be copied when appended + * + * @param a destination UCStrv + * @param b source UCStrv + * @param copy 1 for making a copy of the string when appending it + * 0 to just append the same pointer in b to a + * @return 0 on success, != 0 if appending/allocation fails + */ +int uc_strv_append_all(struct UCStrv *a, struct UCStrv *b, int copy); + #ifdef __cplusplus } #endif diff --git a/src/strvec.c b/src/strvec.c index 079cbdd..9131b3f 100644 --- a/src/strvec.c +++ b/src/strvec.c @@ -105,3 +105,28 @@ void uc_strv_destroy(struct UCStrv *strv) strv->strings = NULL; } +int uc_strv_append_all(struct UCStrv *a, struct UCStrv *b, int copy) +{ + size_t i; + int rc; + + rc = uc_strv_grow(a, a->allocated + b->cnt); + if (rc != 0) { + return rc; + } + + for (i = 0; i < b->cnt; i++) { + if (copy) { + rc = uc_strv_append(a, b->strings[i]); + } else { + rc = uc_strv_append_nocopy(a, b->strings[i]); + } + + if (rc != 0) { + return rc; + } + } + + return 0; +} + diff --git a/test/test_strv.c b/test/test_strv.c index d9745b2..e8bf8ec 100644 --- a/test/test_strv.c +++ b/test/test_strv.c @@ -1,5 +1,6 @@ #include #include +#include #include @@ -73,6 +74,54 @@ START_TEST (test_strv_null_terminate) END_TEST +START_TEST (test_strv_append_all_copy) + struct UCStrv src; + struct UCStrv dst; + int rc; + + uc_strv_init(&src); + uc_strv_init(&dst); + + uc_strv_append(&dst, "string1"); + uc_strv_append(&src, "string2"); + uc_strv_append(&src, "string3"); + + rc = uc_strv_append_all(&dst, &src, 1); + fail_if(rc != 0); + fail_if(dst.cnt != 3); + ck_assert_str_eq("string1", dst.strings[0]); + ck_assert_str_eq("string2", dst.strings[1]); + ck_assert_str_eq("string3", dst.strings[2]); + + uc_strv_destroy(&src); + uc_strv_destroy(&dst); + +END_TEST + +START_TEST (test_strv_append_all_nocopy) + struct UCStrv src; + struct UCStrv dst; + int rc; + + uc_strv_init(&src); + uc_strv_init(&dst); + + uc_strv_append(&dst, "string1"); + uc_strv_append(&src, "string2"); + uc_strv_append(&src, "string3"); + + rc = uc_strv_append_all(&dst, &src, 0); + fail_if(rc != 0); + fail_if(dst.cnt != 3); + ck_assert_str_eq("string1", dst.strings[0]); + ck_assert_str_eq("string2", dst.strings[1]); + ck_assert_str_eq("string3", dst.strings[2]); + + uc_strv_destroy(&dst); + free(src.strings); + +END_TEST + Suite *strv_suite(void) { @@ -83,6 +132,8 @@ Suite *strv_suite(void) tcase_add_test(tc, test_strv_clear); tcase_add_test(tc, test_strv_nocopy); tcase_add_test(tc, test_strv_null_terminate); + tcase_add_test(tc, test_strv_append_all_copy); + tcase_add_test(tc, test_strv_append_all_nocopy); suite_add_tcase(s, tc); From 4b8a49fb81a33370aacdeb3a166d3389679700cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Wed, 18 Sep 2013 10:32:07 +0200 Subject: [PATCH 06/12] Exercise adding/removing timers a bit more --- test/test_timers.c | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/test/test_timers.c b/test/test_timers.c index d0e81aa..33c0b09 100644 --- a/test/test_timers.c +++ b/test/test_timers.c @@ -164,37 +164,31 @@ START_TEST (test_timers_add_remove) struct UCoreSettableClock clk; struct TimerTest tt; struct UCTimers timers; - struct UCTimer timer1; - struct UCTimer timer2; - struct UCTimer timer3; - struct UCTimer timer4; + struct UCTimer timer[1023]; struct timeval first; + size_t i; + int toggle = 5; - common_init(&clk, &tt, &timers, &timer1); - memset(&timer2, 0, sizeof timer2); - memset(&timer3, 0, sizeof timer2); - memset(&timer4, 0, sizeof timer2); + common_init(&clk, &tt, &timers, &timer[0]); + memset(&timer, 0, sizeof timer); + for (i = 0; i < sizeof timer/sizeof timer[0]; i++) { + timer[i].callback = timer_test_cb_add; - timer1.callback = timer_test_cb_add; - timer2.callback = timer_test_cb_add; - timer3.callback = timer_test_cb_add; - timer4.callback = timer_test_cb_add; - - uc_timers_add(&timers, &timer1, 10, 0); - uc_timers_add(&timers, &timer2, 5 , 0); - uc_timers_add(&timers, &timer3, 15, 1); - uc_timers_add(&timers, &timer4, 15, 1); + uc_timers_add(&timers, &timer[i], toggle + i , 0); + if (i > 5) //just to add timeouts non-ascending order + toggle = 5 - toggle; + } fail_if(uc_timers_first(&timers, &first) != 0); fail_if(first.tv_sec != TEST_TIMER_START + 5); fail_if(first.tv_usec != 0); - fail_if(uc_timers_count(&timers) != 4); + fail_if(uc_timers_count(&timers) != sizeof timer/sizeof timer[0]); + + for (i = 0; i < sizeof timer/sizeof timer[0]; i++) { + uc_timers_remove(&timers, &timer[i]); + } - uc_timers_remove(&timers, &timer1); - uc_timers_remove(&timers, &timer2); - uc_timers_remove(&timers, &timer3); - uc_timers_remove(&timers, &timer4); fail_if(uc_timers_count(&timers) != 0); fail_if(uc_timers_first(&timers, &first) == 0); From 5be46cd0434a8765280be7b4a7c9cf2bd284b5db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Thu, 26 Sep 2013 22:22:05 +0200 Subject: [PATCH 07/12] Add RTP sender test --- test/ortp-send-simple.c | 146 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 test/ortp-send-simple.c diff --git a/test/ortp-send-simple.c b/test/ortp-send-simple.c new file mode 100644 index 0000000..7f27b18 --- /dev/null +++ b/test/ortp-send-simple.c @@ -0,0 +1,146 @@ +#include +#include +#include +#include +#include +#include +#include +#include + + +struct IOMux *mux; + +#define errx(x, ...) do { fprintf(stderr, x, __VA_ARGS__); exit(1); } while(0) + +struct RTPSender { + FILE *file; + char remote_ip[48]; + uint16_t remote_port; + struct UCTimer timer; + uint32_t ts; + struct timespec last_ts; + RtpSession *rtp_sess; + RtpProfile *rtp_profile; + int accum_diff; + uint8_t frame[160]; +}; + + +//returns microsec +int diffts(const struct timespec *a, struct timespec *b) +{ + struct timespec diff; + diff.tv_sec = b->tv_sec - a->tv_sec; + diff.tv_nsec = b->tv_nsec - a->tv_nsec; + if (diff.tv_nsec < 0) { + diff.tv_sec--; + diff.tv_nsec += 1000000000; + } + + + return (int) (diff.tv_sec * 1000 + (diff.tv_nsec + 500)/1000); +} + +void timer_cb(struct UCTimers *timers, struct UCTimer *timer) +{ + struct RTPSender *s = CONTAINER_OF(timer, struct RTPSender, timer); + int rc; + ssize_t r; + struct timespec ts; + int diff; + int adjust; + + clock_gettime(CLOCK_MONOTONIC, &ts); + rc = rtp_session_send_with_ts(s->rtp_sess,s->frame, sizeof s->frame, s->ts); + if(rc < sizeof s->frame) { + printf("Error, short send of %d bytes\n", rc); + } + s->ts += 160; + + r = fread(s->frame,1, sizeof s->frame, s->file); + if (r <= 0) { + rtp_session_bye(s->rtp_sess, "Finished"); + return; + } + + diff = diffts(&s->last_ts, &ts); + diff -= 20000; + + s->accum_diff += diff; + + if (s->accum_diff > 500) + adjust = -1000; + else if (s->accum_diff < -500) + adjust = 1000; + else + adjust = s->accum_diff; + + if (s->accum_diff >= 20000 || s->accum_diff <= -20000) { + s->ts += 160; + printf("Skew ! accum_diff %d\n", s->accum_diff); + s->accum_diff -= 20000; + } + + + uc_timers_add(iomux_get_timers(mux), &s->timer, 0, 20 * 1000 + adjust); + + s->last_ts = ts; +} + +void init_sender(FILE* file, const char *remote_ip, uint16_t remote_port) +{ + struct RTPSender *s = calloc(1, sizeof *s); + + RtpSession *rtp_sess = rtp_session_new(RTP_SESSION_SENDONLY); + RtpProfile *rtp_prof = rtp_profile_new("pcmu8000"); + rtp_profile_set_payload(rtp_prof, 0, &payload_type_pcmu8000); + rtp_session_set_profile(rtp_sess, rtp_prof); + //rtp_session_set_local_addr("192.168.1.55", 0); + rtp_session_set_remote_addr(rtp_sess, remote_ip, remote_port); + rtp_session_set_blocking_mode(rtp_sess, FALSE); + + s->file = file; + strcpy(s->remote_ip, remote_ip); + s->remote_port = remote_port; + s->rtp_sess = rtp_sess; + s->rtp_profile = rtp_prof; + s->timer.callback = timer_cb; + clock_gettime(CLOCK_MONOTONIC, &s->last_ts); + uc_timers_add(iomux_get_timers(mux), &s->timer, 0, 20000); +} + +int main(int argc, char *argv[]) +{ + mux = iomux_create(IOMUX_TYPE_DEFAULT); + + FILE *file; + if(argc != 4) { + puts("Specify a file name, remote IP and remote port"); + return 1; + } + + if(strcmp(argv[1], "-") == 0) { + file = stdin; + } else { + file = fopen(argv[1], "rb"); + if(file == NULL) { + perror("Cannot open file"); + return 1; + } + } + + ortp_init(); + ortp_set_log_level_mask(ORTP_DEBUG| ORTP_MESSAGE| ORTP_WARNING| ORTP_ERROR|ORTP_FATAL); + init_sender(file ,argv[2], atoi(argv[3])); + + iomux_run(mux); + + + fclose(file); + ortp_exit(); + + return 0; +} + +//compile: +// gcc -Wall -g -O `pkg-config --cflags --libs ortp` ortp-send-simple.c From ff0fd32ae171408d76c63252f861af5b9d47bf70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Thu, 26 Sep 2013 22:22:19 +0200 Subject: [PATCH 08/12] Fix comment --- include/ucore/mbuf.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/ucore/mbuf.h b/include/ucore/mbuf.h index 3cf45cd..256354a 100644 --- a/include/ucore/mbuf.h +++ b/include/ucore/mbuf.h @@ -17,7 +17,8 @@ enum UC_MBUF_FLAGS { }; struct MBuf { - /** next pointer, user can use this for a linked list*/ + /** prev/next pointer, user can use this for a linked list*/ + struct MBuf *prev; struct MBuf *next; /** Pointers the user can use to remember spots in * the data. (these must either be NULL pointers or point into From dd517a5d85600bc62bdcf98efa9d64dbe495bb5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Sat, 28 Sep 2013 23:45:51 +0200 Subject: [PATCH 09/12] Prefix CONTAINER_OF with UC_ --- include/ucore/utils.h | 6 +++--- src/clock.c | 4 ++-- src/threadqueue.c | 24 +++++++++++++++++------- src/timers.c | 4 ++-- test/ortp-send-simple.c | 2 +- test/test_containerof.c | 2 +- test/timers.c | 2 +- test/udp_heartbeat.c | 4 ++-- 8 files changed, 29 insertions(+), 19 deletions(-) diff --git a/include/ucore/utils.h b/include/ucore/utils.h index aad8379..26d706e 100644 --- a/include/ucore/utils.h +++ b/include/ucore/utils.h @@ -46,14 +46,14 @@ //a 'zap' member inside a struct foo. //give us the struct foo*: //struct foo *f = CONTAINER_OF(p, struct foo, zap); -#define CONTAINER_OF(ptr, type, member) ({ \ +#define UC_CONTAINER_OF(ptr, type, member) ({ \ typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)((void *)(unsigned char *)__mptr - offsetof(type, member) ); }) //the void* cast is to suppress alignment warnings -//Same as CONTAINER_OF, but for a const pointer to avoid gcc warnings.. -#define CONST_CONTAINER_OF(ptr, type, member) ({ \ +//Same as UC_CONTAINER_OF, but for a const pointer to avoid gcc warnings.. +#define UC_CONST_CONTAINER_OF(ptr, type, member) ({ \ const typeof( ((const type *)0)->member ) *__mptr = (ptr); \ (const type *)((const void *)(const unsigned char *)__mptr - offsetof(const type, member) ); }) diff --git a/src/clock.c b/src/clock.c index 3e3e309..aeb0538 100644 --- a/src/clock.c +++ b/src/clock.c @@ -32,7 +32,7 @@ static void uc_cached_clock_now(struct UCoreClock *uclock, struct timeval *tv) { struct UCoreCachedClock *cached_clock; - cached_clock = CONTAINER_OF(uclock, struct UCoreCachedClock, clock), + cached_clock = UC_CONTAINER_OF(uclock, struct UCoreCachedClock, clock), *tv = cached_clock->cache; } @@ -55,7 +55,7 @@ void uc_cached_clock_update(struct UCoreCachedClock *uclock) static void uc_settable_clock_now(struct UCoreClock *uclock, struct timeval *tv) { struct UCoreSettableClock *cached_clock; - cached_clock = CONTAINER_OF(uclock, struct UCoreSettableClock, clock), + cached_clock = UC_CONTAINER_OF(uclock, struct UCoreSettableClock, clock), *tv = cached_clock->now; } diff --git a/src/threadqueue.c b/src/threadqueue.c index 14d087d..47308df 100644 --- a/src/threadqueue.c +++ b/src/threadqueue.c @@ -57,7 +57,9 @@ int uc_thread_queue_init(struct uc_threadqueue *queue, long max_elements) return rc; } -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) { int rc = 0; struct timespec abstimeout; @@ -81,7 +83,8 @@ int uc_thread_queue_tryadd(struct uc_threadqueue *queue, const struct timespec * if(timeout->tv_sec == 0 && timeout->tv_nsec == 0) { rc = ETIMEDOUT; } else { - rc = pthread_cond_timedwait(&queue->write_cond, &queue->mutex, &abstimeout); + rc = pthread_cond_timedwait(&queue->write_cond, &queue->mutex, + &abstimeout); } } else { @@ -127,7 +130,9 @@ int uc_thread_queue_tryadd(struct uc_threadqueue *queue, const struct timespec * } -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) { int rc = 0; struct timespec abstimeout; @@ -153,7 +158,8 @@ int uc_thread_queue_tryget(struct uc_threadqueue *queue, const struct timespec * if(timeout->tv_sec == 0 && timeout->tv_nsec == 0) { rc = ETIMEDOUT; } else { - rc = pthread_cond_timedwait(&queue->read_cond, &queue->mutex, &abstimeout); + rc = pthread_cond_timedwait(&queue->read_cond, &queue->mutex, + &abstimeout); } } else { pthread_cond_wait(&queue->read_cond, &queue->mutex); @@ -192,17 +198,20 @@ int uc_thread_queue_tryget(struct uc_threadqueue *queue, const struct timespec * return 0; } -static void uc_thread_queue_walk_unlocked(struct uc_threadqueue *queue, uc_thread_queue_walk_func walk_func) +static void uc_thread_queue_walk_unlocked(struct uc_threadqueue *queue, + uc_thread_queue_walk_func walk_func) { struct uc_threadmsg *p; struct uc_threadmsg *next; + for(p = queue->first; p; p = next) { next = p->next; walk_func(p); } } -int uc_thread_queue_walk(struct uc_threadqueue *queue, uc_thread_queue_walk_func walk_func) +int uc_thread_queue_walk(struct uc_threadqueue *queue, + uc_thread_queue_walk_func walk_func) { if (queue == NULL || !walk_func) { return EINVAL; @@ -217,7 +226,8 @@ int uc_thread_queue_walk(struct uc_threadqueue *queue, uc_thread_queue_walk_func return 0; } -int uc_thread_queue_destroy(struct uc_threadqueue *queue, uc_thread_queue_walk_func free_func) +int uc_thread_queue_destroy(struct uc_threadqueue *queue, + uc_thread_queue_walk_func free_func) { int rc; diff --git a/src/timers.c b/src/timers.c index ed399dc..872a21b 100644 --- a/src/timers.c +++ b/src/timers.c @@ -6,8 +6,8 @@ static int timers_cmp(const RBNode *a_, const RBNode *b_) { - const struct UCTimer *a = CONST_CONTAINER_OF(a_, struct UCTimer, rb_node); - const struct UCTimer *b = CONST_CONTAINER_OF(b_, struct UCTimer, rb_node); + const struct UCTimer *a = UC_CONST_CONTAINER_OF(a_, struct UCTimer, rb_node); + const struct UCTimer *b = UC_CONST_CONTAINER_OF(b_, struct UCTimer, rb_node); if (timercmp(&a->timeout, &b->timeout, <)) { return -1; diff --git a/test/ortp-send-simple.c b/test/ortp-send-simple.c index 7f27b18..681a038 100644 --- a/test/ortp-send-simple.c +++ b/test/ortp-send-simple.c @@ -43,7 +43,7 @@ int diffts(const struct timespec *a, struct timespec *b) void timer_cb(struct UCTimers *timers, struct UCTimer *timer) { - struct RTPSender *s = CONTAINER_OF(timer, struct RTPSender, timer); + struct RTPSender *s = UC_CONTAINER_OF(timer, struct RTPSender, timer); int rc; ssize_t r; struct timespec ts; diff --git a/test/test_containerof.c b/test/test_containerof.c index f8db97b..b0cc868 100644 --- a/test/test_containerof.c +++ b/test/test_containerof.c @@ -25,7 +25,7 @@ START_TEST (test_container_of) }; struct Inner *innerp = &outer.inner; - struct Outer *outerp = CONTAINER_OF(innerp, struct Outer, inner); + struct Outer *outerp = UC_CONTAINER_OF(innerp, struct Outer, inner); fail_if(outerp != &outer); diff --git a/test/timers.c b/test/timers.c index a708b77..9ff5af9 100644 --- a/test/timers.c +++ b/test/timers.c @@ -22,7 +22,7 @@ void t2_cb(struct UCTimers *timers, struct UCTimer *timer) void mystruct1_cb(struct UCTimers *timers, struct UCTimer *timer) { - struct MyStruct *mystruct = CONTAINER_OF(timer, struct MyStruct, timer); + struct MyStruct *mystruct = UC_CONTAINER_OF(timer, struct MyStruct, timer); TRACEF("MyStruct1 timer: %s\n", mystruct->str); uc_timers_add(timers, timer, 1, 0); diff --git a/test/udp_heartbeat.c b/test/udp_heartbeat.c index 5fc0ae3..4eb3847 100644 --- a/test/udp_heartbeat.c +++ b/test/udp_heartbeat.c @@ -70,7 +70,7 @@ void peer_do_state(struct HBPeer *peer, enum PeerEvent event); void peer_timer_cb(struct UCTimers *timers, struct UCTimer *timer) { - struct HBPeer *peer = CONTAINER_OF(timer, struct HBPeer, timer); + struct HBPeer *peer = UC_CONTAINER_OF(timer, struct HBPeer, timer); struct HBContext *ctx = timer->cookie_ptr; time_t now; @@ -181,7 +181,7 @@ void peer_received(struct HBPeer *peer) void hb_read(struct IOMux *mux, struct IOMuxFD *fd, unsigned int event) { - struct HBContext *ctx = CONTAINER_OF(fd, struct HBContext, sock_fd); + struct HBContext *ctx = UC_CONTAINER_OF(fd, struct HBContext, sock_fd); ssize_t rc; struct sockaddr_in peer_addr; socklen_t peer_len = sizeof peer_addr; From d619d58ccdae30298eb0ddadf415426c55c8dc80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Tue, 1 Oct 2013 22:30:39 +0200 Subject: [PATCH 10/12] Fix overflow in strv_null_terminate, and don't make it increase .cnt --- src/strvec.c | 4 ++-- test/test_strv.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/strvec.c b/src/strvec.c index 9131b3f..7919ad5 100644 --- a/src/strvec.c +++ b/src/strvec.c @@ -29,7 +29,8 @@ int uc_strv_expand(struct UCStrv *strv) int rc = 0; if (strv->cnt >= strv->allocated) { - rc = uc_strv_grow(strv, 1); + //make some extra room + rc = uc_strv_grow(strv, 4); } return rc; @@ -81,7 +82,6 @@ int uc_strv_null_terminate(struct UCStrv *strv) } strv->strings[strv->cnt] = NULL; - strv->cnt++; return 0; } diff --git a/test/test_strv.c b/test/test_strv.c index e8bf8ec..3d172da 100644 --- a/test/test_strv.c +++ b/test/test_strv.c @@ -68,6 +68,7 @@ START_TEST (test_strv_null_terminate) rc = uc_strv_null_terminate(&strv); fail_if(rc != 0); + fail_if(strv.cnt != 1); //shouldn't increase .cnt fail_if(strv.strings[strv.cnt] != NULL); uc_strv_destroy(&strv); From 27aa7ef3d62938ab121fd222e40a6b2b95c63849 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Wed, 2 Oct 2013 21:33:10 +0200 Subject: [PATCH 11/12] Some comment improving --- src/iomux_epoll.c | 2 +- src/iomux_select.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/iomux_epoll.c b/src/iomux_epoll.c index 65a9eaf..6e22319 100644 --- a/src/iomux_epoll.c +++ b/src/iomux_epoll.c @@ -170,7 +170,7 @@ again: event_cnt = iomux_timers_run(mux_); //process timers - if (rc == 0) //Just the timeout + if (rc == 0) //no fd's were ready, no more work to do return event_cnt; for (i = 0; i < rc; i++) { diff --git a/src/iomux_select.c b/src/iomux_select.c index ad39cf9..7312415 100644 --- a/src/iomux_select.c +++ b/src/iomux_select.c @@ -157,7 +157,7 @@ again: event_cnt = iomux_timers_run(mux_); //fire the timers - if (rc == 0) //Just the 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++) { From 41c58589a58b46125ea9636bee486d5f7ad47372 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Wed, 2 Oct 2013 21:35:19 +0200 Subject: [PATCH 12/12] Fix harmless off by one when walking file descriptors --- src/iomux_select.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/iomux_select.c b/src/iomux_select.c index 7312415..bcc3fa3 100644 --- a/src/iomux_select.c +++ b/src/iomux_select.c @@ -160,7 +160,7 @@ again: 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++) { + for (i = 0; rc > 0 && i < mux->num_descriptors; i++) { unsigned int events = 0; if (mux->descriptors[i] == NULL) { //callback might have deleted it