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 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 pool* pool_find(struct caml_heap_state* local, sizeclass sz) { pool* r; /* Hopefully we have a pool we can use directly */ r = local->avail_pools[sz]; if (r) return r; /* Otherwise, try to sweep until we find one */ while (!local->avail_pools[sz] && pool_sweep(local, &local->unswept_avail_pools[sz], sz)); while (!local->avail_pools[sz] && pool_sweep(local, &local->unswept_full_pools[sz], sz)); r = local->avail_pools[sz]; if (r) return r; /* Failing that, we need to allocate a new pool */ r = pool_acquire(local); if (!r) return 0; /* if we can't allocate, give up */ local->stats.pool_words += POOL_WSIZE; if (local->stats.pool_words > local->stats.pool_max_words) local->stats.pool_max_words = local->stats.pool_words; local->stats.pool_frag_words += POOL_HEADER_WSIZE + wastage_sizeclass[sz]; /* Having allocated a new pool, set it up for size sz */ local->avail_pools[sz] = r; r->next = 0; r->owner = local->owner; r->next_obj = 0; r->sz = sz; mlsize_t wh = wsize_sizeclass[sz]; value* p = (value*)((char*)r + POOL_HEADER_SZ); value* end = (value*)((char*)r + Bsize_wsize(POOL_WSIZE)); while (p + wh <= end) { p[0] = 0; /* zero header indicates free object */ p[1] = (value)r->next_obj; r->next_obj = p; p += wh; } return r; }
int bacstack_session_get_message(bacstack_session_t *session, bacstack_message_t **message) { return pool_acquire(&session->message_pool, (void**)message); }