mirror of
https://github.com/tezc/sc.git
synced 2025-01-14 06:43:04 +08:00
made data structures immune to call term/destroy twice
This commit is contained in:
parent
3d11311f90
commit
57e67dc955
@ -2,9 +2,9 @@
|
||||
Language: Cpp
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignConsecutiveMacros: true
|
||||
AlignConsecutiveAssignments: None
|
||||
AlignConsecutiveDeclarations: None
|
||||
AlignConsecutiveMacros: None
|
||||
AlignEscapedNewlines: Right
|
||||
AlignOperands: Align
|
||||
AlignTrailingComments: true
|
||||
@ -100,7 +100,7 @@ PenaltyReturnTypeOnItsOwnLine: 60
|
||||
|
||||
PointerAlignment: Right
|
||||
ReflowComments: true
|
||||
SortIncludes: true
|
||||
SortIncludes: CaseSensitive
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: true
|
||||
SpaceAfterTemplateKeyword: true
|
||||
|
@ -46,6 +46,11 @@ static void test1(void)
|
||||
{
|
||||
int *arr, total = 0;
|
||||
|
||||
sc_array_create(arr, 10);
|
||||
assert(arr != NULL);
|
||||
sc_array_destroy(arr);
|
||||
assert(arr == NULL);
|
||||
|
||||
sc_array_create(arr, 5);
|
||||
sc_array_add(arr, 3);
|
||||
sc_array_add(arr, 4);
|
||||
|
@ -9,6 +9,24 @@ void test1()
|
||||
const char *xstr;
|
||||
struct sc_buf buf, buf2;
|
||||
|
||||
sc_buf_init(&buf, 100);
|
||||
assert(buf.mem != NULL);
|
||||
sc_buf_term(&buf);
|
||||
|
||||
sc_buf_init(&buf2, 0);
|
||||
assert(buf.mem == buf2.mem);
|
||||
assert(buf.limit == buf2.limit);
|
||||
assert(buf.wpos == buf2.wpos);
|
||||
assert(buf.rpos == buf2.rpos);
|
||||
assert(buf.ref == buf2.ref);
|
||||
assert(buf.cap == buf2.cap);
|
||||
assert(buf.err == buf2.err);
|
||||
sc_buf_term(&buf2);
|
||||
|
||||
sc_buf_put_64(&buf, 100);
|
||||
assert(sc_buf_get_64(&buf) == 100);
|
||||
sc_buf_term(&buf);
|
||||
|
||||
sc_buf_init(&buf, 100);
|
||||
sc_buf_set_rpos(&buf, 1);
|
||||
assert(sc_buf_valid(&buf) == false);
|
||||
|
@ -69,6 +69,8 @@ void sc_buf_term(struct sc_buf *b)
|
||||
if (!b->ref) {
|
||||
sc_buf_free(b->mem);
|
||||
}
|
||||
|
||||
sc_buf_init(b, 0);
|
||||
}
|
||||
|
||||
void sc_buf_limit(struct sc_buf *b, uint32_t limit)
|
||||
|
@ -113,16 +113,17 @@ int sc_thread_start(struct sc_thread *thread, void *(*fn)(void *), void *arg)
|
||||
|
||||
int sc_thread_join(struct sc_thread *thread, void **ret)
|
||||
{
|
||||
int rc;
|
||||
void *val;
|
||||
int rc = 0;
|
||||
void *val = NULL;
|
||||
|
||||
if (thread->id == 0) {
|
||||
return -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = pthread_join(thread->id, &val);
|
||||
thread->id = 0;
|
||||
|
||||
out:
|
||||
if (ret != NULL) {
|
||||
*ret = val;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int example(void)
|
||||
{
|
||||
@ -54,6 +55,19 @@ void test1(void)
|
||||
void *data;
|
||||
struct sc_heap heap;
|
||||
|
||||
sc_heap_init(&heap, 0);
|
||||
sc_heap_add(&heap, 100, "test");
|
||||
sc_heap_pop(&heap, &key, &data);
|
||||
assert(key == 100);
|
||||
assert(strcmp("test", data) == 0);
|
||||
sc_heap_term(&heap);
|
||||
|
||||
sc_heap_add(&heap, 100, "test");
|
||||
sc_heap_pop(&heap, &key, &data);
|
||||
assert(key == 100);
|
||||
assert(strcmp("test", data) == 0);
|
||||
sc_heap_term(&heap);
|
||||
|
||||
assert(sc_heap_init(&heap, SIZE_MAX / 2) == false);
|
||||
assert(sc_heap_init(&heap, 3) == true);
|
||||
|
||||
@ -67,7 +81,7 @@ void test1(void)
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
assert(sc_heap_add(&heap, arr[i],
|
||||
(void *) (uintptr_t)(arr[i] * 2)) == true);
|
||||
(void *) (uintptr_t) (arr[i] * 2)) == true);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
@ -97,7 +111,7 @@ void test2(void)
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
assert(sc_heap_add(&heap, -arr[i],
|
||||
(void *) (uintptr_t)(arr[i] * 2)) == true);
|
||||
(void *) (uintptr_t) (arr[i] * 2)) == true);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
|
@ -54,6 +54,10 @@ bool sc_heap_init(struct sc_heap *h, size_t cap)
|
||||
void sc_heap_term(struct sc_heap *h)
|
||||
{
|
||||
sc_heap_free(h->elems);
|
||||
|
||||
*h = (struct sc_heap){
|
||||
.elems = NULL,
|
||||
};
|
||||
}
|
||||
|
||||
size_t sc_heap_size(struct sc_heap *h)
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include "sc_ini.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
@ -186,9 +186,12 @@ int sc_log_term(void)
|
||||
if (rc != 0) {
|
||||
rc = -1;
|
||||
}
|
||||
sc_log_mutex_term(&sc_log.mtx);
|
||||
}
|
||||
|
||||
sc_log_mutex_term(&sc_log.mtx);
|
||||
sc_log = (struct sc_log){
|
||||
.fp = NULL,
|
||||
};
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -518,6 +518,17 @@ void test1()
|
||||
values[i] = str_random((rand() % 64) + 32);
|
||||
}
|
||||
|
||||
sc_map_init_str(&map, 0, 0);
|
||||
sc_map_put_str(&map, "100", "200");
|
||||
sc_map_get_str(&map, "100", &value);
|
||||
assert(strcmp(value, "200") == 0);
|
||||
sc_map_term_str(&map);
|
||||
sc_map_put_str(&map, "100", "200");
|
||||
sc_map_get_str(&map, "100", &value);
|
||||
assert(strcmp(value, "200") == 0);
|
||||
sc_map_term_str(&map);
|
||||
|
||||
|
||||
assert(!sc_map_init_str(&map, 0, -1));
|
||||
assert(!sc_map_init_str(&map, 0, 24));
|
||||
assert(!sc_map_init_str(&map, 0, 96));
|
||||
|
@ -131,7 +131,7 @@
|
||||
m->used = false; \
|
||||
m->cap = cap; \
|
||||
m->load_fac = f; \
|
||||
m->remap = (uint32_t)(m->cap * ((double) m->load_fac / 100)); \
|
||||
m->remap = (uint32_t) (m->cap * ((double) m->load_fac / 100)); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
@ -140,6 +140,7 @@
|
||||
{ \
|
||||
if (m->mem != sc_map_empty_##name.mem) { \
|
||||
sc_map_free(&m->mem[-1]); \
|
||||
*m = sc_map_empty_##name; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
@ -199,7 +200,7 @@
|
||||
\
|
||||
m->mem = new; \
|
||||
m->cap = cap; \
|
||||
m->remap = (uint32_t)(m->cap * ((double) m->load_fac / 100)); \
|
||||
m->remap = (uint32_t) (m->cap * ((double) m->load_fac / 100)); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
@ -330,7 +331,7 @@ static uint32_t sc_map_hash_32(uint32_t a)
|
||||
|
||||
static uint32_t sc_map_hash_64(uint64_t a)
|
||||
{
|
||||
return ((uint32_t) a) ^ (uint32_t)(a >> 32u);
|
||||
return ((uint32_t) a) ^ (uint32_t) (a >> 32u);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
|
@ -21,6 +21,8 @@ void test1()
|
||||
assert(rc == 0);
|
||||
rc = sc_mmap_term(&mmap);
|
||||
assert(rc == 0);
|
||||
rc = sc_mmap_term(&mmap);
|
||||
assert(rc == 0);
|
||||
|
||||
rc = sc_mmap_init(&mmap, "x.txt", O_RDWR | O_CREAT | O_TRUNC,
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED, 0, 8192);
|
||||
|
@ -261,6 +261,10 @@ int sc_mmap_term(struct sc_mmap *m)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (m->fd == -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
close(m->fd);
|
||||
|
||||
rc = munmap(m->ptr, m->len);
|
||||
@ -268,6 +272,12 @@ int sc_mmap_term(struct sc_mmap *m)
|
||||
strncpy(m->err, strerror(errno), sizeof(m->err) - 1);
|
||||
}
|
||||
|
||||
*m = (struct sc_mmap) {
|
||||
.ptr = NULL,
|
||||
.fd = -1,
|
||||
.len = 0,
|
||||
};
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -135,13 +135,14 @@ char *sc_str_create_fmt(const char *fmt, ...)
|
||||
return str;
|
||||
}
|
||||
|
||||
void sc_str_destroy(char *str)
|
||||
void sc_str_destroy(char **str)
|
||||
{
|
||||
if (str == NULL) {
|
||||
if (str == NULL || *str == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
sc_str_free(sc_str_meta(str));
|
||||
sc_str_free(sc_str_meta(*str));
|
||||
*str = NULL;
|
||||
}
|
||||
|
||||
int64_t sc_str_len(const char *str)
|
||||
@ -174,7 +175,7 @@ bool sc_str_set(char **str, const char *param)
|
||||
return false;
|
||||
}
|
||||
|
||||
sc_str_destroy(*str);
|
||||
sc_str_destroy(str);
|
||||
*str = c;
|
||||
|
||||
return true;
|
||||
@ -190,7 +191,7 @@ bool sc_str_set_fmt(char **str, const char *fmt, ...)
|
||||
va_end(args);
|
||||
|
||||
if (ret != NULL) {
|
||||
sc_str_destroy(*str);
|
||||
sc_str_destroy(str);
|
||||
*str = ret;
|
||||
}
|
||||
|
||||
@ -310,7 +311,7 @@ bool sc_str_trim(char **str, const char *list)
|
||||
return false;
|
||||
}
|
||||
|
||||
sc_str_destroy(*str);
|
||||
sc_str_destroy(str);
|
||||
*str = head;
|
||||
}
|
||||
|
||||
@ -336,7 +337,7 @@ bool sc_str_substring(char **str, uint32_t start, uint32_t end)
|
||||
return false;
|
||||
}
|
||||
|
||||
sc_str_destroy(*str);
|
||||
sc_str_destroy(str);
|
||||
*str = c;
|
||||
|
||||
return true;
|
||||
@ -416,7 +417,7 @@ bool sc_str_replace(char **str, const char *replace, const char *with)
|
||||
|
||||
memcpy(tmp, orig, orig_end - orig + 1);
|
||||
|
||||
sc_str_destroy(*str);
|
||||
sc_str_destroy(str);
|
||||
*str = dest->buf;
|
||||
|
||||
return true;
|
||||
|
@ -82,7 +82,7 @@ char *sc_str_create_va(const char *fmt, va_list va);
|
||||
* Deallocate length prefixed string.
|
||||
* @param str length prefixed string. str may be NULL.
|
||||
*/
|
||||
void sc_str_destroy(char *str);
|
||||
void sc_str_destroy(char **str);
|
||||
|
||||
/**
|
||||
* @param str length prefixed string. NULL values are accepted.
|
||||
|
@ -62,6 +62,13 @@ int __wrap_vsnprintf(char *str, size_t size, const char *format, va_list ap)
|
||||
|
||||
void test1()
|
||||
{
|
||||
char* m = sc_str_create(NULL);
|
||||
sc_str_destroy(&m);
|
||||
sc_str_append(&m, "test");
|
||||
sc_str_append_fmt(&m, "%d", 3);
|
||||
assert(strcmp(m, "test3") == 0);
|
||||
sc_str_destroy(&m);
|
||||
|
||||
assert(sc_str_len(NULL) == -1);
|
||||
sc_str_destroy(NULL);
|
||||
assert(sc_str_dup(NULL) == NULL);
|
||||
@ -79,8 +86,8 @@ void test1()
|
||||
assert(strcmp(s1, "test3") == 0);
|
||||
fail_malloc = false;
|
||||
|
||||
sc_str_destroy(s1);
|
||||
sc_str_destroy(s2);
|
||||
sc_str_destroy(&s1);
|
||||
sc_str_destroy(&s2);
|
||||
|
||||
fail_malloc = true;
|
||||
assert(sc_str_create("test") == NULL);
|
||||
@ -96,8 +103,8 @@ void test1()
|
||||
assert(strcmp(s1, "5test5") == 0);
|
||||
s2 = sc_str_dup(s1);
|
||||
assert(sc_str_cmp(s1, s2) == true);
|
||||
sc_str_destroy(s1);
|
||||
sc_str_destroy(s2);
|
||||
sc_str_destroy(&s1);
|
||||
sc_str_destroy(&s2);
|
||||
|
||||
fail_malloc = true;
|
||||
s1 = sc_str_create_fmt("%dtest%d", 5, 5);
|
||||
@ -152,7 +159,7 @@ void test1()
|
||||
assert(strcmp(s1, "test") == 0);
|
||||
fail_vsnprintf_at = -1;
|
||||
free(s2);
|
||||
sc_str_destroy(s1);
|
||||
sc_str_destroy(&s1);
|
||||
|
||||
fail_vsnprintf = true;
|
||||
assert(!sc_str_set_fmt(&s1, "test%d", 3));
|
||||
@ -201,7 +208,7 @@ void test2()
|
||||
fail_strlen = 2;
|
||||
assert(sc_str_replace(&c, "*", "2") == false);
|
||||
fail_strlen = INT32_MAX;
|
||||
sc_str_destroy(c);
|
||||
sc_str_destroy(&c);
|
||||
|
||||
c = sc_str_create("n1n1");
|
||||
assert(sc_str_substring(&c, -1, -3) == false);
|
||||
@ -218,7 +225,7 @@ void test2()
|
||||
assert(sc_str_append(&c, "12") == false);
|
||||
fail_realloc = false;
|
||||
|
||||
sc_str_destroy(c);
|
||||
sc_str_destroy(&c);
|
||||
|
||||
fail_vsnprintf_at = 2;
|
||||
fail_vnsprintf_value = -1;
|
||||
@ -243,7 +250,7 @@ void test2()
|
||||
assert(tmp[i] == x1[i]);
|
||||
}
|
||||
|
||||
sc_str_destroy(x1);
|
||||
sc_str_destroy(&x1);
|
||||
free(tmp);
|
||||
|
||||
x1 = NULL;
|
||||
@ -255,7 +262,7 @@ void test2()
|
||||
assert(x1[i] == 'x');
|
||||
}
|
||||
assert(sc_str_len(x1) == 4000);
|
||||
sc_str_destroy(x1);
|
||||
sc_str_destroy(&x1);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -308,7 +315,7 @@ void test3()
|
||||
while ((token = sc_str_token_begin(str, &save, "-")) != NULL) {
|
||||
}
|
||||
sc_str_token_end(str, &save);
|
||||
sc_str_destroy(str);
|
||||
sc_str_destroy(&str);
|
||||
|
||||
str = sc_str_create(NULL);
|
||||
save = NULL;
|
||||
@ -316,12 +323,12 @@ void test3()
|
||||
assert(strcmp(token, "token") == 0);
|
||||
}
|
||||
sc_str_token_end(str, &save);
|
||||
sc_str_destroy(str);
|
||||
sc_str_destroy(&str);
|
||||
|
||||
str = sc_str_create("x,x");
|
||||
save = NULL;
|
||||
sc_str_token_end(str, &save);
|
||||
sc_str_destroy(str);
|
||||
sc_str_destroy(&str);
|
||||
|
||||
str = sc_str_create("x,x");
|
||||
save = NULL;
|
||||
@ -330,7 +337,7 @@ void test3()
|
||||
break;
|
||||
}
|
||||
sc_str_token_end(str, &save);
|
||||
sc_str_destroy(str);
|
||||
sc_str_destroy(&str);
|
||||
|
||||
str = sc_str_create("x,x");
|
||||
save = NULL;
|
||||
@ -340,7 +347,7 @@ void test3()
|
||||
}
|
||||
sc_str_token_end(str, &save);
|
||||
sc_str_token_end(str, &save);
|
||||
sc_str_destroy(str);
|
||||
sc_str_destroy(&str);
|
||||
}
|
||||
|
||||
void test4()
|
||||
@ -405,7 +412,7 @@ void test4()
|
||||
sc_str_token_end(str, &save);
|
||||
assert(strcmp(str, "tk1;tk2-tk3 tk4 tk5*tk6") == 0);
|
||||
|
||||
sc_str_destroy(str);
|
||||
sc_str_destroy(&str);
|
||||
}
|
||||
|
||||
void test5()
|
||||
@ -419,7 +426,7 @@ void test5()
|
||||
assert(strcmp(s2, "test") == 0);
|
||||
assert(sc_str_len(s2) == 4);
|
||||
assert(strcmp(s1, s2) == 0);
|
||||
sc_str_destroy(s2);
|
||||
sc_str_destroy(&s2);
|
||||
|
||||
sc_str_set(&s1, "test2");
|
||||
assert(strcmp(s1, "test2") == 0);
|
||||
@ -452,7 +459,7 @@ void test5()
|
||||
assert(strcmp(s1, "longeRlongeR") == 0);
|
||||
assert(sc_str_replace(&s1, "longeR", ""));
|
||||
assert(strcmp(s1, "") == 0);
|
||||
sc_str_destroy(s1);
|
||||
sc_str_destroy(&s1);
|
||||
|
||||
s1 = sc_str_create("*test * test*");
|
||||
sc_str_trim(&s1, "*");
|
||||
@ -465,29 +472,29 @@ void test5()
|
||||
sc_str_set(&s1, "testtx");
|
||||
sc_str_trim(&s1, "a");
|
||||
|
||||
sc_str_destroy(s1);
|
||||
sc_str_destroy(&s1);
|
||||
|
||||
s1 = sc_str_create(" elem1,elem2, elem3 ");
|
||||
sc_str_trim(&s1, " ");
|
||||
assert(strcmp(s1, "elem1,elem2, elem3") == 0);
|
||||
sc_str_replace(&s1, " ", "");
|
||||
assert(strcmp(s1, "elem1,elem2,elem3") == 0);
|
||||
sc_str_destroy(s1);
|
||||
sc_str_destroy(&s1);
|
||||
|
||||
s1 = sc_str_create("elem1,elem2,elem3");
|
||||
sc_str_replace(&s1, "elem", "item");
|
||||
assert(strcmp(s1, "item1,item2,item3") == 0);
|
||||
sc_str_destroy(s1);
|
||||
sc_str_destroy(&s1);
|
||||
|
||||
s1 = sc_str_create(NULL);
|
||||
assert(sc_str_append_fmt(&s1, "%s", "string") == true);
|
||||
assert(strcmp(s1, "string") == 0);
|
||||
sc_str_destroy(s1);
|
||||
sc_str_destroy(&s1);
|
||||
|
||||
s1 = sc_str_create(NULL);
|
||||
sc_str_append(&s1, "string");
|
||||
assert(strcmp(s1, "string") == 0);
|
||||
sc_str_destroy(s1);
|
||||
sc_str_destroy(&s1);
|
||||
|
||||
s1 = sc_str_create(NULL);
|
||||
assert(sc_str_trim(&s1, "x") == true);
|
||||
@ -499,17 +506,17 @@ void test5()
|
||||
assert(sc_str_dup(s1) == NULL);
|
||||
assert(sc_str_set(&s1, "string") == true);
|
||||
assert(strcmp(s1, "string") == 0);
|
||||
sc_str_destroy(s1);
|
||||
sc_str_destroy(&s1);
|
||||
|
||||
s1 = sc_str_create(NULL);
|
||||
assert(sc_str_set_fmt(&s1, "%s", "string") == true);
|
||||
assert(strcmp(s1, "string") == 0);
|
||||
sc_str_destroy(s1);
|
||||
sc_str_destroy(&s1);
|
||||
|
||||
s1 = sc_str_create(NULL);
|
||||
assert(sc_str_set(&s1, "string") == true);
|
||||
assert(strcmp(s1, "string") == 0);
|
||||
sc_str_destroy(s1);
|
||||
sc_str_destroy(&s1);
|
||||
}
|
||||
|
||||
void test6()
|
||||
@ -521,47 +528,47 @@ void test6()
|
||||
|
||||
s1 = sc_str_create(NULL);
|
||||
assert(s1 == NULL);
|
||||
sc_str_destroy(s1);
|
||||
sc_str_destroy(&s1);
|
||||
|
||||
s1 = sc_str_create_len(NULL, 100);
|
||||
assert(s1 == NULL);
|
||||
sc_str_destroy(s1);
|
||||
sc_str_destroy(&s1);
|
||||
|
||||
s1 = NULL;
|
||||
b = sc_str_set(&s1, "test");
|
||||
assert(b);
|
||||
assert(strcmp(s1, "test") == 0);
|
||||
sc_str_destroy(s1);
|
||||
sc_str_destroy(&s1);
|
||||
|
||||
s1 = NULL;
|
||||
b = sc_str_set_fmt(&s1, "test");
|
||||
assert(b);
|
||||
assert(strcmp(s1, "test") == 0);
|
||||
sc_str_destroy(s1);
|
||||
sc_str_destroy(&s1);
|
||||
|
||||
s1 = NULL;
|
||||
b = sc_str_append(&s1, "test");
|
||||
assert(b);
|
||||
assert(strcmp(s1, "test") == 0);
|
||||
sc_str_destroy(s1);
|
||||
sc_str_destroy(&s1);
|
||||
|
||||
s1 = NULL;
|
||||
b = sc_str_trim(&s1, "*");
|
||||
assert(b);
|
||||
assert(s1 == NULL);
|
||||
sc_str_destroy(s1);
|
||||
sc_str_destroy(&s1);
|
||||
|
||||
s1 = NULL;
|
||||
b = sc_str_substring(&s1, 0, 0);
|
||||
assert(!b);
|
||||
assert(s1 == NULL);
|
||||
sc_str_destroy(s1);
|
||||
sc_str_destroy(&s1);
|
||||
|
||||
s1 = NULL;
|
||||
b = sc_str_replace(&s1, "s", "a");
|
||||
assert(b);
|
||||
assert(s1 == NULL);
|
||||
sc_str_destroy(s1);
|
||||
sc_str_destroy(&s1);
|
||||
|
||||
s1 = NULL;
|
||||
while ((token = sc_str_token_begin(s1, &save, ";")) != NULL) {
|
||||
@ -570,15 +577,15 @@ void test6()
|
||||
}
|
||||
|
||||
sc_str_token_end(s1, &save);
|
||||
sc_str_destroy(s1);
|
||||
sc_str_destroy(&s1);
|
||||
|
||||
s1 = sc_str_create("de1");
|
||||
s2 = sc_str_create("de2");
|
||||
assert(!sc_str_cmp(s1, s2));
|
||||
sc_str_set(&s1, "dee2");
|
||||
assert(!sc_str_cmp(s1, s2));
|
||||
sc_str_destroy(s1);
|
||||
sc_str_destroy(s2);
|
||||
sc_str_destroy(&s1);
|
||||
sc_str_destroy(&s2);
|
||||
}
|
||||
|
||||
int main()
|
||||
|
@ -78,12 +78,12 @@ int sc_thread_start(struct sc_thread *t, void *(*fn)(void *), void *arg)
|
||||
int sc_thread_join(struct sc_thread *t, void **ret)
|
||||
{
|
||||
int rc = 0;
|
||||
void* val = NULL;
|
||||
DWORD rv;
|
||||
BOOL brc;
|
||||
|
||||
if (t->id == 0) {
|
||||
strncpy(t->err, "Already stopped.", sizeof(t->err));
|
||||
return -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rv = WaitForSingleObject(t->id, INFINITE);
|
||||
@ -98,7 +98,10 @@ int sc_thread_join(struct sc_thread *t, void **ret)
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
val = t->ret;
|
||||
t->id = 0;
|
||||
|
||||
out:
|
||||
if (ret != NULL) {
|
||||
*ret = t->ret;
|
||||
}
|
||||
@ -134,20 +137,17 @@ int sc_thread_start(struct sc_thread *t, void *(*fn)(void *), void *arg)
|
||||
|
||||
int sc_thread_join(struct sc_thread *t, void **ret)
|
||||
{
|
||||
int rc;
|
||||
void *val;
|
||||
int rc = 0;
|
||||
void *val = NULL;
|
||||
|
||||
if (t->id == 0) {
|
||||
return -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = pthread_join(t->id, &val);
|
||||
if (rc != 0) {
|
||||
strncpy(t->err, strerror(rc), sizeof(t->err) - 1);
|
||||
}
|
||||
|
||||
t->id = 0;
|
||||
|
||||
out:
|
||||
if (ret != NULL) {
|
||||
*ret = val;
|
||||
}
|
||||
|
@ -26,7 +26,9 @@ void test1()
|
||||
assert(strcmp((char *) ret, "first") == 0);
|
||||
|
||||
rc = sc_thread_term(&thread);
|
||||
assert(rc == -1);
|
||||
assert(rc == 0);
|
||||
rc = sc_thread_term(&thread);
|
||||
assert(rc == 0);
|
||||
|
||||
sc_thread_init(&thread);
|
||||
rc = sc_thread_start(&thread, fn, "first");
|
||||
|
@ -34,34 +34,20 @@
|
||||
#define SC_TIMER_MAX (UINT32_MAX / sizeof(struct sc_timer_data)) / WHEEL_COUNT
|
||||
#endif
|
||||
|
||||
|
||||
bool sc_timer_init(struct sc_timer *t, uint64_t timestamp)
|
||||
void sc_timer_init(struct sc_timer *t, uint64_t timestamp)
|
||||
{
|
||||
const uint32_t wheel_cap = 4;
|
||||
const uint32_t cap = WHEEL_COUNT * wheel_cap;
|
||||
const size_t size = cap * sizeof(struct sc_timer_data);
|
||||
|
||||
t->count = 0;
|
||||
t->head = 0;
|
||||
t->wheel = wheel_cap;
|
||||
t->timestamp = timestamp;
|
||||
|
||||
t->list = sc_timer_malloc(size);
|
||||
if (t->list == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < cap; i++) {
|
||||
t->list[i].timeout = UINT64_MAX;
|
||||
t->list[i].data = NULL;
|
||||
}
|
||||
|
||||
return true;
|
||||
*t = (struct sc_timer){
|
||||
.timestamp = timestamp,
|
||||
};
|
||||
}
|
||||
|
||||
void sc_timer_term(struct sc_timer *t)
|
||||
{
|
||||
sc_timer_free(t->list);
|
||||
|
||||
*t = (struct sc_timer){
|
||||
.timestamp = t->timestamp,
|
||||
};
|
||||
}
|
||||
|
||||
void sc_timer_clear(struct sc_timer *t)
|
||||
@ -79,7 +65,8 @@ void sc_timer_clear(struct sc_timer *t)
|
||||
|
||||
static bool expand(struct sc_timer *t)
|
||||
{
|
||||
uint32_t cap = t->wheel * WHEEL_COUNT * 2;
|
||||
uint32_t wheel = t->wheel != 0 ? t->wheel * 2 : 4;
|
||||
uint32_t cap = wheel * WHEEL_COUNT * 2;
|
||||
size_t size = cap * sizeof(struct sc_timer_data);
|
||||
struct sc_timer_data *alloc;
|
||||
|
||||
@ -111,7 +98,7 @@ static bool expand(struct sc_timer *t)
|
||||
sc_timer_free(t->list);
|
||||
|
||||
t->list = alloc;
|
||||
t->wheel *= 2;
|
||||
t->wheel = wheel;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -119,12 +106,11 @@ static bool expand(struct sc_timer *t)
|
||||
uint64_t sc_timer_add(struct sc_timer *t, uint64_t timeout, uint64_t type,
|
||||
void *data)
|
||||
{
|
||||
const uint32_t offset = (uint32_t)(timeout / TICK + t->head);
|
||||
const uint32_t offset = (uint32_t) (timeout / TICK + t->head);
|
||||
const uint32_t pos = offset & (WHEEL_COUNT - 1);
|
||||
uint64_t id;
|
||||
uint32_t seq, index, wheel_pos;
|
||||
|
||||
|
||||
wheel_pos = (pos * t->wheel);
|
||||
for (seq = 0; seq < t->wheel; seq++) {
|
||||
index = wheel_pos + seq;
|
||||
@ -176,7 +162,7 @@ uint64_t sc_timer_timeout(struct sc_timer *t, uint64_t timestamp, void *arg,
|
||||
const uint64_t time = timestamp - t->timestamp;
|
||||
uint32_t wheel, base;
|
||||
uint32_t head = t->head;
|
||||
uint32_t wheels = (uint32_t)(sc_timer_min(time / TICK, WHEEL_COUNT));
|
||||
uint32_t wheels = (uint32_t) (sc_timer_min(time / TICK, WHEEL_COUNT));
|
||||
struct sc_timer_data *item;
|
||||
|
||||
if (wheels == 0) {
|
||||
|
@ -60,9 +60,8 @@ struct sc_timer {
|
||||
*
|
||||
* @param t timer
|
||||
* @param timestamp current timestamp. Use monotonic timer source.
|
||||
* @return 'false' on out of memory.
|
||||
*/
|
||||
bool sc_timer_init(struct sc_timer *t, uint64_t timestamp);
|
||||
void sc_timer_init(struct sc_timer *t, uint64_t timestamp);
|
||||
|
||||
/**
|
||||
* Destroy timer.
|
||||
|
@ -81,7 +81,8 @@ void test1(void)
|
||||
{
|
||||
struct sc_timer timer;
|
||||
|
||||
assert(sc_timer_init(&timer, time_ms()));
|
||||
sc_timer_init(&timer, time_ms());
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
ids[i] = sc_timer_add(&timer, rand() % 100, i,
|
||||
(void *) (uintptr_t) i);
|
||||
@ -105,13 +106,37 @@ void test1(void)
|
||||
}
|
||||
|
||||
sc_timer_term(&timer);
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
ids[i] = sc_timer_add(&timer, rand() % 100, i,
|
||||
(void *) (uintptr_t) i);
|
||||
assert(ids[i] != SC_TIMER_INVALID);
|
||||
}
|
||||
|
||||
t = 10000;
|
||||
while (t > 0) {
|
||||
n = sc_timer_timeout(&timer, time_ms(),
|
||||
(void *) (uintptr_t) 333, callback);
|
||||
if (timer.count == 0) {
|
||||
break;
|
||||
}
|
||||
t -= n;
|
||||
sleep_ms(n);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
assert(ids[i] == SC_TIMER_INVALID);
|
||||
}
|
||||
|
||||
sc_timer_term(&timer);
|
||||
}
|
||||
|
||||
void test2(void)
|
||||
{
|
||||
struct sc_timer timer;
|
||||
|
||||
assert(sc_timer_init(&timer, time_ms()));
|
||||
sc_timer_init(&timer, time_ms());
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
ids[i] = SC_TIMER_INVALID;
|
||||
sc_timer_add(&timer, rand() % 100, i, (void *) (uintptr_t) i);
|
||||
@ -164,7 +189,8 @@ void test3(void)
|
||||
{
|
||||
struct sc_timer timer;
|
||||
|
||||
assert(sc_timer_init(&timer, time_ms()));
|
||||
sc_timer_init(&timer, time_ms());
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
ids[i] = sc_timer_add(&timer, rand() % 20, i,
|
||||
(void *) (uintptr_t) i);
|
||||
@ -202,7 +228,8 @@ void test4(void)
|
||||
{
|
||||
struct sc_timer timer;
|
||||
|
||||
assert(sc_timer_init(&timer, 0));
|
||||
sc_timer_init(&timer, 0);
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
ids[i] = sc_timer_add(&timer, rand() % 20, i,
|
||||
(void *) (uintptr_t) i);
|
||||
@ -256,10 +283,7 @@ void fail_test(void)
|
||||
size_t max = 50000;
|
||||
struct sc_timer timer;
|
||||
|
||||
fail_malloc = true;
|
||||
assert(sc_timer_init(&timer, time_ms()) == false);
|
||||
fail_malloc = false;
|
||||
assert(sc_timer_init(&timer, time_ms()) == true);
|
||||
sc_timer_init(&timer, time_ms());
|
||||
|
||||
uint64_t id;
|
||||
for (size_t i = 0; i < max + 100; i++) {
|
||||
|
@ -174,7 +174,12 @@ error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void sc_uri_destroy(struct sc_uri *uri)
|
||||
void sc_uri_destroy(struct sc_uri **uri)
|
||||
{
|
||||
sc_uri_free(uri);
|
||||
if (uri == NULL || *uri == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
sc_uri_free(*uri);
|
||||
*uri = NULL;
|
||||
}
|
||||
|
@ -100,6 +100,6 @@ struct sc_uri *sc_uri_create(const char *str);
|
||||
/**
|
||||
* @param uri uri
|
||||
*/
|
||||
void sc_uri_destroy(struct sc_uri *uri);
|
||||
void sc_uri_destroy(struct sc_uri **uri);
|
||||
|
||||
#endif
|
||||
|
@ -12,6 +12,11 @@ void test1(void)
|
||||
const char *f = "foo://user:password@example.com:8042/over/"
|
||||
"there?name=ferret#nose";
|
||||
|
||||
uri = sc_uri_create("");
|
||||
assert(uri == NULL);
|
||||
sc_uri_destroy(&uri);
|
||||
sc_uri_destroy(NULL);
|
||||
|
||||
uri = sc_uri_create(f);
|
||||
assert(uri != NULL);
|
||||
assert(strcmp(uri->str, f) == 0);
|
||||
@ -23,7 +28,7 @@ void test1(void)
|
||||
assert(strcmp(uri->query, "name=ferret") == 0);
|
||||
assert(strcmp(uri->fragment, "nose") == 0);
|
||||
|
||||
sc_uri_destroy(uri);
|
||||
sc_uri_destroy(&uri);
|
||||
}
|
||||
|
||||
void test2(void)
|
||||
@ -43,7 +48,7 @@ void test2(void)
|
||||
assert(strcmp(uri->query, "tag=networking&order=newest") == 0);
|
||||
assert(strcmp(uri->fragment, "top") == 0);
|
||||
|
||||
sc_uri_destroy(uri);
|
||||
sc_uri_destroy(&uri);
|
||||
}
|
||||
|
||||
void test3(void)
|
||||
@ -62,7 +67,7 @@ void test3(void)
|
||||
assert(strcmp(uri->query, "objectClass?one") == 0);
|
||||
assert(strcmp(uri->fragment, "") == 0);
|
||||
|
||||
sc_uri_destroy(uri);
|
||||
sc_uri_destroy(&uri);
|
||||
}
|
||||
|
||||
void test4(void)
|
||||
@ -81,7 +86,7 @@ void test4(void)
|
||||
assert(strcmp(uri->query, "") == 0);
|
||||
assert(strcmp(uri->fragment, "") == 0);
|
||||
|
||||
sc_uri_destroy(uri);
|
||||
sc_uri_destroy(&uri);
|
||||
}
|
||||
|
||||
void test5(void)
|
||||
@ -100,7 +105,7 @@ void test5(void)
|
||||
assert(strcmp(uri->query, "") == 0);
|
||||
assert(strcmp(uri->fragment, "") == 0);
|
||||
|
||||
sc_uri_destroy(uri);
|
||||
sc_uri_destroy(&uri);
|
||||
}
|
||||
|
||||
void test6(void)
|
||||
@ -119,7 +124,7 @@ void test6(void)
|
||||
assert(strcmp(uri->query, "") == 0);
|
||||
assert(strcmp(uri->fragment, "") == 0);
|
||||
|
||||
sc_uri_destroy(uri);
|
||||
sc_uri_destroy(&uri);
|
||||
}
|
||||
|
||||
void test7(void)
|
||||
@ -138,7 +143,7 @@ void test7(void)
|
||||
assert(strcmp(uri->query, "") == 0);
|
||||
assert(strcmp(uri->fragment, "") == 0);
|
||||
|
||||
sc_uri_destroy(uri);
|
||||
sc_uri_destroy(&uri);
|
||||
}
|
||||
|
||||
void test8(void)
|
||||
@ -158,7 +163,7 @@ void test8(void)
|
||||
assert(strcmp(uri->query, "") == 0);
|
||||
assert(strcmp(uri->fragment, "") == 0);
|
||||
|
||||
sc_uri_destroy(uri);
|
||||
sc_uri_destroy(&uri);
|
||||
}
|
||||
|
||||
void test9(void)
|
||||
@ -177,7 +182,7 @@ void test9(void)
|
||||
assert(strcmp(uri->query, "fred") == 0);
|
||||
assert(strcmp(uri->fragment, "") == 0);
|
||||
|
||||
sc_uri_destroy(uri);
|
||||
sc_uri_destroy(&uri);
|
||||
}
|
||||
|
||||
void test10(void)
|
||||
@ -196,7 +201,7 @@ void test10(void)
|
||||
assert(strcmp(uri->query, "") == 0);
|
||||
assert(strcmp(uri->fragment, "") == 0);
|
||||
|
||||
sc_uri_destroy(uri);
|
||||
sc_uri_destroy(&uri);
|
||||
}
|
||||
|
||||
void test11(void)
|
||||
@ -213,7 +218,7 @@ void test11(void)
|
||||
NULL);
|
||||
assert(sc_uri_create("ldap://[2001:db8::7") == NULL);
|
||||
|
||||
sc_uri_destroy(uri);
|
||||
sc_uri_destroy(&uri);
|
||||
}
|
||||
|
||||
void test12(void)
|
||||
@ -232,7 +237,7 @@ void test12(void)
|
||||
assert(strcmp(uri->query, "x") == 0);
|
||||
assert(strcmp(uri->fragment, "3") == 0);
|
||||
|
||||
sc_uri_destroy(uri);
|
||||
sc_uri_destroy(&uri);
|
||||
}
|
||||
|
||||
void test13(void)
|
||||
@ -321,13 +326,13 @@ void fail_test()
|
||||
|
||||
uri = sc_uri_create("tcp://127.0.0.1");
|
||||
assert(uri != NULL);
|
||||
sc_uri_destroy(uri);
|
||||
sc_uri_destroy(&uri);
|
||||
|
||||
uri = sc_uri_create("tcp:/127.0.0.1");
|
||||
assert(uri != NULL);
|
||||
assert(strcmp(uri->scheme, "tcp") == 0);
|
||||
assert(strcmp(uri->path, "/127.0.0.1") == 0);
|
||||
sc_uri_destroy(uri);
|
||||
sc_uri_destroy(&uri);
|
||||
|
||||
fail_snprintf = -1;
|
||||
assert(sc_uri_create("tcp://127.0.0.1") == NULL);
|
||||
|
Loading…
x
Reference in New Issue
Block a user