Esempio n. 1
0
        void net_io::do_write()
        {
            auto msg = _sq.peek();
            if (nullptr == msg.get())
                return;

            std::vector<blob> buffers;
            _parser->prepare_buffers_for_send(msg, buffers);

            std::vector<boost::asio::const_buffer> buffers2;
            for (auto& b : buffers)
            {
                buffers2.push_back(boost::asio::const_buffer(b.data(), b.length()));
            }

            add_reference();
            boost::asio::async_write(_socket, buffers2,
                [this, msg](boost::system::error_code ec, std::size_t length)
            {
                if (!!ec)
                {
                    on_failure();
                }
                else
                {
                    auto smsg = _sq.dequeue_peeked();
                    dassert(smsg == msg, "sent msg must be the first msg in send queue");
                    //dinfo("network message sent, rpc_id = %016llx", msg->header().rpc_id);

                    do_write();
                }

                release_reference();
            });
        }
Esempio n. 2
0
        void net_io::do_read(size_t sz)
        {
            add_reference();

            void* ptr = _parser->read_buffer_ptr((int)sz);
            int remaining = _parser->read_buffer_capacity();

            _socket.async_read_some(boost::asio::buffer(ptr, remaining),
                [this](boost::system::error_code ec, std::size_t length)
            {
                if (!!ec)
                {
                    on_failure();
                }
                else
                {
                    int read_next;
                    message_ptr msg = _parser->get_message_on_receive((int)length, read_next);

                    while (msg != nullptr)
                    {
                        this->on_message_read(msg);
                        msg = _parser->get_message_on_receive(0, read_next);
                    }
                     
                    do_read(read_next);
                }

                release_reference();
            });
        }
Esempio n. 3
0
/*	===== tls_access_next ==========================================================
	PRIVATE. Get access to the next entry/exit structure.
		Loose access to the current entry/exit structure.
	================================================================================	*/
_tls_entry_exit_t* tls_access_next (_tls_entry_exit_t* pCurrent)
	{
	_tls_entry_exit_t* p ;

	if (!pCurrent) return NULL ;

	tls_entry_exit_mutex_p () ;
		{
		//	Get new reference on next.
		p = new_reference (pCurrent->next) ;
		//	Release reference on current.
		release_reference (pCurrent) ;
		}
	tls_entry_exit_mutex_v () ;

	return p ;
	}
Esempio n. 4
0
/*	===== tls_remove_entry_exit ====================================================
	PRIVATE. Find an existing entry/exit structure, and remove it.
	The proc AND the param must match.
	================================================================================	*/
status_t tls_remove_entry_exit (bool bEntry, tls_proc_t proc, int param)
	{
	_tls_entry_exit_t* p = NULL ;
	_tls_entry_exit_t** ppNext = &gm_entry_proc_list ;

	//	Check parameters.
	if (proc == NULL) return B_BAD_VALUE ;

	//	Remove structure from the right list.
	//	Note: list are processed IN the mutex zone, so we dont care of
	//		managing useCount values.
	tls_entry_exit_mutex_p () ;
		{
		if (bEntry)	// bEntry == PROC_ENTRY
			ppNext = &gm_entry_proc_list ;
		else		// bEntry == PROC_EXIT
			ppNext = &gm_exit_proc_list ;
		//	Find the structure.
		//	Use the welle known algorithm which use list pointer links
		//	address in place of value, to reach the last link address and
		//	be able to update it.
		while (*ppNext != NULL)
			{
			//	Check proc AND param.
			if ((*ppNext)->proc == proc && (*ppNext)->param == param)
				{
				//	Founded. Remove it from the list.
				p = *ppNext ;
				*ppNext = (*ppNext)->next ;
				p->next = NULL ;
				//	And delete it (if possible).
				release_reference (p) ;
				break ;
				}
			ppNext = &((*ppNext)->next) ;
			}
		}
	tls_entry_exit_mutex_v () ;

	//	Finish.
	if (p != NULL)
		return B_NO_ERROR ;
	else
		return B_ERROR ;
	}
Esempio n. 5
0
        void client_net_io::connect()
        {
            session_state closed_state = SS_CLOSED;

            if (_state.compare_exchange_strong(closed_state, SS_CONNECTING))
            {
                boost::asio::ip::tcp::endpoint ep(
                    boost::asio::ip::address_v4(ntohl(_remote_addr.ip)), _remote_addr.port);

                add_reference();
                _socket.async_connect(ep, [this](boost::system::error_code ec)
                {
                    if (!ec)
                    {
                        _reconnect_count = 0;
                        _state = SS_CONNECTED;

                        dinfo("client session %s:%d connected",
                            _remote_addr.name.c_str(),
                            static_cast<int>(_remote_addr.port)
                            );

                        set_options();

                        do_write();
                        do_read();                        
                    }
                    else
                    {
                        derror("network client session connect failed, error = %s",
                            ec.message().c_str()
                            );
                        on_failure();
                    }
                    release_reference();
                });
            }
        }