From 5edf38a6cbe9a3f3785bf4cba0648a96a61030a1 Mon Sep 17 00:00:00 2001 From: lotodore Date: Sun, 30 Sep 2007 13:15:52 +0000 Subject: [PATCH] Fixed some msvc problems with libircclient. Fixed auto start boost timer issue. Fixed irc thread termination (this time for real). Using strdup and free on MSVC causes "heap corruption error" in debug mode - use _strdup instead in libircclient. --- src/core/boost/timers.hpp | 1 + src/core/libircclient/include/libircclient.h | 2 +- src/core/libircclient/src/libircclient.c | 6 +++ src/core/libircclient/src/portable.c | 2 +- src/net/common/clientstate.cpp | 1 - src/net/common/ircthread.cpp | 49 ++++++++++++++++++-- src/net/common/receiverhelper.cpp | 4 ++ src/net/common/servergamestate.cpp | 1 + src/net/common/serverlobbythread.cpp | 1 - src/net/genericsocket.h | 1 - src/net/ircthread.h | 5 +- src/net/receiverhelper.h | 2 - src/net/socket_helper.h | 2 + src/playerdata.cpp | 4 +- src/session.cpp | 2 +- 15 files changed, 69 insertions(+), 14 deletions(-) diff --git a/src/core/boost/timers.hpp b/src/core/boost/timers.hpp index c80b8913..2743b56a 100644 --- a/src/core/boost/timers.hpp +++ b/src/core/boost/timers.hpp @@ -13,6 +13,7 @@ // Speeds up compilation a bit on msvc #if (defined _MSC_VER) && (_MSC_VER >= 1200) #pragma once +#define _WINSOCKAPI_ #endif #include diff --git a/src/core/libircclient/include/libircclient.h b/src/core/libircclient/include/libircclient.h index 82bff5c7..051d7fb3 100644 --- a/src/core/libircclient/include/libircclient.h +++ b/src/core/libircclient/include/libircclient.h @@ -49,7 +49,7 @@ #include /* fd_set */ #include /* sockaddr_in */ #else - #include + #include #endif #ifdef __cplusplus diff --git a/src/core/libircclient/src/libircclient.c b/src/core/libircclient/src/libircclient.c index 453bb41d..39bc3cc2 100644 --- a/src/core/libircclient/src/libircclient.c +++ b/src/core/libircclient/src/libircclient.c @@ -14,6 +14,7 @@ * $Id: libircclient.c 42 2004-10-10 16:16:15Z gyunaev $ */ + #include "portable.c" #include "sockets.c" @@ -25,6 +26,11 @@ #include "colors.c" #include "dcc.c" +#ifdef _MSC_VER + #undef strdup + #define strdup _strdup +#endif + #define IS_DEBUG_ENABLED(s) ((s)->option & LIBIRC_OPTION_DEBUG) diff --git a/src/core/libircclient/src/portable.c b/src/core/libircclient/src/portable.c index bbc46258..fc44e767 100644 --- a/src/core/libircclient/src/portable.c +++ b/src/core/libircclient/src/portable.c @@ -42,8 +42,8 @@ #endif #endif #else + #include #include - #include #include #include #include diff --git a/src/net/common/clientstate.cpp b/src/net/common/clientstate.cpp index e0348ecc..97e83c23 100644 --- a/src/net/common/clientstate.cpp +++ b/src/net/common/clientstate.cpp @@ -249,7 +249,6 @@ ClientStateStartConnect::Process(ClientThread &client) if (errCode == SOCKET_ERR_WOULDBLOCK) { boost::timers::portable::microsec_timer connectTimer; - connectTimer.start(); ClientStateConnecting::Instance().SetTimer(connectTimer); client.SetState(ClientStateConnecting::Instance()); retVal = MSG_SOCK_INTERNAL_PENDING; diff --git a/src/net/common/ircthread.cpp b/src/net/common/ircthread.cpp index 1e2581ed..1ea732a3 100644 --- a/src/net/common/ircthread.cpp +++ b/src/net/common/ircthread.cpp @@ -19,12 +19,15 @@ #include +#include #include #include #include using namespace std; +#define IRC_WAIT_TERMINATION_MSEC 500 + struct IrcContext { IrcContext(IrcThread &t) : ircThread(t), session(NULL), serverPort(0) {} @@ -137,7 +140,7 @@ irc_event_numeric(irc_session_t * session, unsigned irc_event, const char *origi } IrcThread::IrcThread(IrcCallback &callback) -: m_callback(callback) +: m_callback(callback), m_terminationTimer(boost::posix_time::time_duration(0, 0, 0), boost::timers::portable::microsec_timer::manual_start) { m_context.reset(new IrcContext(*this)); } @@ -212,14 +215,54 @@ void IrcThread::Main() { IrcContext &context = GetContext(); + irc_session_t *s = context.session; if (s) { if (irc_connect(s, context.serverAddress.c_str(), context.serverPort, 0, context.nick.c_str(), 0, 0) == 0) { - if (!ShouldTerminate()) - irc_run(s); + // Main loop. + while (irc_is_connected(s)) + { + // Handle thread termination - gracefully. + if (!m_terminationTimer.is_running()) + { + if (ShouldTerminate()) + m_terminationTimer.start(); + } + else + { + if (m_terminationTimer.elapsed().total_milliseconds() > IRC_WAIT_TERMINATION_MSEC) + break; + } + + struct timeval timeout; + fd_set readSet, writeSet; + int maxfd = 0; + + + FD_ZERO(&readSet); + FD_ZERO(&writeSet); + timeout.tv_sec = 0; + timeout.tv_usec = RECV_TIMEOUT_MSEC * 1000; + + irc_add_select_descriptors(s, &readSet, &writeSet, &maxfd); + + int selectResult = select(maxfd + 1, &readSet, &writeSet, 0, &timeout); + if (!IS_VALID_SELECT(selectResult)) + { + //todo + break; + } + + if (irc_process_select_descriptors(s, &readSet, &writeSet) != 0) + { + //todo + break; + } + } } + irc_destroy_session(s); } } diff --git a/src/net/common/receiverhelper.cpp b/src/net/common/receiverhelper.cpp index b745b049..8557158e 100644 --- a/src/net/common/receiverhelper.cpp +++ b/src/net/common/receiverhelper.cpp @@ -17,6 +17,10 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +#ifdef _WIN32 + #define FD_SETSIZE 512 +#endif + #include #include #include diff --git a/src/net/common/servergamestate.cpp b/src/net/common/servergamestate.cpp index 6590fda1..06f2812c 100644 --- a/src/net/common/servergamestate.cpp +++ b/src/net/common/servergamestate.cpp @@ -190,6 +190,7 @@ AbstractServerGameStateReceiving::Process(ServerGameThread &server) //----------------------------------------------------------------------------- AbstractServerGameStateTimer::AbstractServerGameStateTimer() +: m_timer(boost::posix_time::time_duration(0, 0, 0), boost::timers::portable::microsec_timer::manual_start) { } diff --git a/src/net/common/serverlobbythread.cpp b/src/net/common/serverlobbythread.cpp index c4df5dcf..5f45d08b 100644 --- a/src/net/common/serverlobbythread.cpp +++ b/src/net/common/serverlobbythread.cpp @@ -120,7 +120,6 @@ ServerLobbyThread::CloseSessionDelayed(SessionWrapper session) m_gameSessionManager.RemoveSession(session.sessionData->GetSocket()); boost::timers::portable::microsec_timer closeTimer; - closeTimer.start(); CloseSessionList::value_type closeSessionData(closeTimer, session.sessionData); boost::mutex::scoped_lock lock(m_closeSessionListMutex); diff --git a/src/net/genericsocket.h b/src/net/genericsocket.h index 32cdc071..0c8a06bf 100644 --- a/src/net/genericsocket.h +++ b/src/net/genericsocket.h @@ -21,7 +21,6 @@ #define _GENERICSOCKET_H_ #ifdef _WIN32 -#define FD_SETSIZE 512 #include #include #else diff --git a/src/net/ircthread.h b/src/net/ircthread.h index 89d99810..151974aa 100644 --- a/src/net/ircthread.h +++ b/src/net/ircthread.h @@ -23,6 +23,7 @@ #include #include +#include #include struct IrcContext; @@ -52,8 +53,10 @@ protected: IrcContext &GetContext(); private: - std::auto_ptr m_context; + boost::shared_ptr m_context; IrcCallback &m_callback; + + boost::timers::portable::microsec_timer m_terminationTimer; }; #endif diff --git a/src/net/receiverhelper.h b/src/net/receiverhelper.h index f0387313..131993de 100644 --- a/src/net/receiverhelper.h +++ b/src/net/receiverhelper.h @@ -28,8 +28,6 @@ #include #include -#define RECV_TIMEOUT_MSEC 50 - class ReceiverHelper { public: diff --git a/src/net/socket_helper.h b/src/net/socket_helper.h index 8a9c3617..87ae2a57 100644 --- a/src/net/socket_helper.h +++ b/src/net/socket_helper.h @@ -69,6 +69,8 @@ typedef unsigned char u_char; #define IS_VALID_SEND(_s) ((_s) != SOCKET_ERROR) #define IS_VALID_SELECT(_s) ((_s) != SOCKET_ERROR) +#define RECV_TIMEOUT_MSEC 50 + #ifdef IPPROTO_SCTP #define SOCKET_IPPROTO_SCTP IPPROTO_SCTP #else diff --git a/src/playerdata.cpp b/src/playerdata.cpp index a7fb0f1a..0840d237 100644 --- a/src/playerdata.cpp +++ b/src/playerdata.cpp @@ -66,14 +66,14 @@ PlayerData::SetAvatarFile(const std::string &avatarFile) boost::shared_ptr PlayerData::GetNetSessionData() const { - boost::mutex::scoped_lock lock(m_dataMutex); + // setting/getting boost::shared_ptr is thread safe. return m_netSessionData; } void PlayerData::SetNetSessionData(boost::shared_ptr session) { - boost::mutex::scoped_lock lock(m_dataMutex); + // setting/getting boost::shared_ptr is thread safe. m_netSessionData = session; } diff --git a/src/session.cpp b/src/session.cpp index 4f0bf83f..d9e560bf 100755 --- a/src/session.cpp +++ b/src/session.cpp @@ -32,7 +32,7 @@ #define NET_CLIENT_TERMINATE_TIMEOUT_MSEC 1000 #define NET_SERVER_TERMINATE_TIMEOUT_MSEC 2000 -#define NET_IRC_TERMINATE_TIMEOUT_MSEC 5000 +#define NET_IRC_TERMINATE_TIMEOUT_MSEC 2000 #define NET_DEFAULT_GAME "default"