예제 #1
0
파일: bundle.cpp 프로젝트: aabbox/kbengine
//-------------------------------------------------------------------------------------
bool Bundle::revokeMessage(int32 size)
{
	if(pCurrPacket_)
	{
		if(size >= (int32)pCurrPacket_->wpos())
		{
			size -= pCurrPacket_->wpos();
			RECLAIM_PACKET(isTCPPacket_, pCurrPacket_);
			pCurrPacket_ = NULL;
		}
		else
		{
			pCurrPacket_->wpos(pCurrPacket_->wpos() - size);
			size = 0;
		}
	}
	
	while(size > 0 && packets_.size() > 0)
	{
		Network::Packet* pPacket = packets_.back();
		if(pPacket->wpos() > (size_t)size)
		{
			pPacket->wpos(pPacket->wpos() - size);
			size = 0;
			break;
		}
		else
		{
			size -= pPacket->wpos();
			RECLAIM_PACKET(isTCPPacket_, pPacket);
			packets_.pop_back();
		}
	}
	
	if (pCurrPacket_)
	{
		packets_.push_back(pCurrPacket_);
		pCurrPacket_ = NULL;
	}

	--numMessages_;
	currMsgHandlerLength_ = 0;
		
	currMsgID_ = 0;
	currMsgPacketCount_ = 0;
	currMsgLength_ = 0;
	currMsgLengthPos_ = 0;
	pCurrMsgHandler_ = NULL;

	return size == 0;
}
예제 #2
0
//-------------------------------------------------------------------------------------
void Bundle::clear(bool isRecl)
{
	if(pCurrPacket_ != NULL)
	{
		packets_.push_back(pCurrPacket_);
		pCurrPacket_ = NULL;
	}

	Packets::iterator iter = packets_.begin();
	for (; iter != packets_.end(); ++iter)
	{
		if(!isRecl)
		{
			delete (*iter);
		}
		else
		{
			RECLAIM_PACKET(isTCPPacket_, (*iter));
		}
	}
	
	packets_.clear();

	pChannel_ = NULL;
	numMessages_ = 0;

	currMsgID_ = 0;
	currMsgPacketCount_ = 0;
	currMsgLength_ = 0;
	currMsgLengthPos_ = 0;
	currMsgHandlerLength_ = 0;
	pCurrMsgHandler_ = NULL;
	_calcPacketMaxSize();
}
예제 #3
0
//-------------------------------------------------------------------------------------
void Bundle::clearPackets()
{
	if(pCurrPacket_ != NULL)
	{
		packets_.push_back(pCurrPacket_);
		pCurrPacket_ = NULL;
	}

	Packets::iterator iter = packets_.begin();
	for (; iter != packets_.end(); ++iter)
	{
		RECLAIM_PACKET(isTCPPacket_, (*iter));
	}

	packets_.clear();
}
예제 #4
0
//-------------------------------------------------------------------------------------
bool TCPPacketSender::processSend(Channel* pChannel)
{
	bool noticed = pChannel == NULL;

	// 如果是有poller通知的,我们需要通过地址找到channel
	if(noticed)
		pChannel = getChannel();

	KBE_ASSERT(pChannel != NULL);
	
	if(pChannel->isCondemn())
	{
		return false;
	}
	
	Channel::Bundles& bundles = pChannel->bundles();
	Reason reason = REASON_SUCCESS;

	Channel::Bundles::iterator iter = bundles.begin();
	for(; iter != bundles.end(); ++iter)
	{
		Bundle::Packets& pakcets = (*iter)->packets();
		Bundle::Packets::iterator iter1 = pakcets.begin();
		for (; iter1 != pakcets.end(); ++iter1)
		{
			reason = processPacket(pChannel, (*iter1));
			if(reason != REASON_SUCCESS)
				break; 
			else
				RECLAIM_PACKET((*iter)->isTCPPacket(), (*iter1));
		}

		if(reason == REASON_SUCCESS)
		{
			pakcets.clear();
			Network::Bundle::ObjPool().reclaimObject((*iter));
		}
		else
		{
			pakcets.erase(pakcets.begin(), iter1);
			bundles.erase(bundles.begin(), iter);

			if (reason == REASON_RESOURCE_UNAVAILABLE)
			{
				/* 此处输出可能会造成debugHelper处死锁
					WARNING_MSG(fmt::format("TCPPacketSender::processSend: "
						"Transmit queue full, waiting for space(kbengine.xml->channelCommon->writeBufferSize->{})...\n",
						(pChannel->isInternal() ? "internal" : "external")));
				*/

				this->dispatcher().errorReporter().reportException(reason, pEndpoint_->addr());
			}
			else
			{
				this->dispatcher().errorReporter().reportException(reason, pEndpoint_->addr());
				onGetError(pChannel);
			}

			return false;
		}
	}

	bundles.clear();

	if(noticed)
		pChannel->onSendCompleted();

	return true;
}
예제 #5
0
bool TCPPacketSender::processSend(Channel* pChannel)
{
	bool noticed = pChannel == NULL;

	//如果由poller通知的,我們需要通過地址找到channel
	if(noticed)
	{
		pChannel = getChannel();
	}

	SLASSERT(pChannel != NULL, "wtf");

	if(pChannel->isCondemn())
	{
		return false;
	}

	if(!pChannel->isConnected()){
		return false;
	}

	Channel::Bundles& bundles = pChannel->bundles();
	Reason reason = REASON_SUCCESS;

	Channel::Bundles::iterator iter = bundles.begin();
	for (; iter != bundles.end(); ++iter)
	{
		Bundle::Packets& packets = (*iter)->packets();
		Bundle::Packets::iterator iter1 = packets.begin();
		for (; iter1 != packets.end(); ++iter1)
		{
			reason = processPacket(pChannel, (*iter1));
			if(reason != REASON_SUCCESS)
				break;
			else
			{
				RECLAIM_PACKET((*iter)->isTCPPacket(), (*iter1));
			}
		}

		if(reason == REASON_SUCCESS)
		{
			packets.clear();
			RELEASE_POOL_OBJECT(Bundle, *iter);
		}
		else
		{
			packets.erase(packets.begin(), iter1);
			bundles.erase(bundles.begin(), iter);

			if(reason == REASON_RESOURCE_UNAVAILABLE)
			{

			}
			else
			{
				onGetError(pChannel);
			}
			return false;
		}
	}
	bundles.clear();

	if(noticed)
		pChannel->onSendCompleted();

	return true;

}