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"