int svcond_destroy(svcond_t *cond) { int ret = 0; if (svsem_wait(cond->blocked_lock) == -1) { AMSG(""); return -1; } if (svsem_trywait(cond->unblock_lock) != 0) { AMSG(""); svsem_post(cond->blocked_lock); return -1; } if (cond) { if (cond->blocked_lock) { ret += pool_release(cond->sempool, cond->blocked_lock); if (cond->block_queue) { ret += pool_release(cond->sempool, cond->block_queue); if (cond->unblock_lock) { ret += pool_release(cond->sempool, cond->unblock_lock); cond->unblock_lock = NULL; } cond->block_queue = NULL; } cond->blocked_lock = NULL; } } return ret ? -1 : 0; }
void bacstack_session_dl_receive_thread_handler(void *state) { info("session receive thread started"); bacstack_session_t *session = (bacstack_session_t*)state; uint8_t port_id; bacdl_msg_t msg; bacstack_message_t *stack_msg; while(!session->disposing) { if(bacdl_server_receive_msg(&session->dl_server, &msg, &port_id)) { switch(msg.code) { case BACDL_MSG_CODE_PORT_ID: debug("Port %i port_id message: %i", port_id, msg.port_id.port_id); break; case BACDL_MSG_CODE_TEXT: debug("Port %i text message: %s", port_id, msg.text.text); break; case BACDL_MSG_CODE_DATAGRAM: debug("Port %i datagram message", port_id); if(pool_acquire(&session->message_pool, (void**)&stack_msg)) { stack_msg->datagram.port_id = port_id; bacstack_mac_init( &stack_msg->datagram.source_mac, msg.datagram.source_mac, msg.datagram.source_mac_length); bacstack_mac_init( &stack_msg->datagram.dest_mac, msg.datagram.dest_mac, msg.datagram.dest_mac_length); stack_msg->raw_length = msg.datagram.datagram_length; memcpy(stack_msg->raw, msg.datagram.datagram, msg.datagram.datagram_length); buffer_init(&stack_msg->buf, stack_msg->raw, stack_msg->raw_length); if(!pool_release(&session->proc_pool, stack_msg)) { warn("failed to release bacstack message to proc pool"); pool_release(&session->message_pool, &stack_msg); } } else warn("failed to acquire bacstack_message from pool"); break; } bacdl_msg_destroy(&msg); } } }
static void pet_test(void) { #define NODES 1000000 node_t *pool, *root; struct timeval tv, tv2; time_t sec; suseconds_t msec; int i, j; pool = pool_new(NODES); j = NODES / 2; gettimeofday(&tv, NULL); root = alloc_node(pool); root = make_node(root, 0); for (i = 1; i < NODES; i++, j = (j + 17) % NODES) root = insert(root, alloc_node(pool), j); while (root) root = delete_min(root); gettimeofday(&tv2, NULL); sec = tv2.tv_sec - tv.tv_sec; msec = tv2.tv_usec - tv.tv_usec; msec += sec * 1000000; printf("%d nodes add/remove: %lu msec\n", NODES, msec); pool_release(pool); }
void bacstack_session_msg_proc_thread_handler(void *state) { info("message proc thread started"); bacstack_session_t *session = (bacstack_session_t*)state; bacstack_message_t *message = NULL; while(!session->disposing) { if(pool_acquire(&session->proc_pool, (void**)&message) && message != NULL) { debug("processor thread received datagram"); // hand the message off to the network processing functionality if(!bacstack_proc_npdu(session, message)) { error("failed to process network message"); goto release; } if(!(message->npdu_header.control & BACSTACK_NPDU_NETWORK_MESSAGE_MASK)) { debug("bacstack received an apdu"); } release: if(!bacstack_message_reset(message)) { warn("error while resetting processed bacstack message"); } if(!pool_release(&session->message_pool, message)) { error("failure releasing processed message back to message pool"); } } } }
VOID CL_ThreadUnix::ExecRun() { #if defined (_FOR_ANDROID_) || defined (_FOR_APPLE_) || defined (_LINUX) m_dwThreadID = GetCurrentThreadId(); #else m_dwThreadID = (DWORD)m_tid; #endif #if defined(_LINUX) pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); // 允许退出线程 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); // 设置立即取消 #endif SetPriorityNormal(); SetThreadName(); CL_Printf("<<<< Thread [%s] run (%lu, 0x%x) prio: %d, TC: %lu.", m_szThreadName, m_dwThreadID, m_dwThreadID, GetPriorityExt(), ::GetTickCount()); #ifdef _FOR_APPLE_ m_pPool = NULL; pool_alloc(&m_pPool); #endif m_pThreadIF->Run(); #ifdef _FOR_APPLE_ pool_release(&m_pPool); #endif CL_Printf("<<<< Thread [%s] quit (%lu, 0x%x) TC: %lu.", m_szThreadName, m_dwThreadID, m_dwThreadID, ::GetTickCount()); m_isAlive = CL_FALSE; m_dwThreadID = 0; }
int bacstack_session_put_message(bacstack_session_t *session, bacstack_message_t *message) { if(!bacstack_message_reset(message)) { warn("failed to reset a message"); } return pool_release(&session->message_pool, (void*)message); }
int PoolExercise(int verbose, struct cfg *cfg, char *args[]) { void *data; int rate, i; struct linkedlist *l; struct pool *p; cfg = NULL; args[0] = NULL; if ((p = pool_new(EXERCISE_SM_COUNT, (new_fn)allocator_alloc, allocator_free, NULL, NULL, BUFFER_SIZE_SM, 0, NULL)) == NULL || (l = linkedlist_new(0, NULL)) == NULL) { PMNO(errno); return 1; } rate = EXERCISE_R0; for (i = 0; i < EXERCISE_SM_COUNT; i++) { if (i == EXERCISE_SM_P1) { rate = EXERCISE_R1; } else if (i == EXERCISE_SM_P2) { rate = EXERCISE_R2; } else if (i == EXERCISE_SM_P3) { rate = EXERCISE_R3; } if (rand() % 10 < rate) { if (pool_size(p) == EXERCISE_SM_COUNT && pool_unused(p) == 0) { continue; } else if ((data = pool_get(p)) == NULL) { AMSG(""); return -1; } else if (linkedlist_add(l, data) == -1) { AMSG("%04d %p s=%d,u=%d\n", i, data, pool_size(p), pool_unused(p)); return -1; } tcase_printf(verbose, "%04d get %p s=%d,u=%d\n", i, data, pool_size(p), pool_unused(p)); } else if ((data = linkedlist_remove(l, 0))) { if (data == NULL || pool_release(p, data) == -1) { AMSG("%04d %p s=%d,u=%d\n", i, data, pool_size(p), pool_unused(p)); return -1; } tcase_printf(verbose, "%04d rel %p s=%d,u=%d\n", i, data, pool_size(p), pool_unused(p)); } else { tcase_printf(verbose, "%04d nothing to release\n", i); } } linkedlist_del(l, NULL, NULL); pool_del(p); return 0; }
struct sproto * sproto_create(const void * proto, size_t sz) { struct pool mem; pool_init(&mem); struct sproto * s = pool_alloc(&mem, sizeof(*s)); if (s == NULL) return NULL; memset(s, 0, sizeof(*s)); s->memory = mem; if (create_from_bundle(s, proto, sz) == NULL) { pool_release(&s->memory); return NULL; } return s; }
static intnat pool_sweep(struct caml_heap_state* local, pool** plist, sizeclass sz) { pool* a = *plist; if (!a) return 0; *plist = a->next; value* p = (value*)((char*)a + POOL_HEADER_SZ); value* end = (value*)a + POOL_WSIZE; mlsize_t wh = wsize_sizeclass[sz]; int all_free = 1, all_used = 1; struct heap_stats* s = &local->stats; while (p + wh <= end) { header_t hd = (header_t)*p; if (hd == 0) { /* already on freelist */ all_used = 0; } else if (Has_status_hd(hd, global.GARBAGE)) { Assert(Whsize_hd(hd) <= wh); /* add to freelist */ p[0] = 0; p[1] = (value)a->next_obj; Assert(Is_block((value)p)); a->next_obj = p; all_used = 0; /* update stats */ s->pool_live_blocks--; s->pool_live_words -= Whsize_hd(hd); s->pool_frag_words -= (wh - Whsize_hd(hd)); } else { /* still live */ all_free = 0; } p += wh; } if (all_free) { pool_release(local, a, sz); } else { pool** list = all_used ? &local->full_pools[sz] : &local->avail_pools[sz]; a->next = *list; *list = a; } return POOL_WSIZE; }
void test_mempool() { MemPool *block = pool_create(bsz,1); clock_t start, end; int i , j ; start = clock(); for( j = 0 ;j < runtimes; ++j) for ( i = 0 ; i < times; ++i) { void *f = m_malloc(block); m_free(block,&f); } end = clock(); fprintf(stdout,"Block Pool Time Ellapsed:%d\n",end-start); pool_release(block); }
static void delete_test(void) { node_t *pool, *root, *node; pool = pool_new(10); root = make_node(alloc_node(pool), 1); root = insert(root, alloc_node(pool), 5); root = insert(root, alloc_node(pool), 8); root = insert(root, alloc_node(pool), 10); root = insert(root, alloc_node(pool), 2); root = insert(root, alloc_node(pool), 4); root = insert(root, alloc_node(pool), 6); node = alloc_node(pool); root = insert(root, node, 3); delete(root, node); pool_release(pool); }
void test_pool() { MemPool *pool = pool_create(128,10); char *cp; int i = 0; for ( ; i < 15; ++i ) { char *c = (char*)m_malloc(pool); sprintf(c,"%d\tThis Is My Pool\n",i+1); printf(c); } cp = m_malloc(pool); m_free(pool,&cp); m_free(pool,&cp); cp = m_malloc(pool); pool_release(pool); }
static void delete_min_test(void) { node_t *pool, *root; pool = pool_new(10); root = make_node(alloc_node(pool), 1); root = insert(root, alloc_node(pool), 5); root = insert(root, alloc_node(pool), 8); root = insert(root, alloc_node(pool), 10); root = insert(root, alloc_node(pool), 2); root = insert(root, alloc_node(pool), 4); root = insert(root, alloc_node(pool), 6); root = insert(root, alloc_node(pool), 3); while (root) { printf("delete key: %lu\n", root->key); root = delete_min(root); } pool_release(pool); }
/* * Call the function_name inside the module * Store all vps in hashes %RAD_CHECK %RAD_REPLY %RAD_REQUEST * */ static int rlmperl_call(void *instance, REQUEST *request, char *function_name) { PERL_INST *inst = instance; VALUE_PAIR *vp; int exitstatus=0, count; STRLEN n_a; HV *rad_reply_hv; HV *rad_check_hv; HV *rad_request_hv; HV *rad_request_proxy_hv; HV *rad_request_proxy_reply_hv; #ifdef USE_ITHREADS POOL_HANDLE *handle; if ((handle = pool_pop(instance)) == NULL) { return RLM_MODULE_FAIL; } radlog(L_DBG,"found interpetator at address 0x%lx",(unsigned long) handle->clone); { dTHXa(handle->clone); PERL_SET_CONTEXT(handle->clone); } #else PERL_SET_CONTEXT(inst->perl); radlog(L_DBG,"Using perl at 0x%lx",(unsigned long) inst->perl); #endif { dSP; ENTER; SAVETMPS; /* * Radius has told us to call this function, but none * is defined. */ if (!function_name) { return RLM_MODULE_FAIL; } rad_reply_hv = get_hv("RAD_REPLY",1); rad_check_hv = get_hv("RAD_CHECK",1); rad_request_hv = get_hv("RAD_REQUEST",1); rad_request_proxy_hv = get_hv("RAD_REQUEST_PROXY",1); rad_request_proxy_reply_hv = get_hv("RAD_REQUEST_PROXY_REPLY",1); perl_store_vps(request->reply->vps, rad_reply_hv); perl_store_vps(request->config_items, rad_check_hv); perl_store_vps(request->packet->vps, rad_request_hv); if (request->proxy != NULL) { perl_store_vps(request->proxy->vps, rad_request_proxy_hv); } else { hv_undef(rad_request_proxy_hv); } if (request->proxy_reply !=NULL) { perl_store_vps(request->proxy_reply->vps, rad_request_proxy_reply_hv); } else { hv_undef(rad_request_proxy_reply_hv); } vp = NULL; PUSHMARK(SP); /* * This way %RAD_xx can be pushed onto stack as sub parameters. * XPUSHs( newRV_noinc((SV *)rad_request_hv) ); * XPUSHs( newRV_noinc((SV *)rad_reply_hv) ); * XPUSHs( newRV_noinc((SV *)rad_check_hv) ); * PUTBACK; */ count = call_pv(function_name, G_SCALAR | G_EVAL | G_NOARGS); SPAGAIN; if (SvTRUE(ERRSV)) { radlog(L_ERR, "rlm_perl: perl_embed:: module = %s , func = %s exit status= %s\n", inst->module, function_name, SvPV(ERRSV,n_a)); POPs; } if (count == 1) { exitstatus = POPi; if (exitstatus >= 100 || exitstatus < 0) { exitstatus = RLM_MODULE_FAIL; } } PUTBACK; FREETMPS; LEAVE; if ((get_hv_content(rad_reply_hv, &vp)) > 0 ) { pairmove(&request->reply->vps, &vp); pairfree(&vp); } if ((get_hv_content(rad_check_hv, &vp)) > 0 ) { pairmove(&request->config_items, &vp); pairfree(&vp); } if ((get_hv_content(rad_request_proxy_reply_hv, &vp)) > 0 && request->proxy_reply != NULL) { pairfree(&request->proxy_reply->vps); pairmove(&request->proxy_reply->vps, &vp); pairfree(&vp); } } #ifdef USE_ITHREADS pool_release(handle,instance); radlog(L_DBG,"Unreserve perl at address 0x%lx", (unsigned long) handle->clone); #endif return exitstatus; }
void sproto_release(struct sproto * s) { if (s == NULL) return; pool_release(&s->memory); }
int bacstack_session_init(bacstack_session_t *session) { int ret = 1; memset(session, 0, sizeof(*session)); /* this setting sets the range that is used * as the network numbers of directly attached netork. * For example, if this value is set to 1000, then * the network out of port 0 will be assigned * network number 1000. The network out of port * 100 would be assigned network number 1100. This * number must be chosen to not conflict with * existing network numbers on the BACnet network */ session->local_networks_origin = 65535 - 255; if(!rwlock_init(&session->routetable_lock)) { ret = 0; goto done; } if(!bacstack_routetable_init(&session->routetable, 2048)) { ret = 0; goto done; } if(!pool_init(&session->message_pool, BACSTACK_SESSION_MESSAGE_POOL_CAPACITY)) { ret = 0; goto done; } for(int i = 0; i < BACSTACK_SESSION_MESSAGE_POOL_CAPACITY; i++) { bacstack_message_t *message = malloc(sizeof(bacstack_message_t)); if(message == NULL || !bacstack_message_init(message)) { ret = 0; goto done; } if(!pool_release(&session->message_pool, message)) { ret = 0; goto done; } } if(!pool_init(&session->proc_pool, BACSTACK_SESSION_MESSAGE_POOL_CAPACITY)) { ret = 0; goto done; } if(!bacdl_server_init(&session->dl_server, 54321)) { ret = 0; goto done; } if(!thread_init(&session->msg_proc_thread, bacstack_session_msg_proc_thread_handler, session)) { ret = 0; goto done; } if(!thread_init(&session->dl_accept_thread, bacstack_session_dl_accept_thread_handler, session)) { ret = 0; goto done; } if(!thread_init(&session->dl_receive_thread, bacstack_session_dl_receive_thread_handler, session)) { ret = 0; goto done; } done: if(!ret){ rwlock_destroy(&session->routetable_lock); bacstack_routetable_destroy(&session->routetable); pool_destroy(&session->message_pool); pool_destroy(&session->proc_pool); bacdl_server_destroy(&session->dl_server); thread_destroy(&session->msg_proc_thread); thread_destroy(&session->dl_accept_thread); thread_destroy(&session->dl_receive_thread); } return ret; }
static void release(IQueue *queue) { Queue* q = itos(queue); mutex_release(q->mutex); pool_release(q->pool); free(q); }
/* * The xlat function */ static int perl_xlat(void *instance, REQUEST *request, char *fmt, char * out, size_t freespace, RADIUS_ESCAPE_STRING func) { PERL_INST *inst= (PERL_INST *) instance; PerlInterpreter *perl; char params[1024], *ptr, *tmp; int count, ret=0; STRLEN n_a; /* * Do an xlat on the provided string (nice recursive operation). */ if (!radius_xlat(params, sizeof(params), fmt, request, func)) { radlog(L_ERR, "rlm_perl: xlat failed."); return 0; } #ifndef USE_ITHREADS perl = inst->perl; #endif #ifdef USE_ITHREADS POOL_HANDLE *handle; if ((handle = pool_pop(instance)) == NULL) { return 0; } perl = handle->clone; radlog(L_DBG,"Found a interpetator 0x%lx",(unsigned long) perl); { dTHXa(perl); } #endif PERL_SET_CONTEXT(perl); { dSP; ENTER;SAVETMPS; ptr = strtok(params, " "); PUSHMARK(SP); while (ptr != NULL) { XPUSHs(sv_2mortal(newSVpv(ptr,0))); ptr = strtok(NULL, " "); } PUTBACK; count = call_pv(inst->func_xlat, G_SCALAR | G_EVAL); SPAGAIN; if (SvTRUE(ERRSV)) { radlog(L_ERR, "rlm_perl: perl_xlat exit %s\n", SvPV(ERRSV,n_a)); POPs ; } else if (count > 0) { tmp = POPp; ret = strlen(tmp); strncpy(out,tmp,ret); radlog(L_DBG,"rlm_perl: Len is %d , out is %s freespace is %d", ret, out,freespace); } PUTBACK ; FREETMPS ; LEAVE ; } #ifdef USE_ITHREADS pool_release(handle, instance); #endif return ret; }
/** * @note The disposition parameter marks whether or not the signature is currently marked as junk. * So training the signature means that it will toggle its status. * @param usernum the numerical id of the user making the spam training request. * @param disposition if 0, dspam will mark the signature as junk; otherwise, mark as OK. * @param signature a managed string containing the spam signature to be trained. * @return true on success or false on failure. */ bool_t dspam_train(uint64_t usernum, int_t disposition, stringer_t *signature) { int_t ret; DSPAM_CTX *ctx; chr_t unum[20]; stringer_t *tmpdir; uint32_t connection; struct _mysql_drv_dbh dbh; struct _ds_spam_signature sig; // Generate a string version of the dispatch number. if (snprintf(unum, 20, "%lu", usernum) <= 0 || !(tmpdir = spool_path(MAGMA_SPOOL_DATA))) { log_pedantic("Context setup error."); return false; } // Initialize the DSPAM context. else if (!(ctx = dspam_create_d(unum, NULL, st_char_get(tmpdir), DSM_PROCESS, DSF_SIGNATURE | DSF_NOISE | DSF_WHITELIST))) { log_pedantic("An error occurred inside the DSPAM library. {dspam_create = NULL}"); st_free(tmpdir); return false; } st_free(tmpdir); // Get a DB connection. if (pool_pull(sql_pool, &connection) != PL_RESERVED) { log_info("Unable to get an available connection for the query."); dspam_destroy_d(ctx); return false; } else if (sql_ping(connection) < 0 || !stmt_rebuild(connection)) { log_info("The database connection has been lost and the reconnection attempt failed."); dspam_destroy_d(ctx); return false; } // Setup the database handle in a structure format. dbh.dbh_read = pool_get_obj(sql_pool, connection); dbh.dbh_write = pool_get_obj(sql_pool, connection); if ((ret = dspam_attach_d(ctx, &dbh))) { if (dspam_detach_d(ctx) != 0) { log_pedantic("Could not detach the DB connection."); } pool_release(sql_pool, connection); log_pedantic("An error occurred while attaching to the statistical database. {dspam_attach = %i}", ret); dspam_destroy_d(ctx); return false; } // Tokenization method and statistical algorithm. ctx->algorithms = DSA_GRAHAM | DSA_BURTON | DSP_GRAHAM; ctx->tokenizer = DSZ_CHAIN; // Setup the classification as opposite of what the original was. ctx->classification = disposition ? DSR_ISINNOCENT : DSR_ISSPAM; // Set up the context for error correction. ctx->source = DSS_ERROR; // Setup the signature. sig.length = st_length_get(signature); sig.data = st_char_get(signature); ctx->signature = &sig; // Call DSPAM, and then destroy the context. ret = dspam_process_d(ctx, NULL); dspam_detach_d(ctx); dspam_destroy_d(ctx); pool_release(sql_pool, connection); if (ret) { log_pedantic("An error occurred while training message signature. {dspam_process = %i}", ret); return false; } return true; }
/// HIGH: Return a result structure with the disposition, confidence, probability and signature data. Then store the analysis result with the message. Either in the DB or /// by adding a custom header to the message. Return codes should become 0 for success, or a negative integer for errors. Add statistical updates to check and train functions. /// Result: result=\"%s\"; class=\"%s\"; probability=%01.4f; confidence=%02.2f; signature=%lu; key=%lu; /// Layman's terms: How spammy is this message int_t dspam_check(uint64_t usernum, stringer_t *message, stringer_t **signature) { DSPAM_CTX *ctx; chr_t unum[20]; uint32_t connection; int_t result = 2, ret; struct _mysql_drv_dbh dbh; stringer_t *tmpdir, *output; // Generate a string version of the dispatch number. if (snprintf(unum, 20, "%lu", usernum) <= 0 || !(tmpdir = spool_path(MAGMA_SPOOL_DATA))) { log_pedantic("Context setup error."); return -1; } // Initialize the DSPAM context. else if (!(ctx = dspam_create_d(unum, NULL, st_char_get(tmpdir), DSM_PROCESS, DSF_SIGNATURE | DSF_NOISE | DSF_WHITELIST))) { log_pedantic("An error occurred inside the DSPAM library. {dspam_create = NULL}"); st_free(tmpdir); return -1; } st_free(tmpdir); if (pool_pull(sql_pool, &connection) != PL_RESERVED) { log_info("Unable to get an available connection for the query."); dspam_destroy_d(ctx); return -1; } else if (sql_ping(connection) < 0 || !stmt_rebuild(connection)) { log_info("The database connection has been lost and the reconnection attempt failed."); dspam_destroy_d(ctx); return -1; } // Setup the database handle in a structure format. dbh.dbh_read = pool_get_obj(sql_pool, connection); dbh.dbh_write = pool_get_obj(sql_pool, connection); if ((ret = dspam_attach_d(ctx, &dbh))) { if (dspam_detach_d(ctx) != 0) { log_pedantic("Could not detach the DB connection."); } pool_release(sql_pool, connection); log_pedantic("An error occurred while attaching to the statistical database. {dspam_attach = %i}", ret); dspam_destroy_d(ctx); return -1; } // Tokenization method and statistical algorithm. ctx->algorithms = DSA_GRAHAM | DSA_BURTON | DSP_GRAHAM; ctx->tokenizer = DSZ_CHAIN; // To prevent the message tokens from being stored in the database we disable training. ctx->training_mode = DST_NOTRAIN; // This actually processes the message. if ((ret = dspam_process_d(ctx, st_char_get(message)))) { if (dspam_detach_d(ctx) != 0) { log_pedantic("Could not detach the DB connection."); } pool_release(sql_pool, connection); log_pedantic("An error occurred while analyzing an email with DSPAM. {dspam_process = %i}", ret); dspam_destroy_d(ctx); return -1; } // We assume that the SQL connection will no longer be needed. if ((ret = dspam_detach_d(ctx))) { log_pedantic("Could not detach the DB connection. {dspam_detach = %i}", ret); pool_release(sql_pool, connection); dspam_destroy_d(ctx); return -1; } // Return the connection to our pool. pool_release(sql_pool, connection); // Check to see if the message is junk mail. if (ctx->result == DSR_ISSPAM) { result = -2; } else { result = 1; } //log_pedantic("Probability: %2.4f Confidence: %2.4f, Result: %s", ctx->probability, ctx->confidence, // (ctx->result == DSR_ISSPAM) ? "JUNK" : "INNOCENT"); // See what happens if we don't get a signature back. if (ctx->signature == NULL) { log_error("DSPAM did not return a signature. {ctx->signature = NULL}"); dspam_destroy_d(ctx); return result; } // Copy over the signature. if (!(output = st_import(ctx->signature->data, ctx->signature->length))) { log_pedantic("Could not import the statistical signature. {length = %lu}", ctx->signature->length); dspam_destroy_d(ctx); return result; } if (signature) { *signature = output; } // Destroy the context and return the result. dspam_destroy_d(ctx); return result; }
void net_packet_release(net_socket_t s, net_packet_t p) { pool_release(s->poolPackets, p); }