diff --git a/Sources/Plasma/NucleusLib/pnSimpleNet/CMakeLists.txt b/Sources/Plasma/NucleusLib/pnSimpleNet/CMakeLists.txt index 96491f39..77d60d72 100644 --- a/Sources/Plasma/NucleusLib/pnSimpleNet/CMakeLists.txt +++ b/Sources/Plasma/NucleusLib/pnSimpleNet/CMakeLists.txt @@ -2,7 +2,6 @@ include_directories("../../CoreLib") include_directories("../../NucleusLib") set(pnSimpleNet_HEADERS - Pch.h pnSimpleNet.h ) diff --git a/Sources/Plasma/NucleusLib/pnSimpleNet/Pch.h b/Sources/Plasma/NucleusLib/pnSimpleNet/Pch.h deleted file mode 100644 index 762562b8..00000000 --- a/Sources/Plasma/NucleusLib/pnSimpleNet/Pch.h +++ /dev/null @@ -1,54 +0,0 @@ -/*==LICENSE==* - -CyanWorlds.com Engine - MMOG client, server and tools -Copyright (C) 2011 Cyan Worlds, Inc. - -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 3 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, see . - -Additional permissions under GNU GPL version 3 section 7 - -If you modify this Program, or any covered work, by linking or -combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, -NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent -JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK -(or a modified version of those libraries), -containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, -PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG -JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the -licensors of this Program grant you additional -permission to convey the resulting work. Corresponding Source for a -non-source form of such a combination shall include the source code for -the parts of OpenSSL and IJG JPEG Library used as well as that of the covered -work. - -You can contact Cyan Worlds, Inc. by email legal@cyan.com - or by snail mail at: - Cyan Worlds, Inc. - 14617 N Newport Hwy - Mead, WA 99021 - -*==LICENSE==*/ -/***************************************************************************** -* -* $/Plasma20/Sources/Plasma/NucleusLib/pnSimpleNet/Pch.h -* -***/ - -#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSIMPLENET_PCH_H -#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnSimpleNet/Pch.h included more than once" -#endif -#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSIMPLENET_PCH_H - - -#include "pnSimpleNet.h" diff --git a/Sources/Plasma/NucleusLib/pnSimpleNet/pnSimpleNet.cpp b/Sources/Plasma/NucleusLib/pnSimpleNet/pnSimpleNet.cpp index 0743b003..be0986c9 100644 --- a/Sources/Plasma/NucleusLib/pnSimpleNet/pnSimpleNet.cpp +++ b/Sources/Plasma/NucleusLib/pnSimpleNet/pnSimpleNet.cpp @@ -45,9 +45,11 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com * ***/ -#include "Pch.h" -#pragma hdrstop +#include "pnSimpleNet.h" +#include "hsThread.h" +#include +#include /***************************************************************************** * @@ -56,35 +58,25 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com ***/ struct SimpleNetConn : AtomicRef { - LINK(SimpleNetConn) link; AsyncSocket sock; AsyncCancelId cancelId; - unsigned channelId; + uint32_t channelId; bool abandoned; struct ConnectParam * connectParam; SimpleNet_MsgHeader * oversizeMsg; - ARRAY(uint8_t) oversizeBuffer; - - ~SimpleNetConn () { - ASSERT(!link.IsLinked()); - } + ARRAY(uint8_t) oversizeBuffer; }; -struct SimpleNetChannel : AtomicRef, THashKeyVal { - HASHLINK(SimpleNetChannel) link; - +struct SimpleNetChannel : AtomicRef { FSimpleNetOnMsg onMsg; FSimpleNetOnError onError; - - LISTDECL(SimpleNetConn, link) conns; + uint32_t channelId; + std::list conns; - SimpleNetChannel (unsigned channel) - : THashKeyVal(channel) - { } + SimpleNetChannel (uint32_t channel) : channelId(channel) { } ~SimpleNetChannel () { - ASSERT(!link.IsLinked()); - ASSERT(!conns.Head()); + ASSERT(!conns.size()); } }; @@ -92,7 +84,7 @@ struct ConnectParam { SimpleNetChannel * channel; FSimpleNetOnConnect callback; void * param; - + ~ConnectParam () { if (channel) channel->DecRef(); @@ -107,15 +99,10 @@ struct ConnectParam { ***/ static bool s_running; -static CCritSect s_critsect; +static hsMutex s_critsect; static FSimpleNetQueryAccept s_queryAccept; static void * s_queryAcceptParam; - -static HASHTABLEDECL( - SimpleNetChannel, - THashKeyVal, - link -) s_channels; +static std::map s_channels; /***************************************************************************** @@ -128,13 +115,13 @@ static HASHTABLEDECL( static void NotifyConnSocketConnect (SimpleNetConn * conn) { conn->TransferRef("Connecting", "Connected"); - + conn->connectParam->callback( conn->connectParam->param, conn, kNetSuccess ); - + delete conn->connectParam; conn->connectParam = nil; } @@ -142,18 +129,21 @@ static void NotifyConnSocketConnect (SimpleNetConn * conn) { //============================================================================ static void NotifyConnSocketConnectFailed (SimpleNetConn * conn) { - s_critsect.Enter(); + s_critsect.Lock(); { - conn->link.Unlink(); + std::map::iterator it; + if ((it = s_channels.find(conn->channelId)) != s_channels.end()) { + it->second->conns.remove(conn); + } } - s_critsect.Leave(); + s_critsect.Unlock(); conn->connectParam->callback( conn->connectParam->param, nil, kNetErrConnectFailed ); - + delete conn->connectParam; conn->connectParam = nil; @@ -165,38 +155,44 @@ static void NotifyConnSocketConnectFailed (SimpleNetConn * conn) { static void NotifyConnSocketDisconnect (SimpleNetConn * conn) { bool abandoned; - SimpleNetChannel * channel; - s_critsect.Enter(); + SimpleNetChannel* channel = nil; + s_critsect.Lock(); { abandoned = conn->abandoned; - if (nil != (channel = s_channels.Find(conn->channelId))) + std::map::iterator it; + if ((it = s_channels.find(conn->channelId)) != s_channels.end()) { + channel = it->second; channel->IncRef(); - conn->link.Unlink(); + channel->conns.remove(conn); + } } - s_critsect.Leave(); - + s_critsect.Unlock(); + if (channel && !abandoned) { channel->onError(conn, kNetErrDisconnected); channel->DecRef(); } - + conn->DecRef("Connected"); } //============================================================================ static bool NotifyConnSocketRead (SimpleNetConn * conn, AsyncNotifySocketRead * read) { - SimpleNetChannel * channel; - s_critsect.Enter(); + SimpleNetChannel* channel = nil; + s_critsect.Lock(); { - if (nil != (channel = s_channels.Find(conn->channelId))) + std::map::iterator it; + if ((it = s_channels.find(conn->channelId)) != s_channels.end()) { + channel = it->second; channel->IncRef(); + } } - s_critsect.Leave(); - + s_critsect.Unlock(); + if (!channel) return false; - + bool result = true; const uint8_t * curr = read->buffer; @@ -208,19 +204,19 @@ static bool NotifyConnSocketRead (SimpleNetConn * conn, AsyncNotifySocketRead * unsigned spaceLeft = conn->oversizeMsg->messageBytes - conn->oversizeBuffer.Count(); unsigned copyBytes = min(spaceLeft, term - curr); conn->oversizeBuffer.Add(curr, copyBytes); - + curr += copyBytes; // Wait until we have received the entire message if (copyBytes != spaceLeft) break; - + // Dispatch oversize msg if (!channel->onMsg(conn, conn->oversizeMsg)) { result = false; break; } - + conn->oversizeBuffer.SetCount(0); continue; } @@ -231,23 +227,23 @@ static bool NotifyConnSocketRead (SimpleNetConn * conn, AsyncNotifySocketRead * SimpleNet_MsgHeader * msg = (SimpleNet_MsgHeader *) read->buffer; - // Sanity check message size + // Sanity check message size if (msg->messageBytes < sizeof(*msg)) { result = false; break; } - + // Handle oversized messages if (msg->messageBytes > kAsyncSocketBufferSize) { - + conn->oversizeBuffer.SetCount(msg->messageBytes); conn->oversizeMsg = (SimpleNet_MsgHeader *) conn->oversizeBuffer.Ptr(); - *conn->oversizeMsg = *msg; - + *conn->oversizeMsg = *msg; + curr += sizeof(*msg); continue; } - + // Wait until we have received the entire message const uint8_t * msgTerm = (const uint8_t *) curr + msg->messageBytes; if (msgTerm > term) @@ -263,7 +259,7 @@ static bool NotifyConnSocketRead (SimpleNetConn * conn, AsyncNotifySocketRead * // Return count of bytes we processed read->bytesProcessed = curr - read->buffer; - + channel->DecRef(); return result; } @@ -286,59 +282,62 @@ static bool AsyncNotifySocketProc ( const SimpleNet_ConnData & connect = *(const SimpleNet_ConnData *) listen->buffer; listen->bytesProcessed += sizeof(connect); - SimpleNetChannel * channel; - s_critsect.Enter(); + SimpleNetChannel* channel = nil; + s_critsect.Lock(); { - if (nil != (channel = s_channels.Find(connect.channelId))) + std::map::iterator it; + if ((it = s_channels.find(conn->channelId)) != s_channels.end()) { + channel = it->second; channel->IncRef(); + } } - s_critsect.Leave(); - + s_critsect.Unlock(); + if (!channel) break; - + conn = NEWZERO(SimpleNetConn); - conn->channelId = channel->GetValue(); + conn->channelId = channel->channelId; conn->IncRef("Lifetime"); conn->IncRef("Connected"); conn->sock = sock; *userState = conn; - + bool accepted = s_queryAccept( s_queryAcceptParam, - channel->GetValue(), + channel->channelId, conn, listen->remoteAddr ); - + if (!accepted) { SimpleNetDisconnect(conn); } else { - s_critsect.Enter(); + s_critsect.Lock(); { - channel->conns.Link(conn); + channel->conns.push_back(conn); } - s_critsect.Leave(); + s_critsect.Unlock(); } - + channel->DecRef(); } break; - + case kNotifySocketConnectSuccess: { conn = (SimpleNetConn *) notify->param; *userState = conn; bool abandoned; - - s_critsect.Enter(); + + s_critsect.Lock(); { conn->sock = sock; conn->cancelId = 0; abandoned = conn->abandoned; } - s_critsect.Leave(); - + s_critsect.Unlock(); + if (abandoned) AsyncSocketDisconnect(sock, true); else @@ -349,17 +348,20 @@ static bool AsyncNotifySocketProc ( case kNotifySocketConnectFailed: conn = (SimpleNetConn *) notify->param; NotifyConnSocketConnectFailed(conn); - break; + break; case kNotifySocketDisconnect: conn = (SimpleNetConn *) *userState; NotifyConnSocketDisconnect(conn); - break; + break; case kNotifySocketRead: conn = (SimpleNetConn *) *userState; result = NotifyConnSocketRead(conn, (AsyncNotifySocketRead *) notify); - break; + break; + + default: + break; } return result; @@ -369,15 +371,15 @@ static bool AsyncNotifySocketProc ( static void Connect (const NetAddress & addr, ConnectParam * cp) { SimpleNetConn * conn = NEWZERO(SimpleNetConn); - conn->channelId = cp->channel->GetValue(); + conn->channelId = cp->channel->channelId; conn->connectParam = cp; conn->IncRef("Lifetime"); conn->IncRef("Connecting"); - s_critsect.Enter(); + s_critsect.Lock(); { - cp->channel->conns.Link(conn); - + cp->channel->conns.push_back(conn); + SimpleNet_Connect connect; connect.hdr.connType = kConnTypeSimpleNet; connect.hdr.hdrBytes = sizeof(connect.hdr); @@ -385,8 +387,8 @@ static void Connect (const NetAddress & addr, ConnectParam * cp) { connect.hdr.buildType = BUILD_TYPE_LIVE; connect.hdr.branchId = BranchId(); connect.hdr.productId = ProductId(); - connect.data.channelId = cp->channel->GetValue(); - + connect.data.channelId = cp->channel->channelId; + AsyncSocketConnect( &conn->cancelId, addr, @@ -395,12 +397,12 @@ static void Connect (const NetAddress & addr, ConnectParam * cp) { &connect, sizeof(connect) ); - - conn = nil; + + conn = nil; cp = nil; } - s_critsect.Leave(); - + s_critsect.Unlock(); + delete conn; delete cp; } @@ -447,8 +449,8 @@ void SimpleNetShutdown () { s_running = false; - ASSERT(!s_channels.Head()); - + ASSERT(!s_channels.size()); + AsyncSocketUnregisterNotifyProc( kConnTypeSimpleNet, AsyncNotifySocketProc @@ -460,7 +462,7 @@ void SimpleNetConnIncRef (SimpleNetConn * conn) { ASSERT(s_running); ASSERT(conn); - + conn->IncRef(); } @@ -469,7 +471,7 @@ void SimpleNetConnDecRef (SimpleNetConn * conn) { ASSERT(s_running); ASSERT(conn); - + conn->DecRef(); } @@ -481,10 +483,10 @@ bool SimpleNetStartListening ( ASSERT(s_running); ASSERT(queryAccept); ASSERT(!s_queryAccept); - + s_queryAccept = queryAccept; s_queryAcceptParam = param; - + NetAddress addr; NetAddressFromNode(0, kNetDefaultSimpleNetPort, &addr); return (0 != AsyncSocketStartListening(addr, nil)); @@ -514,22 +516,22 @@ void SimpleNetCreateChannel ( SimpleNetChannel * channel = NEWZERO(SimpleNetChannel)(channelId); channel->IncRef(); - s_critsect.Enter(); + s_critsect.Lock(); { #ifdef HS_DEBUGGING { - SimpleNetChannel * existing = s_channels.Find(channelId); - ASSERT(!existing); + std::map::iterator it = s_channels.find(channelId); + ASSERT(it == s_channels.end()); } #endif - + channel->onMsg = onMsg; channel->onError = onError; - s_channels.Add(channel); + s_channels[channelId] = channel; channel->IncRef(); } - s_critsect.Leave(); - + s_critsect.Unlock(); + channel->DecRef(); } @@ -539,20 +541,26 @@ void SimpleNetDestroyChannel (unsigned channelId) { ASSERT(s_running); SimpleNetChannel * channel; - s_critsect.Enter(); + s_critsect.Lock(); { - if (nil != (channel = s_channels.Find(channelId))) { - s_channels.Unlink(channel); - while (SimpleNetConn * conn = channel->conns.Head()) { + std::map::iterator it; + if ((it = s_channels.find(channelId)) != s_channels.end()) { + channel = it->second; + + while (channel->conns.size()) { + SimpleNetConn* conn = channel->conns.front(); SimpleNetDisconnect(conn); - channel->conns.Unlink(conn); + + channel->conns.pop_front(); } + + s_channels.erase(it); } } - s_critsect.Leave(); + s_critsect.Unlock(); if (channel) - channel->DecRef(); + channel->DecRef(); } //============================================================================ @@ -564,18 +572,22 @@ void SimpleNetStartConnecting ( ) { ASSERT(s_running); ASSERT(onConnect); - + ConnectParam * cp = new ConnectParam; cp->callback = onConnect; cp->param = param; - - s_critsect.Enter(); + cp->channel = nil; + + s_critsect.Lock(); { - if (nil != (cp->channel = s_channels.Find(channelId))) + std::map::iterator it; + if ((it = s_channels.find(channelId)) != s_channels.end()) { + cp->channel = it->second; cp->channel->IncRef(); + } } - s_critsect.Leave(); - + s_critsect.Unlock(); + ASSERT(cp->channel); // Do we need to lookup the address? @@ -608,8 +620,8 @@ void SimpleNetDisconnect ( ) { ASSERT(s_running); ASSERT(conn); - - s_critsect.Enter(); + + s_critsect.Lock(); { conn->abandoned = true; if (conn->sock) { @@ -621,7 +633,7 @@ void SimpleNetDisconnect ( conn->cancelId = nil; } } - s_critsect.Leave(); + s_critsect.Unlock(); conn->DecRef("Lifetime"); } @@ -635,11 +647,11 @@ void SimpleNetSend ( ASSERT(msg); ASSERT(msg->messageBytes != (uint32_t)-1); ASSERT(conn); - - s_critsect.Enter(); + + s_critsect.Lock(); { if (conn->sock) AsyncSocketSend(conn->sock, msg, msg->messageBytes); } - s_critsect.Leave(); + s_critsect.Unlock(); }