|
|
@ -45,9 +45,11 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
|
|
*
|
|
|
|
*
|
|
|
|
***/ |
|
|
|
***/ |
|
|
|
|
|
|
|
|
|
|
|
#include "Pch.h" |
|
|
|
#include "pnSimpleNet.h" |
|
|
|
#pragma hdrstop |
|
|
|
#include "hsThread.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <list> |
|
|
|
|
|
|
|
#include <map> |
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
/*****************************************************************************
|
|
|
|
* |
|
|
|
* |
|
|
@ -56,35 +58,25 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
|
|
***/ |
|
|
|
***/ |
|
|
|
|
|
|
|
|
|
|
|
struct SimpleNetConn : AtomicRef { |
|
|
|
struct SimpleNetConn : AtomicRef { |
|
|
|
LINK(SimpleNetConn) link; |
|
|
|
|
|
|
|
AsyncSocket sock; |
|
|
|
AsyncSocket sock; |
|
|
|
AsyncCancelId cancelId; |
|
|
|
AsyncCancelId cancelId; |
|
|
|
unsigned channelId; |
|
|
|
uint32_t channelId; |
|
|
|
bool abandoned; |
|
|
|
bool abandoned; |
|
|
|
struct ConnectParam * connectParam; |
|
|
|
struct ConnectParam * connectParam; |
|
|
|
|
|
|
|
|
|
|
|
SimpleNet_MsgHeader * oversizeMsg; |
|
|
|
SimpleNet_MsgHeader * oversizeMsg; |
|
|
|
ARRAY(uint8_t) oversizeBuffer; |
|
|
|
ARRAY(uint8_t) oversizeBuffer; |
|
|
|
|
|
|
|
|
|
|
|
~SimpleNetConn () { |
|
|
|
|
|
|
|
ASSERT(!link.IsLinked()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
struct SimpleNetChannel : AtomicRef, THashKeyVal<unsigned> { |
|
|
|
struct SimpleNetChannel : AtomicRef { |
|
|
|
HASHLINK(SimpleNetChannel) link; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FSimpleNetOnMsg onMsg; |
|
|
|
FSimpleNetOnMsg onMsg; |
|
|
|
FSimpleNetOnError onError; |
|
|
|
FSimpleNetOnError onError; |
|
|
|
|
|
|
|
uint32_t channelId; |
|
|
|
|
|
|
|
std::list<SimpleNetConn*> conns; |
|
|
|
|
|
|
|
|
|
|
|
LISTDECL(SimpleNetConn, link) conns; |
|
|
|
SimpleNetChannel (uint32_t channel) : channelId(channel) { } |
|
|
|
|
|
|
|
|
|
|
|
SimpleNetChannel (unsigned channel) |
|
|
|
|
|
|
|
: THashKeyVal<unsigned>(channel) |
|
|
|
|
|
|
|
{ } |
|
|
|
|
|
|
|
~SimpleNetChannel () { |
|
|
|
~SimpleNetChannel () { |
|
|
|
ASSERT(!link.IsLinked()); |
|
|
|
ASSERT(!conns.size()); |
|
|
|
ASSERT(!conns.Head()); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
@ -107,15 +99,10 @@ struct ConnectParam { |
|
|
|
***/ |
|
|
|
***/ |
|
|
|
|
|
|
|
|
|
|
|
static bool s_running; |
|
|
|
static bool s_running; |
|
|
|
static CCritSect s_critsect; |
|
|
|
static hsMutex s_critsect; |
|
|
|
static FSimpleNetQueryAccept s_queryAccept; |
|
|
|
static FSimpleNetQueryAccept s_queryAccept; |
|
|
|
static void * s_queryAcceptParam; |
|
|
|
static void * s_queryAcceptParam; |
|
|
|
|
|
|
|
static std::map<uint32_t, SimpleNetChannel*> s_channels; |
|
|
|
static HASHTABLEDECL( |
|
|
|
|
|
|
|
SimpleNetChannel, |
|
|
|
|
|
|
|
THashKeyVal<unsigned>, |
|
|
|
|
|
|
|
link |
|
|
|
|
|
|
|
) s_channels; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
/*****************************************************************************
|
|
|
@ -142,11 +129,14 @@ static void NotifyConnSocketConnect (SimpleNetConn * conn) { |
|
|
|
//============================================================================
|
|
|
|
//============================================================================
|
|
|
|
static void NotifyConnSocketConnectFailed (SimpleNetConn * conn) { |
|
|
|
static void NotifyConnSocketConnectFailed (SimpleNetConn * conn) { |
|
|
|
|
|
|
|
|
|
|
|
s_critsect.Enter(); |
|
|
|
s_critsect.Lock(); |
|
|
|
{ |
|
|
|
{ |
|
|
|
conn->link.Unlink(); |
|
|
|
std::map<uint32_t, SimpleNetChannel*>::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->callback( |
|
|
|
conn->connectParam->param, |
|
|
|
conn->connectParam->param, |
|
|
@ -165,15 +155,18 @@ static void NotifyConnSocketConnectFailed (SimpleNetConn * conn) { |
|
|
|
static void NotifyConnSocketDisconnect (SimpleNetConn * conn) { |
|
|
|
static void NotifyConnSocketDisconnect (SimpleNetConn * conn) { |
|
|
|
|
|
|
|
|
|
|
|
bool abandoned; |
|
|
|
bool abandoned; |
|
|
|
SimpleNetChannel * channel; |
|
|
|
SimpleNetChannel* channel = nil; |
|
|
|
s_critsect.Enter(); |
|
|
|
s_critsect.Lock(); |
|
|
|
{ |
|
|
|
{ |
|
|
|
abandoned = conn->abandoned; |
|
|
|
abandoned = conn->abandoned; |
|
|
|
if (nil != (channel = s_channels.Find(conn->channelId))) |
|
|
|
std::map<uint32_t, SimpleNetChannel*>::iterator it; |
|
|
|
|
|
|
|
if ((it = s_channels.find(conn->channelId)) != s_channels.end()) { |
|
|
|
|
|
|
|
channel = it->second; |
|
|
|
channel->IncRef(); |
|
|
|
channel->IncRef(); |
|
|
|
conn->link.Unlink(); |
|
|
|
channel->conns.remove(conn); |
|
|
|
} |
|
|
|
} |
|
|
|
s_critsect.Leave(); |
|
|
|
} |
|
|
|
|
|
|
|
s_critsect.Unlock(); |
|
|
|
|
|
|
|
|
|
|
|
if (channel && !abandoned) { |
|
|
|
if (channel && !abandoned) { |
|
|
|
channel->onError(conn, kNetErrDisconnected); |
|
|
|
channel->onError(conn, kNetErrDisconnected); |
|
|
@ -186,13 +179,16 @@ static void NotifyConnSocketDisconnect (SimpleNetConn * conn) { |
|
|
|
//============================================================================
|
|
|
|
//============================================================================
|
|
|
|
static bool NotifyConnSocketRead (SimpleNetConn * conn, AsyncNotifySocketRead * read) { |
|
|
|
static bool NotifyConnSocketRead (SimpleNetConn * conn, AsyncNotifySocketRead * read) { |
|
|
|
|
|
|
|
|
|
|
|
SimpleNetChannel * channel; |
|
|
|
SimpleNetChannel* channel = nil; |
|
|
|
s_critsect.Enter(); |
|
|
|
s_critsect.Lock(); |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (nil != (channel = s_channels.Find(conn->channelId))) |
|
|
|
std::map<uint32_t, SimpleNetChannel*>::iterator it; |
|
|
|
|
|
|
|
if ((it = s_channels.find(conn->channelId)) != s_channels.end()) { |
|
|
|
|
|
|
|
channel = it->second; |
|
|
|
channel->IncRef(); |
|
|
|
channel->IncRef(); |
|
|
|
} |
|
|
|
} |
|
|
|
s_critsect.Leave(); |
|
|
|
} |
|
|
|
|
|
|
|
s_critsect.Unlock(); |
|
|
|
|
|
|
|
|
|
|
|
if (!channel) |
|
|
|
if (!channel) |
|
|
|
return false; |
|
|
|
return false; |
|
|
@ -286,19 +282,22 @@ static bool AsyncNotifySocketProc ( |
|
|
|
const SimpleNet_ConnData & connect = *(const SimpleNet_ConnData *) listen->buffer; |
|
|
|
const SimpleNet_ConnData & connect = *(const SimpleNet_ConnData *) listen->buffer; |
|
|
|
listen->bytesProcessed += sizeof(connect); |
|
|
|
listen->bytesProcessed += sizeof(connect); |
|
|
|
|
|
|
|
|
|
|
|
SimpleNetChannel * channel; |
|
|
|
SimpleNetChannel* channel = nil; |
|
|
|
s_critsect.Enter(); |
|
|
|
s_critsect.Lock(); |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (nil != (channel = s_channels.Find(connect.channelId))) |
|
|
|
std::map<uint32_t, SimpleNetChannel*>::iterator it; |
|
|
|
|
|
|
|
if ((it = s_channels.find(conn->channelId)) != s_channels.end()) { |
|
|
|
|
|
|
|
channel = it->second; |
|
|
|
channel->IncRef(); |
|
|
|
channel->IncRef(); |
|
|
|
} |
|
|
|
} |
|
|
|
s_critsect.Leave(); |
|
|
|
} |
|
|
|
|
|
|
|
s_critsect.Unlock(); |
|
|
|
|
|
|
|
|
|
|
|
if (!channel) |
|
|
|
if (!channel) |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
conn = NEWZERO(SimpleNetConn); |
|
|
|
conn = NEWZERO(SimpleNetConn); |
|
|
|
conn->channelId = channel->GetValue(); |
|
|
|
conn->channelId = channel->channelId; |
|
|
|
conn->IncRef("Lifetime"); |
|
|
|
conn->IncRef("Lifetime"); |
|
|
|
conn->IncRef("Connected"); |
|
|
|
conn->IncRef("Connected"); |
|
|
|
conn->sock = sock; |
|
|
|
conn->sock = sock; |
|
|
@ -306,7 +305,7 @@ static bool AsyncNotifySocketProc ( |
|
|
|
|
|
|
|
|
|
|
|
bool accepted = s_queryAccept( |
|
|
|
bool accepted = s_queryAccept( |
|
|
|
s_queryAcceptParam, |
|
|
|
s_queryAcceptParam, |
|
|
|
channel->GetValue(), |
|
|
|
channel->channelId, |
|
|
|
conn, |
|
|
|
conn, |
|
|
|
listen->remoteAddr |
|
|
|
listen->remoteAddr |
|
|
|
); |
|
|
|
); |
|
|
@ -315,11 +314,11 @@ static bool AsyncNotifySocketProc ( |
|
|
|
SimpleNetDisconnect(conn); |
|
|
|
SimpleNetDisconnect(conn); |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
|
s_critsect.Enter(); |
|
|
|
s_critsect.Lock(); |
|
|
|
{ |
|
|
|
{ |
|
|
|
channel->conns.Link(conn); |
|
|
|
channel->conns.push_back(conn); |
|
|
|
} |
|
|
|
} |
|
|
|
s_critsect.Leave(); |
|
|
|
s_critsect.Unlock(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
channel->DecRef(); |
|
|
|
channel->DecRef(); |
|
|
@ -331,13 +330,13 @@ static bool AsyncNotifySocketProc ( |
|
|
|
*userState = conn; |
|
|
|
*userState = conn; |
|
|
|
bool abandoned; |
|
|
|
bool abandoned; |
|
|
|
|
|
|
|
|
|
|
|
s_critsect.Enter(); |
|
|
|
s_critsect.Lock(); |
|
|
|
{ |
|
|
|
{ |
|
|
|
conn->sock = sock; |
|
|
|
conn->sock = sock; |
|
|
|
conn->cancelId = 0; |
|
|
|
conn->cancelId = 0; |
|
|
|
abandoned = conn->abandoned; |
|
|
|
abandoned = conn->abandoned; |
|
|
|
} |
|
|
|
} |
|
|
|
s_critsect.Leave(); |
|
|
|
s_critsect.Unlock(); |
|
|
|
|
|
|
|
|
|
|
|
if (abandoned) |
|
|
|
if (abandoned) |
|
|
|
AsyncSocketDisconnect(sock, true); |
|
|
|
AsyncSocketDisconnect(sock, true); |
|
|
@ -360,6 +359,9 @@ static bool AsyncNotifySocketProc ( |
|
|
|
conn = (SimpleNetConn *) *userState; |
|
|
|
conn = (SimpleNetConn *) *userState; |
|
|
|
result = NotifyConnSocketRead(conn, (AsyncNotifySocketRead *) notify); |
|
|
|
result = NotifyConnSocketRead(conn, (AsyncNotifySocketRead *) notify); |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return result; |
|
|
|
return result; |
|
|
@ -369,14 +371,14 @@ static bool AsyncNotifySocketProc ( |
|
|
|
static void Connect (const NetAddress & addr, ConnectParam * cp) { |
|
|
|
static void Connect (const NetAddress & addr, ConnectParam * cp) { |
|
|
|
|
|
|
|
|
|
|
|
SimpleNetConn * conn = NEWZERO(SimpleNetConn); |
|
|
|
SimpleNetConn * conn = NEWZERO(SimpleNetConn); |
|
|
|
conn->channelId = cp->channel->GetValue(); |
|
|
|
conn->channelId = cp->channel->channelId; |
|
|
|
conn->connectParam = cp; |
|
|
|
conn->connectParam = cp; |
|
|
|
conn->IncRef("Lifetime"); |
|
|
|
conn->IncRef("Lifetime"); |
|
|
|
conn->IncRef("Connecting"); |
|
|
|
conn->IncRef("Connecting"); |
|
|
|
|
|
|
|
|
|
|
|
s_critsect.Enter(); |
|
|
|
s_critsect.Lock(); |
|
|
|
{ |
|
|
|
{ |
|
|
|
cp->channel->conns.Link(conn); |
|
|
|
cp->channel->conns.push_back(conn); |
|
|
|
|
|
|
|
|
|
|
|
SimpleNet_Connect connect; |
|
|
|
SimpleNet_Connect connect; |
|
|
|
connect.hdr.connType = kConnTypeSimpleNet; |
|
|
|
connect.hdr.connType = kConnTypeSimpleNet; |
|
|
@ -385,7 +387,7 @@ static void Connect (const NetAddress & addr, ConnectParam * cp) { |
|
|
|
connect.hdr.buildType = BUILD_TYPE_LIVE; |
|
|
|
connect.hdr.buildType = BUILD_TYPE_LIVE; |
|
|
|
connect.hdr.branchId = BranchId(); |
|
|
|
connect.hdr.branchId = BranchId(); |
|
|
|
connect.hdr.productId = ProductId(); |
|
|
|
connect.hdr.productId = ProductId(); |
|
|
|
connect.data.channelId = cp->channel->GetValue(); |
|
|
|
connect.data.channelId = cp->channel->channelId; |
|
|
|
|
|
|
|
|
|
|
|
AsyncSocketConnect( |
|
|
|
AsyncSocketConnect( |
|
|
|
&conn->cancelId, |
|
|
|
&conn->cancelId, |
|
|
@ -399,7 +401,7 @@ static void Connect (const NetAddress & addr, ConnectParam * cp) { |
|
|
|
conn = nil; |
|
|
|
conn = nil; |
|
|
|
cp = nil; |
|
|
|
cp = nil; |
|
|
|
} |
|
|
|
} |
|
|
|
s_critsect.Leave(); |
|
|
|
s_critsect.Unlock(); |
|
|
|
|
|
|
|
|
|
|
|
delete conn; |
|
|
|
delete conn; |
|
|
|
delete cp; |
|
|
|
delete cp; |
|
|
@ -447,7 +449,7 @@ void SimpleNetShutdown () { |
|
|
|
|
|
|
|
|
|
|
|
s_running = false; |
|
|
|
s_running = false; |
|
|
|
|
|
|
|
|
|
|
|
ASSERT(!s_channels.Head()); |
|
|
|
ASSERT(!s_channels.size()); |
|
|
|
|
|
|
|
|
|
|
|
AsyncSocketUnregisterNotifyProc( |
|
|
|
AsyncSocketUnregisterNotifyProc( |
|
|
|
kConnTypeSimpleNet, |
|
|
|
kConnTypeSimpleNet, |
|
|
@ -514,21 +516,21 @@ void SimpleNetCreateChannel ( |
|
|
|
SimpleNetChannel * channel = NEWZERO(SimpleNetChannel)(channelId); |
|
|
|
SimpleNetChannel * channel = NEWZERO(SimpleNetChannel)(channelId); |
|
|
|
channel->IncRef(); |
|
|
|
channel->IncRef(); |
|
|
|
|
|
|
|
|
|
|
|
s_critsect.Enter(); |
|
|
|
s_critsect.Lock(); |
|
|
|
{ |
|
|
|
{ |
|
|
|
#ifdef HS_DEBUGGING |
|
|
|
#ifdef HS_DEBUGGING |
|
|
|
{ |
|
|
|
{ |
|
|
|
SimpleNetChannel * existing = s_channels.Find(channelId); |
|
|
|
std::map<uint32_t, SimpleNetChannel*>::iterator it = s_channels.find(channelId); |
|
|
|
ASSERT(!existing); |
|
|
|
ASSERT(it == s_channels.end()); |
|
|
|
} |
|
|
|
} |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
channel->onMsg = onMsg; |
|
|
|
channel->onMsg = onMsg; |
|
|
|
channel->onError = onError; |
|
|
|
channel->onError = onError; |
|
|
|
s_channels.Add(channel); |
|
|
|
s_channels[channelId] = channel; |
|
|
|
channel->IncRef(); |
|
|
|
channel->IncRef(); |
|
|
|
} |
|
|
|
} |
|
|
|
s_critsect.Leave(); |
|
|
|
s_critsect.Unlock(); |
|
|
|
|
|
|
|
|
|
|
|
channel->DecRef(); |
|
|
|
channel->DecRef(); |
|
|
|
} |
|
|
|
} |
|
|
@ -539,17 +541,23 @@ void SimpleNetDestroyChannel (unsigned channelId) { |
|
|
|
ASSERT(s_running); |
|
|
|
ASSERT(s_running); |
|
|
|
|
|
|
|
|
|
|
|
SimpleNetChannel * channel; |
|
|
|
SimpleNetChannel * channel; |
|
|
|
s_critsect.Enter(); |
|
|
|
s_critsect.Lock(); |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (nil != (channel = s_channels.Find(channelId))) { |
|
|
|
std::map<uint32_t, SimpleNetChannel*>::iterator it; |
|
|
|
s_channels.Unlink(channel); |
|
|
|
if ((it = s_channels.find(channelId)) != s_channels.end()) { |
|
|
|
while (SimpleNetConn * conn = channel->conns.Head()) { |
|
|
|
channel = it->second; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (channel->conns.size()) { |
|
|
|
|
|
|
|
SimpleNetConn* conn = channel->conns.front(); |
|
|
|
SimpleNetDisconnect(conn); |
|
|
|
SimpleNetDisconnect(conn); |
|
|
|
channel->conns.Unlink(conn); |
|
|
|
|
|
|
|
|
|
|
|
channel->conns.pop_front(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
s_channels.erase(it); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
s_critsect.Leave(); |
|
|
|
s_critsect.Unlock(); |
|
|
|
|
|
|
|
|
|
|
|
if (channel) |
|
|
|
if (channel) |
|
|
|
channel->DecRef(); |
|
|
|
channel->DecRef(); |
|
|
@ -568,13 +576,17 @@ void SimpleNetStartConnecting ( |
|
|
|
ConnectParam * cp = new ConnectParam; |
|
|
|
ConnectParam * cp = new ConnectParam; |
|
|
|
cp->callback = onConnect; |
|
|
|
cp->callback = onConnect; |
|
|
|
cp->param = param; |
|
|
|
cp->param = param; |
|
|
|
|
|
|
|
cp->channel = nil; |
|
|
|
|
|
|
|
|
|
|
|
s_critsect.Enter(); |
|
|
|
s_critsect.Lock(); |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (nil != (cp->channel = s_channels.Find(channelId))) |
|
|
|
std::map<uint32_t, SimpleNetChannel*>::iterator it; |
|
|
|
|
|
|
|
if ((it = s_channels.find(channelId)) != s_channels.end()) { |
|
|
|
|
|
|
|
cp->channel = it->second; |
|
|
|
cp->channel->IncRef(); |
|
|
|
cp->channel->IncRef(); |
|
|
|
} |
|
|
|
} |
|
|
|
s_critsect.Leave(); |
|
|
|
} |
|
|
|
|
|
|
|
s_critsect.Unlock(); |
|
|
|
|
|
|
|
|
|
|
|
ASSERT(cp->channel); |
|
|
|
ASSERT(cp->channel); |
|
|
|
|
|
|
|
|
|
|
@ -609,7 +621,7 @@ void SimpleNetDisconnect ( |
|
|
|
ASSERT(s_running); |
|
|
|
ASSERT(s_running); |
|
|
|
ASSERT(conn); |
|
|
|
ASSERT(conn); |
|
|
|
|
|
|
|
|
|
|
|
s_critsect.Enter(); |
|
|
|
s_critsect.Lock(); |
|
|
|
{ |
|
|
|
{ |
|
|
|
conn->abandoned = true; |
|
|
|
conn->abandoned = true; |
|
|
|
if (conn->sock) { |
|
|
|
if (conn->sock) { |
|
|
@ -621,7 +633,7 @@ void SimpleNetDisconnect ( |
|
|
|
conn->cancelId = nil; |
|
|
|
conn->cancelId = nil; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
s_critsect.Leave(); |
|
|
|
s_critsect.Unlock(); |
|
|
|
|
|
|
|
|
|
|
|
conn->DecRef("Lifetime"); |
|
|
|
conn->DecRef("Lifetime"); |
|
|
|
} |
|
|
|
} |
|
|
@ -636,10 +648,10 @@ void SimpleNetSend ( |
|
|
|
ASSERT(msg->messageBytes != (uint32_t)-1); |
|
|
|
ASSERT(msg->messageBytes != (uint32_t)-1); |
|
|
|
ASSERT(conn); |
|
|
|
ASSERT(conn); |
|
|
|
|
|
|
|
|
|
|
|
s_critsect.Enter(); |
|
|
|
s_critsect.Lock(); |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (conn->sock) |
|
|
|
if (conn->sock) |
|
|
|
AsyncSocketSend(conn->sock, msg, msg->messageBytes); |
|
|
|
AsyncSocketSend(conn->sock, msg, msg->messageBytes); |
|
|
|
} |
|
|
|
} |
|
|
|
s_critsect.Leave(); |
|
|
|
s_critsect.Unlock(); |
|
|
|
} |
|
|
|
} |
|
|
|