bool mdict_put_str(struct MDict *dict, const char *key, unsigned klen, const char *val, unsigned vlen) { char *kptr, *vptr = NULL; struct MDictElem *el; if (val) { vptr = cx_alloc(dict->cx, vlen + 1); if (!vptr) return false; memcpy(vptr, val, vlen); vptr[vlen] = 0; } el = cbtree_lookup(dict->tree, key, klen); if (el) { cx_free(dict->cx, mbuf_data(&el->val)); mbuf_init_fixed_reader(&el->val, vptr, vlen); } else { kptr = cx_alloc(dict->cx, klen + 1); if (!kptr) return false; memcpy(kptr, key, klen); kptr[klen] = 0; el = cx_alloc(dict->cx, sizeof(*el)); if (!el) return false; mbuf_init_fixed_reader(&el->key, kptr, klen); mbuf_init_fixed_reader(&el->val, vptr, vlen); if (!cbtree_insert(dict->tree, el)) return false; } return true; }
static Consumer* Consumer_new(Queue* queue, int id) { Consumer* consumer = cx_alloc(sizeof(Consumer)); consumer->id = id; consumer->queue = queue; consumer->thread = cx_alloc(sizeof(pthread_t)); consumer->processed = 0; return consumer; }
int main(int argc, char** argv) { XASSERT(argc == 5, "usage: $0 THREADS CONNECTIONS IP PORT"); int thread_count = atoi(argv[1]); connections = atoi(argv[2]); ip = argv[3]; port = (uint16_t)atoi(argv[4]); pthread_t* threads = cx_alloc((size_t)thread_count * sizeof(pthread_t*)); PROFILE_BEGIN_FMT("threads:%d requests/thread:%d\n", thread_count, connections); int i; for (i = 0; i < thread_count; i++) pthread_create(&threads[i], NULL, thread_send_data, NULL); for (i = 0; i < thread_count; i++) pthread_join(threads[i], NULL); PROFILE_END cx_free(threads); return 0; }
void *cx_memdup(CxMem *cx, const void *src, size_t len) { void *p = cx_alloc(cx, len); if (p) memcpy(p, src, len); return p; }
int cx_vasprintf(CxMem *cx, char **dst_p, const char *fmt, va_list ap) { char buf[128], *dst; int res, res2; *dst_p = NULL; res = vsnprintf(buf, sizeof buf, fmt, ap); if (res < 0) return -1; dst = cx_alloc(cx, res + 1); if (!dst) return -1; if ((size_t)res < sizeof buf) { memcpy(dst, buf, res+1); } else { res2 = vsnprintf(dst, res+1, fmt, ap); if (res2 != res) { cx_free(cx, dst); return -1; } } *dst_p = dst; return res; }
void *cx_alloc0(CxMem *cx, size_t len) { void *p = cx_alloc(cx, len); if (p) memset(p, 0, len); return p; }
StringPair* StringPair_init(String* key, String* value) { StringPair* p = cx_alloc(sizeof(StringPair)); p->key = key; p->value = value; return p; }
void *cx_realloc(CxMem *cx, void *ptr, size_t len) { if (!ptr) return cx_alloc(cx, len); if (!len) { cx_free(cx, ptr); return NULL; } return cx->ops->c_realloc(cx->ctx, ptr, len); }
Connection* Connection_new(ConnectionCallbacks* callbacks) { Connection* conn = cx_alloc(sizeof(Connection)); conn->callbacks = callbacks; conn->response_queue = Queue_new(); ((List*)conn->response_queue)->f_node_data_free = free_response; return conn; }
int cx_beginbuf(char *buf, struct value *arg, int narg) { if (cx_alloc() < 0) return -1; cx.x_type = X_BUF; cx.x_bufp = cx.x_buf = buf; cx.x_arg = arg; cx.x_narg = narg; return 0; }
static void test_Queue() { Queue* queue = Queue_new(); Consumer* consumers[NTHREADS_TOTAL]; int i_thread; for (i_thread = 0; i_thread < (NTHREADS_TOTAL / 2); i_thread++) consumers[i_thread] = Consumer_start(queue, i_thread, get_item); for (; i_thread < NTHREADS_TOTAL; i_thread++) consumers[i_thread] = Consumer_start(queue, i_thread, get_item_timed); PROFILE_BEGIN_FMT("Processing %d simple requests with %d threads\n", NITERATATIONS, NTHREADS_TOTAL); int i_item; int expected_sum = 0; for (i_item = 0; i_item < NITERATATIONS; i_item++) { int* x = cx_alloc(sizeof(int)); *x = i_item; Queue_add(queue, x); /* simulate submission delay */ expected_sum += i_item; #ifdef SUBMISSION_DELAY_MAX_MSEC usleep((rand() % SUBMISSION_DELAY_MAX_MSEC) * 1000); #endif } /* wait for threads to finish processing */ int total_processed = 0; for (i_thread = 0; i_thread < NTHREADS_TOTAL; i_thread++) { Consumer* consumer = consumers[i_thread]; // see http://stackoverflow.com/questions/5610677/valgrind-memory-leak-errors-when-using-pthread-create // http://stackoverflow.com/questions/5282099/signal-handling-in-pthreads pthread_join(*consumer->thread, NULL); XFLOG("Consumer[%d] processed %d", consumer->id, consumer->processed); total_processed += consumer->processed; Consumer_free(consumer); } PROFILE_END TEST_ASSERT_EQUAL(total_processed, NITERATATIONS); }
bool mdict_urldecode(struct MDict *dict, const char *str, unsigned len) { const char *s = str; const char *end = s + len; const char *k, *v; unsigned klen, vlen; struct MDictElem *el; while (s < end) { v = NULL; vlen = 0; el = NULL; /* read key */ k = urldec_str(dict->cx, &s, end, &klen); if (!k) goto fail; /* read value */ if (s < end && *s == '=') { s++; v = urldec_str(dict->cx, &s, end, &vlen); if (!v) goto fail; } if (s < end && *s == '&') s++; /* insert value */ el = cbtree_lookup(dict->tree, k, klen); if (el) { cx_free(dict->cx, mbuf_data(&el->val)); mbuf_init_fixed_reader(&el->val, v, vlen); } else { el = cx_alloc(dict->cx, sizeof(*el)); if (!el) goto fail; mbuf_init_fixed_reader(&el->key, k, klen); mbuf_init_fixed_reader(&el->val, v, vlen); if (!cbtree_insert(dict->tree, el)) goto fail; } } return true; fail: if (k) cx_free(dict->cx, k); if (v) cx_free(dict->cx, v); if (el) cx_free(dict->cx, el); return false; }
struct MDict *mdict_new(CxMem *cx) { struct MDict *dict; dict = cx_alloc(cx, sizeof(struct MDict)); if (!dict) return NULL; dict->cx = cx; dict->tree = cbtree_create(mdict_getkey, mdict_free_obj, dict, cx); if (!dict->tree) { cx_free(cx, dict); return NULL; } return dict; }
struct CBTree *cbtree_create(cbtree_getkey_func obj_key_cb, cbtree_walker_func obj_free_cb, void *cb_ctx, CxMem *cx) { struct CBTree *tree = cx_alloc(cx, sizeof(*tree)); if (!tree) return NULL; tree->root = NULL; tree->cb_ctx = cb_ctx; tree->obj_key_cb = obj_key_cb; tree->obj_free_cb = obj_free_cb; tree->cx = cx; return tree; }
static void *urldec_str(CxMem *cx, const char **src_p, const char *end, unsigned *len_p) { const char *s; char *d, *dst; int c, len = 0; /* estimate size */ for (s = *src_p; s < end; s++) { if (*s == '%') s += 2; else if (*s == '&' || *s == '=') break; len++; } /* allocate room */ d = dst = cx_alloc(cx, len + 1); if (!dst) return NULL; /* write out */ for (s = *src_p; s < end; ) { if (*s == '%') { if (s + 3 > end) goto err; c = gethex(s[1]) << 4; c |= gethex(s[2]); if (c < 0) goto err; s += 3; *d++ = c; } else if (*s == '+') { *d++ = ' '; s++; } else if (*s == '&' || *s == '=') { break; } else { *d++ = *s++; } } *d = 0; *len_p = d - dst; *src_p = s; return dst; err: cx_free(cx, dst); return NULL; }
/* get new reference to str */ struct PStr *strpool_get(struct StrPool *sp, const char *str, int len) { struct PStr *cstr; bool ok; pthread_mutex_lock(&sp->mutex); if (len < 0) len = strlen(str); /* search */ cstr = cbtree_lookup(sp->tree, str, len); if (cstr) { cstr->refcnt++; pthread_mutex_unlock(&sp->mutex); return cstr; } /* create */ cstr = cx_alloc(sp->ca, sizeof(*cstr) + len + 1); if (!cstr) { pthread_mutex_unlock(&sp->mutex); return NULL; } cstr->pool = sp; cstr->refcnt = 1; cstr->len = len; memcpy(cstr->str, str, len + 1); /* insert */ ok = cbtree_insert(sp->tree, cstr); if (!ok) { cx_free(sp->ca, cstr); pthread_mutex_unlock(&sp->mutex); return NULL; } sp->count++; pthread_mutex_unlock(&sp->mutex); return cstr; }
int cx_beginfile(char *filename) { if (cx_alloc() < 0) return -1; cx.x_type = X_FILE; if ((cx.x_filename = str_cpy(filename)) == 0) goto bad; cx.x_fp = fopen(filename, "r"); if (cx.x_fp == 0) goto bad; (void) fcntl(fileno(cx.x_fp), F_SETFD, 1); cx.x_bol = 1; cx.x_lineno = 0; cx.x_errwin = 0; cx.x_noerr = 0; return 0; bad: if (cx.x_filename != 0) str_free(cx.x_filename); cx_free(); return -1; }
/* create main structure */ struct StrPool *strpool_create(CxMem *ca) { struct StrPool *sp; int err = 0; sp = cx_alloc(ca, sizeof(*sp)); if (!sp) return NULL; sp->count = 0; sp->ca = ca; err = pthread_mutex_init(&sp->mutex, NULL); if (err < 0) { cx_free(ca, sp); return NULL; } sp->tree = cbtree_create(get_key, NULL, NULL, ca); if (!sp->tree) { cx_free(ca, sp); return NULL; } return sp; }
MessageParser* MessageParser_from_buf(StringBuffer* buffer, int keep_buffer) { MessageParser* parser = cx_alloc(sizeof(MessageParser)); RagelParser* ragel_parser = (RagelParser*)parser; RagelParser_init(ragel_parser); parser->message = Message_new(); parser->message->buffer = buffer; parser->message->keep_buffer = keep_buffer; ragel_parser->buffer = buffer; // set buffer pointer ragel_parser->buffer_position = buffer->string->value; ragel_parser->buffer_end = ragel_parser->buffer_position; /* setup event handlers */ ragel_parser->f_event = event_handler; ragel_parser->f_parse = message_fsm_parse; parser->f_body_parse = simple_body_parser; parser->f_body_event = NULL; return parser; }
/* node allocation */ static struct Node *new_node(struct CBTree *tree) { struct Node *node = cx_alloc(tree->cx, sizeof(*node)); memset(node, 0, sizeof(*node)); return node; }