diff --git a/pokerth_game.pro b/pokerth_game.pro index de64d441..5bcd54e3 100644 --- a/pokerth_game.pro +++ b/pokerth_game.pro @@ -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 \ diff --git a/pokerth_lib.pro b/pokerth_lib.pro index 6c4234fc..d00a8b52 100644 --- a/pokerth_lib.pro +++ b/pokerth_lib.pro @@ -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 diff --git a/src/net/chatcleanermanager.h b/src/net/chatcleanermanager.h index 8eac1540..1e46ea2f 100644 --- a/src/net/chatcleanermanager.h +++ b/src/net/chatcleanermanager.h @@ -27,7 +27,7 @@ #include #include -class EncodedPacket; +class SendDataManager; class ChatCleanerManager : public boost::enable_shared_from_this { @@ -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 tmpPacket); void HandleRead(const boost::system::error_code &ec, size_t bytesRead); bool HandleMessage(InternalChatCleanerPacket &msg); @@ -58,6 +57,7 @@ private: boost::shared_ptr m_ioService; boost::shared_ptr m_resolver; boost::shared_ptr m_socket; + boost::shared_ptr m_sendManager; bool m_connected; unsigned m_curRequestId; diff --git a/src/net/common/chatcleanermanager.cpp b/src/net/common/chatcleanermanager.cpp index 9b6eda67..7bc9f6a4 100644 --- a/src/net/common/chatcleanermanager.cpp +++ b/src/net/common/chatcleanermanager.cpp @@ -18,7 +18,7 @@ ***************************************************************************/ #include -#include +#include #include #include #include @@ -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 /*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 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); } } diff --git a/src/net/common/encodedpacket.cpp b/src/net/common/encodedpacket.cpp deleted file mode 100644 index bc9827fc..00000000 --- a/src/net/common/encodedpacket.cpp +++ /dev/null @@ -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 -#include - -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; -} - diff --git a/src/net/common/senddatamanager.cpp b/src/net/common/senddatamanager.cpp new file mode 100644 index 00000000..5c1c544d --- /dev/null +++ b/src/net/common/senddatamanager.cpp @@ -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 +#include + +#include +#include + +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 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 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; +} + diff --git a/src/net/common/senderhelper.cpp b/src/net/common/senderhelper.cpp index f903a315..2e51c339 100644 --- a/src/net/common/senderhelper.cpp +++ b/src/net/common/senderhelper.cpp @@ -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 -#include -#include -#include - #include +#include #include #include #include @@ -31,108 +27,6 @@ #include 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 -{ -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 socket, const boost::system::error_code &error); - - void AsyncSendNextPacket(boost::shared_ptr 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 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 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 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 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); diff --git a/src/net/encodedpacket.h b/src/net/encodedpacket.h deleted file mode 100644 index 60e669c0..00000000 --- a/src/net/encodedpacket.h +++ /dev/null @@ -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 - diff --git a/src/net/senddatamanager.h b/src/net/senddatamanager.h new file mode 100644 index 00000000..1203379c --- /dev/null +++ b/src/net/senddatamanager.h @@ -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 +#include +#include +#include + + +#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 +{ +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 socket, const boost::system::error_code &error); + void AsyncSendNextPacket(boost::shared_ptr 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 +