Пример #1
0
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;
		}
	}
}
Пример #2
0
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;
}
Пример #3
0
void tlibc_timer_pop(tlibc_timer_entry_t *self)
{
	tlibc_list_del(&self->entry);
}
Пример #4
0
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;
}