Place new send code in a separate class, and use it also for the chat cleaner communication. Data class "encoded packet" is no longer used, it was overhead.
This commit is contained in:
@@ -27,7 +27,7 @@
|
||||
#include <net/chatcleanercallback.h>
|
||||
#include <net/internalchatcleanerpacket.h>
|
||||
|
||||
class EncodedPacket;
|
||||
class SendDataManager;
|
||||
|
||||
class ChatCleanerManager : public boost::enable_shared_from_this<ChatCleanerManager>
|
||||
{
|
||||
@@ -45,7 +45,6 @@ protected:
|
||||
|
||||
void HandleResolve(const boost::system::error_code& ec, boost::asio::ip::tcp::resolver::iterator endpoint_iterator);
|
||||
void HandleConnect(const boost::system::error_code& ec, boost::asio::ip::tcp::resolver::iterator endpoint_iterator);
|
||||
void HandleWrite(const boost::system::error_code &ec, boost::shared_ptr<EncodedPacket> tmpPacket);
|
||||
void HandleRead(const boost::system::error_code &ec, size_t bytesRead);
|
||||
bool HandleMessage(InternalChatCleanerPacket &msg);
|
||||
|
||||
@@ -58,6 +57,7 @@ private:
|
||||
boost::shared_ptr<boost::asio::io_service> m_ioService;
|
||||
boost::shared_ptr<boost::asio::ip::tcp::resolver> m_resolver;
|
||||
boost::shared_ptr<boost::asio::ip::tcp::socket> m_socket;
|
||||
boost::shared_ptr<SendDataManager> m_sendManager;
|
||||
|
||||
bool m_connected;
|
||||
unsigned m_curRequestId;
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include <net/chatcleanermanager.h>
|
||||
#include <net/encodedpacket.h>
|
||||
#include <net/senddatamanager.h>
|
||||
#include <boost/bind.hpp>
|
||||
#include <core/loghelper.h>
|
||||
#include <third_party/asn1/ChatCleanerMessage.h>
|
||||
@@ -36,6 +36,8 @@ ChatCleanerManager::ChatCleanerManager(ChatCleanerCallback &cb, boost::shared_pt
|
||||
m_recvBuf[0] = 0;
|
||||
m_resolver.reset(
|
||||
new boost::asio::ip::tcp::resolver(*m_ioService));
|
||||
m_sendManager.reset(
|
||||
new SendDataManager);
|
||||
}
|
||||
|
||||
ChatCleanerManager::~ChatCleanerManager()
|
||||
@@ -159,18 +161,6 @@ ChatCleanerManager::HandleConnect(const boost::system::error_code& ec,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ChatCleanerManager::HandleWrite(const boost::system::error_code &ec,
|
||||
boost::shared_ptr<EncodedPacket> /*tmpPacket*/)
|
||||
{
|
||||
if (ec && ec != boost::asio::error::operation_aborted) {
|
||||
LOG_ERROR("Error sending message to chat cleaner.");
|
||||
boost::system::error_code ec;
|
||||
m_socket->close(ec);
|
||||
m_connected = false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ChatCleanerManager::HandleRead(const boost::system::error_code &ec, size_t bytesRead)
|
||||
{
|
||||
@@ -258,22 +248,12 @@ ChatCleanerManager::HandleMessage(InternalChatCleanerPacket &msg)
|
||||
void
|
||||
ChatCleanerManager::SendMessageToServer(InternalChatCleanerPacket &msg)
|
||||
{
|
||||
unsigned char buf[MAX_CLEANER_PACKET_SIZE];
|
||||
asn_enc_rval_t e = der_encode_to_buffer(&asn_DEF_ChatCleanerMessage, msg.GetMsg(), buf, MAX_CLEANER_PACKET_SIZE);
|
||||
asn_enc_rval_t e = der_encode(&asn_DEF_ChatCleanerMessage, msg.GetMsg(), &SendDataManager::EncodeToBuf, &m_sendManager);
|
||||
|
||||
if (e.encoded == -1)
|
||||
LOG_ERROR("Failed to encode chat cleaner packet: " << msg.GetMsg()->present);
|
||||
else {
|
||||
boost::shared_ptr<EncodedPacket> tmpPacket(new EncodedPacket(buf, e.encoded));
|
||||
// Actually, this should not be done (parallel async_write calls might break data).
|
||||
// But we do not want to create additional buffers here.
|
||||
boost::asio::async_write(
|
||||
*m_socket,
|
||||
boost::asio::buffer(tmpPacket->GetData(), tmpPacket->GetSize()),
|
||||
boost::bind(&ChatCleanerManager::HandleWrite,
|
||||
shared_from_this(),
|
||||
boost::asio::placeholders::error,
|
||||
tmpPacket));
|
||||
m_sendManager->AsyncSendNextPacket(m_socket);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2009 by Lothar May *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <net/encodedpacket.h>
|
||||
#include <cstring>
|
||||
|
||||
using namespace std;
|
||||
|
||||
EncodedPacket::EncodedPacket(const unsigned char *data, unsigned size)
|
||||
: m_size(size)
|
||||
{
|
||||
m_data = new unsigned char[size];
|
||||
memcpy(m_data, data, size);
|
||||
}
|
||||
|
||||
EncodedPacket::~EncodedPacket()
|
||||
{
|
||||
delete[] m_data;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2011 by Lothar May *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include <net/senddatamanager.h>
|
||||
#include <boost/swap.hpp>
|
||||
|
||||
using namespace std;
|
||||
using boost::asio::ip::tcp;
|
||||
|
||||
|
||||
SendDataManager::SendDataManager()
|
||||
: sendBuf(NULL), curWriteBuf(NULL), sendBufAllocated(0), sendBufUsed(0),
|
||||
curWriteBufAllocated(0), curWriteBufUsed(0)
|
||||
{
|
||||
}
|
||||
|
||||
SendDataManager::~SendDataManager()
|
||||
{
|
||||
free(sendBuf);
|
||||
free(curWriteBuf);
|
||||
}
|
||||
|
||||
void
|
||||
SendDataManager::HandleWrite(boost::shared_ptr<boost::asio::ip::tcp::socket> socket, const boost::system::error_code &error)
|
||||
{
|
||||
if (!error) {
|
||||
// Successfully sent the data.
|
||||
curWriteBufUsed = 0;
|
||||
// Send more data, if available.
|
||||
AsyncSendNextPacket(socket);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SendDataManager::AsyncSendNextPacket(boost::shared_ptr<boost::asio::ip::tcp::socket> socket)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(dataMutex);
|
||||
if (!curWriteBufUsed) {
|
||||
// Swap buffers and send data.
|
||||
boost::swap(curWriteBuf, sendBuf);
|
||||
boost::swap(curWriteBufAllocated, sendBufAllocated);
|
||||
boost::swap(curWriteBufUsed, sendBufUsed);
|
||||
if (curWriteBufUsed) {
|
||||
boost::asio::async_write(
|
||||
*socket,
|
||||
boost::asio::buffer(curWriteBuf, curWriteBufUsed),
|
||||
boost::bind(&SendDataManager::HandleWrite,
|
||||
shared_from_this(),
|
||||
socket,
|
||||
boost::asio::placeholders::error));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
SendDataManager::EncodeToBuf(const void *data, size_t size, void *arg)
|
||||
{
|
||||
SendDataManager *m = (SendDataManager *)arg;
|
||||
|
||||
// Realloc buffer if necessary.
|
||||
while (m->GetSendBufLeft() < size) {
|
||||
if (!m->ReallocSendBuf()) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
m->AppendToSendBufWithoutCheck((const char*)data, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2007-2009 by Lothar May *
|
||||
* Copyright (C) 2007-2011 by Lothar May *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
@@ -17,12 +17,8 @@
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/swap.hpp>
|
||||
|
||||
#include <net/senderhelper.h>
|
||||
#include <net/senddatamanager.h>
|
||||
#include <net/sendercallback.h>
|
||||
#include <net/socket_helper.h>
|
||||
#include <net/socket_msg.h>
|
||||
@@ -31,108 +27,6 @@
|
||||
#include <cassert>
|
||||
|
||||
using namespace std;
|
||||
using boost::asio::ip::tcp;
|
||||
|
||||
|
||||
#define SEND_BUF_FIRST_ALLOC_CHUNKSIZE 4096
|
||||
#define MAX_SEND_BUF_SIZE SEND_BUF_FIRST_ALLOC_CHUNKSIZE * 1000
|
||||
|
||||
|
||||
class SendDataManager : public boost::enable_shared_from_this<SendDataManager>
|
||||
{
|
||||
public:
|
||||
SendDataManager()
|
||||
: sendBuf(NULL), curWriteBuf(NULL), sendBufAllocated(0), sendBufUsed(0),
|
||||
curWriteBufAllocated(0), curWriteBufUsed(0)
|
||||
{
|
||||
}
|
||||
|
||||
~SendDataManager()
|
||||
{
|
||||
free(sendBuf);
|
||||
free(curWriteBuf);
|
||||
}
|
||||
|
||||
inline size_t GetSendBufLeft() const
|
||||
{
|
||||
int bytesLeft = sendBufAllocated - sendBufUsed;
|
||||
return bytesLeft < 0 ? (size_t)0 : (size_t)bytesLeft;
|
||||
}
|
||||
|
||||
inline size_t GetAllocated() const
|
||||
{
|
||||
return sendBufAllocated;
|
||||
}
|
||||
|
||||
inline bool ReallocSendBuf()
|
||||
{
|
||||
bool retVal = false;
|
||||
size_t allocAmount = sendBufAllocated * 2;
|
||||
if (0 == allocAmount) {
|
||||
allocAmount = (size_t)SEND_BUF_FIRST_ALLOC_CHUNKSIZE;
|
||||
}
|
||||
char *tempBuf = (char *)realloc(sendBuf, allocAmount);
|
||||
if (tempBuf) {
|
||||
sendBuf = tempBuf;
|
||||
sendBufAllocated = allocAmount;
|
||||
retVal = true;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
inline void AppendToSendBufWithoutCheck(const char *data, size_t size)
|
||||
{
|
||||
memcpy(sendBuf + sendBufUsed, data, size);
|
||||
sendBufUsed += size;
|
||||
}
|
||||
|
||||
void HandleWrite(boost::shared_ptr<boost::asio::ip::tcp::socket> socket, const boost::system::error_code &error);
|
||||
|
||||
void AsyncSendNextPacket(boost::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
||||
|
||||
mutable boost::mutex dataMutex;
|
||||
|
||||
private:
|
||||
char *sendBuf;
|
||||
char *curWriteBuf;
|
||||
size_t sendBufAllocated;
|
||||
size_t sendBufUsed;
|
||||
size_t curWriteBufAllocated;
|
||||
size_t curWriteBufUsed;
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
SendDataManager::HandleWrite(boost::shared_ptr<boost::asio::ip::tcp::socket> socket, const boost::system::error_code &error)
|
||||
{
|
||||
if (!error) {
|
||||
// Successfully sent the data.
|
||||
curWriteBufUsed = 0;
|
||||
// Send more data, if available.
|
||||
AsyncSendNextPacket(socket);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SendDataManager::AsyncSendNextPacket(boost::shared_ptr<boost::asio::ip::tcp::socket> socket)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(dataMutex);
|
||||
if (!curWriteBufUsed) {
|
||||
// Swap buffers and send data.
|
||||
boost::swap(curWriteBuf, sendBuf);
|
||||
boost::swap(curWriteBufAllocated, sendBufAllocated);
|
||||
boost::swap(curWriteBufUsed, sendBufUsed);
|
||||
if (curWriteBufUsed) {
|
||||
boost::asio::async_write(
|
||||
*socket,
|
||||
boost::asio::buffer(curWriteBuf, curWriteBufUsed),
|
||||
boost::bind(&SendDataManager::HandleWrite,
|
||||
shared_from_this(),
|
||||
socket,
|
||||
boost::asio::placeholders::error));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SenderHelper::SenderHelper(SenderCallback &cb, boost::shared_ptr<boost::asio::io_service> ioService)
|
||||
: m_callback(cb), m_ioService(ioService)
|
||||
@@ -213,25 +107,10 @@ SenderHelper::SignalSessionTerminated(unsigned sessionId)
|
||||
m_sendQueueMap.erase(pos);
|
||||
}
|
||||
|
||||
static int der_encode_to_buffer_cb(const void *data, size_t size, void *arg) {
|
||||
SendDataManager *m = (SendDataManager *)arg;
|
||||
|
||||
// Realloc buffer if necessary.
|
||||
while (m->GetSendBufLeft() < size) {
|
||||
if (!m->ReallocSendBuf()) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
m->AppendToSendBufWithoutCheck((const char*)data, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
SenderHelper::InternalStorePacket(SendDataManager &tmpManager, boost::shared_ptr<NetPacket> packet)
|
||||
{
|
||||
asn_enc_rval_t e = der_encode(&asn_DEF_PokerTHMessage, packet->GetMsg(), der_encode_to_buffer_cb, &tmpManager);
|
||||
asn_enc_rval_t e = der_encode(&asn_DEF_PokerTHMessage, packet->GetMsg(), &SendDataManager::EncodeToBuf, &tmpManager);
|
||||
//cerr << "OUT:" << endl << packet->ToString() << endl;
|
||||
if (e.encoded == -1)
|
||||
LOG_ERROR("Failed to encode NetPacket: " << packet->GetMsg()->present);
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2009 by Lothar May *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
/* PokerTH encoded packet. */
|
||||
|
||||
#ifndef _ENCODEDPACKET_H_
|
||||
#define _ENCODEDPACKET_H_
|
||||
|
||||
|
||||
class EncodedPacket
|
||||
{
|
||||
public:
|
||||
EncodedPacket(const unsigned char *data, unsigned size);
|
||||
~EncodedPacket();
|
||||
|
||||
unsigned GetSize() const {
|
||||
return m_size;
|
||||
}
|
||||
|
||||
const unsigned char *GetData() const {
|
||||
return m_data;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned m_size;
|
||||
unsigned char *m_data;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2011 by Lothar May *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
/* Manager for sending network data. */
|
||||
|
||||
#ifndef _SENDDATAMANAGER_H_
|
||||
#define _SENDDATAMANAGER_H_
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
#define SEND_BUF_FIRST_ALLOC_CHUNKSIZE 4096
|
||||
#define MAX_SEND_BUF_SIZE SEND_BUF_FIRST_ALLOC_CHUNKSIZE * 1000
|
||||
|
||||
|
||||
class SendDataManager : public boost::enable_shared_from_this<SendDataManager>
|
||||
{
|
||||
public:
|
||||
SendDataManager();
|
||||
~SendDataManager();
|
||||
|
||||
inline size_t GetSendBufLeft() const
|
||||
{
|
||||
int bytesLeft = sendBufAllocated - sendBufUsed;
|
||||
return bytesLeft < 0 ? (size_t)0 : (size_t)bytesLeft;
|
||||
}
|
||||
|
||||
inline size_t GetAllocated() const
|
||||
{
|
||||
return sendBufAllocated;
|
||||
}
|
||||
|
||||
inline bool ReallocSendBuf()
|
||||
{
|
||||
bool retVal = false;
|
||||
size_t allocAmount = sendBufAllocated * 2;
|
||||
if (0 == allocAmount) {
|
||||
allocAmount = (size_t)SEND_BUF_FIRST_ALLOC_CHUNKSIZE;
|
||||
}
|
||||
char *tempBuf = (char *)std::realloc(sendBuf, allocAmount);
|
||||
if (tempBuf) {
|
||||
sendBuf = tempBuf;
|
||||
sendBufAllocated = allocAmount;
|
||||
retVal = true;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
inline void AppendToSendBufWithoutCheck(const char *data, size_t size)
|
||||
{
|
||||
std::memcpy(sendBuf + sendBufUsed, data, size);
|
||||
sendBufUsed += size;
|
||||
}
|
||||
|
||||
void HandleWrite(boost::shared_ptr<boost::asio::ip::tcp::socket> socket, const boost::system::error_code &error);
|
||||
void AsyncSendNextPacket(boost::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
||||
|
||||
static int EncodeToBuf(const void *data, size_t size, void *arg);
|
||||
|
||||
mutable boost::mutex dataMutex;
|
||||
|
||||
private:
|
||||
char *sendBuf;
|
||||
char *curWriteBuf;
|
||||
size_t sendBufAllocated;
|
||||
size_t sendBufUsed;
|
||||
size_t curWriteBufAllocated;
|
||||
size_t curWriteBufUsed;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user