void tlibc_hash_remove(tlibc_hash_t *self, tlibc_hash_head_t *ele) { if(ele->key_index < self->size) { tlibc_hash_bucket_t *bucket = &self->buckets[ele->key_index]; tlibc_list_del(&ele->data_list); --bucket->data_list_num; if(bucket->data_list_num == 0) { tlibc_list_del(&bucket->used_bucket_list); --self->used_bucket_list_num; } } }
tlibc_error_code_t tconnd_epool_proc() { int i; tlibc_error_code_t ret = E_TLIBC_WOULD_BLOCK; tlibc_list_head_t *iter, *next; if(tlibc_list_empty(&readable_list)) { struct epoll_event events[TCONND_EPOLL_MAX_EVENTS]; int events_num; events_num = epoll_wait(g_epollfd, events, TCONND_EPOLL_MAX_EVENTS, 0); if(events_num == -1) { //有可能被时钟打断 if(errno == EINTR) { ret = E_TLIBC_NOERROR; goto done; } ERROR_LOG("epoll_wait errno[%d], %s.", errno, strerror(errno)); ret = E_TLIBC_ERRNO; goto done; } for(i = 0; i < events_num; ++i) { tconnd_epoll_data_type_t *etype = events[i].data.ptr; if(*etype == e_ted_socket) { tconnd_socket_t *socket = TLIBC_CONTAINER_OF(etype, tconnd_socket_t, etype); if(socket->readable) { ERROR_LOG("socket [%u, %"PRIu64"] already readable.", socket->id, socket->mempool_entry.sn); assert(0); ret = E_TLIBC_ERROR; goto done; } socket->readable = true; tlibc_list_init(&socket->readable_list); tlibc_list_add_tail(&socket->readable_list, &readable_list); } else if(*etype == e_ted_timer) { tconnd_timer_on_tick(); ret = E_TLIBC_NOERROR; } } } if(tlibc_list_empty(&readable_list)) { ret = E_TLIBC_WOULD_BLOCK; goto done; } for(iter = readable_list.next; iter != &readable_list; iter = next) { tlibc_error_code_t r; tconnd_socket_t *socket = TLIBC_CONTAINER_OF(iter, tconnd_socket_t, readable_list); next = iter->next; if(socket == &g_listen) { r = tconnd_listen(); } else { r = tconnd_socket_recv(socket); } switch(r) { case E_TLIBC_NOERROR: ret = E_TLIBC_NOERROR; break; case E_TLIBC_TBUS_NOT_ENOUGH_SPACE: ret = E_TLIBC_WOULD_BLOCK; goto done; case E_TLIBC_TOO_MANY_SOCKET: break; case E_TLIBC_WOULD_BLOCK: break; case E_TLIBC_ERRNO: switch(errno) { case EAGAIN: socket->readable = false; tlibc_list_del(iter); break; case EINTR: break; default: ret = E_TLIBC_ERRNO; goto done; } break; case E_TLIBC_NO_MEMORY: { tconnd_socket_t *sock = NULL; if(tlibc_list_empty(&g_package_socket_list)) { ret = E_TLIBC_NO_MEMORY; ERROR_LOG("Not enough package buff."); break; } sock = TLIBC_CONTAINER_OF(g_package_socket_list.next, tconnd_socket_t, g_package_socket_list); assert(sock->package_buff != NULL); WARN_LOG("close socket [%u, %"PRIu64"] to release package buff.", sock->id, sock->mempool_entry.sn); tconnd_socket_delete(sock); } break; case E_TLIBC_CLOSE: tconnd_socket_delete(socket); break; default: ret = r; goto done; } } done: return ret; }
void tlibc_timer_pop(tlibc_timer_entry_t *self) { tlibc_list_del(&self->entry); }
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; }