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:
lotodore
2011-02-18 19:22:44 +00:00
parent 46a136bc8b
commit db3fa66ec5
9 changed files with 194 additions and 236 deletions
+2 -1
View File
@@ -195,7 +195,8 @@ HEADERS += src/game.h \
src/gui/qt/internetgamelogindialog/internetgamelogindialogimpl.h \
src/engine/local_engine/replay.h \
src/gui/qt/gamelobbydialog/mynicklistsortfilterproxymodel.h \
src/gui/qt/gametable/myslider.h
src/gui/qt/gametable/myslider.h \
src/net/senddatamanager.h
FORMS += src/gui/qt/gametable.ui \
src/gui/qt/aboutpokerth.ui \
src/gui/qt/connecttoserverdialog.ui \
+2 -3
View File
@@ -104,7 +104,6 @@ HEADERS += \
src/net/uploadhelper.h \
src/net/downloaderthread.h \
src/net/downloadhelper.h \
src/net/encodedpacket.h \
src/net/internalchatcleanerpacket.h \
src/third_party/libircclient/include/libircclient.h \
src/third_party/libircclient/include/config.h \
@@ -208,10 +207,10 @@ SOURCES += \
src/net/common/transferhelper.cpp \
src/net/common/uploaderthread.cpp \
src/net/common/uploadhelper.cpp \
src/net/common/encodedpacket.cpp \
src/net/common/internalchatcleanerpacket.cpp \
src/gui/generic/serverguiwrapper.cpp \
src/gui/qttoolsinterface.cpp
src/gui/qttoolsinterface.cpp \
src/net/common/senddatamanager.cpp
official_server{
INCLUDEPATH += pkth_stat/daemon_lib/src
+2 -2
View File
@@ -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;
+5 -25
View File
@@ -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);
}
}
-36
View File
@@ -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;
}
+90
View File
@@ -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;
}
+3 -124
View File
@@ -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);
-45
View File
@@ -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
+90
View File
@@ -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