tlibc_error_code_t tbusapi_process(tbusapi_t *self) { tlibc_error_code_t ret = E_TLIBC_NOERROR; size_t iov_num = self->iov_num; tbus_atomic_size_t tbus_head = tbus_read_begin(self->itb, self->iov, &iov_num); if(iov_num == 0) { if(tbus_head != self->itb->head_offset) { goto read_end; } else { ret = E_TLIBC_WOULD_BLOCK; goto done; } } if(self->on_recviov) { uint16_t pos = self->on_recviov(self, self->iov, (uint16_t)iov_num); if(pos < iov_num) { tbus_head = tbus_packet2offset(self->itb, self->iov[pos].iov_base); } if(pos == 0) { ret = E_TLIBC_WOULD_BLOCK; } } read_end: tbus_read_end(self->itb, tbus_head); done: return ret; }
tlibc_error_code_t process_input_tbus() { tlibc_error_code_t ret = E_TLIBC_NOERROR; struct iovec iov[TCONND_IOV_NUM]; size_t iov_num; tlibc_list_head_t writable_list; tlibc_list_head_t *iter; tbus_atomic_size_t tbus_head; size_t iov_index; tlibc_list_init(&writable_list); iov_num = TCONND_IOV_NUM; tbus_head = tbus_read_begin(g_input_tbus, iov, &iov_num); if(iov_num == 0) { if(tbus_head == g_input_tbus->head_offset) { ret = E_TLIBC_WOULD_BLOCK; } goto read_end; } for(iov_index = 0; iov_index < iov_num; ++iov_index) { uint32_t i; const sip_rsp_t *head = NULL; size_t head_size = 0; char* body_addr = NULL; size_t body_size = 0; head = (const sip_rsp_t*)iov[iov_index].iov_base; head_size = SIZEOF_SIP_RSP_T(head); if(iov[iov_index].iov_len < head_size) { ERROR_LOG("can not decode sip_rst_t."); goto flush_socket; } if(head->cmd == e_sip_rsp_cmd_send) { body_size = head->size; body_addr = (char*)iov[iov_index].iov_base + head_size; if(head_size + body_size > iov[iov_index].iov_len) { ERROR_LOG("sip_rst_t.size out of range."); goto flush_socket; } } else { body_addr = NULL; body_size = 0; } for(i = 0; i < head->cid_list_num; ++i) { tconnd_socket_t *socket = NULL; if(i >= SIP_BROADCAST_NUM) { ERROR_LOG("cid [%u] >= SIP_BROADCAST_NUM [%u]", head->cid_list_num, SIP_BROADCAST_NUM); break; } if(!tlibc_mempool_id_test(&g_socket_pool, head->cid_list[i].id)) { DEBUG_LOG("head->cmd = %d [%u, %"PRIu64"] , head->cid_list[i].id[%u] > g_socket_pool->unit_num[%zu]." , head->cmd, head->cid_list[i].id, head->cid_list[i].sn, head->cid_list[i].id, g_socket_pool.unit_num); continue; } socket = (tconnd_socket_t*)tlibc_mempool_id2ptr(&g_socket_pool, head->cid_list[i].id); if(!tlibc_mempool_ptr_test(socket, mempool_entry, head->cid_list[i].sn)) { DEBUG_LOG("socket [%u, %"PRIu64"] head->cmd = %d [%u, %"PRIu64"] mismatch." , head->cid_list[i].id, socket->mempool_entry.sn, head->cmd, head->cid_list[i].id, head->cid_list[i].sn); continue; } if(tconnd_socket_push_pkg(socket, head, body_addr, body_size) == E_TLIBC_CLOSE) { if(socket->writable) { socket->writable = false; tlibc_list_del(&socket->writable_list); } tconnd_socket_delete(socket); } else { if(!socket->writable) { socket->writable = true; tlibc_list_add_tail(&socket->writable_list, &writable_list); } } } } flush_socket: for(iter = writable_list.next; iter != &writable_list; iter = iter->next) { tconnd_socket_t *socket = TLIBC_CONTAINER_OF(iter, tconnd_socket_t, writable_list); tlibc_error_code_t r = tconnd_socket_flush(socket); socket->writable = false; if(r == E_TLIBC_CLOSE) { tconnd_socket_delete(socket); } } read_end: tbus_read_end(g_input_tbus, tbus_head); return ret; }