/* Allocate and add a new page to the given pool * may result in a LS_ERR_NO_MEMORY err, * increments pool->size as side-effect */ static bool _add_page(ls_pool* pool, ls_err* err) { _pool_page* page; if ( !_malloc_fnc(pool, sizeof(struct pool_page), (void*) &page, NULL, err) ) { return false; } if ( !_malloc_fnc(pool, pool->page_size, &(page->block), NULL, err) ) { ls_data_free(page); return false; } if ( !ls_pool_add_cleaner(pool, _free_page, page, err) ) { ls_data_free(page->block); ls_data_free(page); return false; } page->size = pool->page_size; page->used = 0; page->next = pool->pages; pool->pages = page; pool->size += pool->page_size; return true; }
/* page cleaner */ static void _free_page(void* arg) { _pool_page* page = (struct pool_page*)arg; ls_data_free(page->block); ls_data_free(page); }
static void cleaner(ls_queue* q, void* data) { UNUSED_PARAM(q); ls_data_free(data); }
LS_API void tube_destroy(tube *t) { if (t->pktinfo) { ls_pktinfo_destroy(t->pktinfo); } ls_data_free(t); }
LS_API void ls_pool_destroy(ls_pool* pool) { struct pool_cleaner_ctx* cur, * next; assert(pool); cur = pool->cleaners; while (cur != NULL) { (*cur->cleaner)(cur->arg); next = cur->next; ls_data_free(cur); cur = next; } ls_data_free(pool); }
static void remove_cb(ls_event_data* evt, void* arg) { tube* t = evt->data; int* i = tube_get_data(t); UNUSED_PARAM(arg); tubes[*i] = NULL; ls_data_free(i); }
LS_API bool tube_send(tube *t, spud_command cmd, bool adec, bool pdec, uint8_t **data, size_t *len, int num, ls_err *err) { spud_header smh; int i, count; struct iovec *iov; bool ret; assert(t!=NULL); iov = ls_data_calloc(num+1, sizeof(struct iovec)); if (!iov) { LS_ERROR(err, LS_ERR_NO_MEMORY); return false; } if (!spud_init(&smh, &t->id, err)) { return false; } smh.flags = 0; smh.flags |= cmd; if (adec) { smh.flags |= SPUD_ADEC; } if (pdec) { smh.flags |= SPUD_PDEC; } count = 0; iov[count].iov_base = &smh; iov[count].iov_len = sizeof(smh); count++; for (i=0; i<num; i++) { if (len[i] > 0) { iov[count].iov_base = data[i]; iov[count].iov_len = len[i]; count++; } } ret = tube_manager_sendmsg(t->sock, t->pktinfo, (struct sockaddr *)&t->peer, iov, count, err); ls_data_free(iov); return ret; }
/* * malloc and free wrappers, _malloc_fnc checks errors and add cleaners as * needed. */ static bool _malloc_fnc(ls_pool* pool, size_t size, void** ptr, ls_pool_cleaner cleaner, ls_err* err) { void* ret = ls_data_malloc(size); if (!ret) { LS_ERROR(err, LS_ERR_NO_MEMORY); return false; } if ( pool && cleaner && !ls_pool_add_cleaner(pool, cleaner, ret, err) ) { ls_data_free(ret); return false; } *ptr = ret; return true; }
LS_API bool ls_pool_create(size_t size, ls_pool** pool, ls_err* err) { ls_pool* ret; assert(pool); if ( !_malloc_fnc(NULL, sizeof(struct _ls_pool_int), (void*) &ret, NULL, err) ) { return false; } ret->cleaners = NULL; ret->pages = NULL; ret->size = 0; /* see ../include/pool_types.h for information on DISABLE_POOL_PAGES */ #ifdef DISABLE_POOL_PAGES _paging_enabled = false; #endif if (!_paging_enabled) { size = 0; } ret->page_size = size; if ( size && !_add_page(ret, err) ) { ls_data_free(ret); return false; } *pool = ret; return true; }
LS_API void ls_pktinfo_destroy(ls_pktinfo *p) { assert(p); ls_data_free(p); }