Skip to content

Commit 7537770

Browse files
committed
Possible fix for crash
1 parent dfd519d commit 7537770

File tree

6 files changed

+65
-30
lines changed

6 files changed

+65
-30
lines changed

resources/sockets/irctest.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ addEventHandler("onIRCNick", root,
170170
addEventHandler("onIRCNotice", root,
171171
function(socket, user, target, notice)
172172
if socket == sock then
173-
user = ircGetUserNick(user)
173+
user = ircGetUserNick(user) or user
174174
outputServerLog("IRC: NOTICE ("..user.." -> "..target.."): "..notice)
175175
end
176176
end

sockets/include/CSocket.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,9 @@ class CSocket
3636
{
3737
public:
3838
CSocket (lua_State *luaVM, const string& strHost, const unsigned short& usPort);
39-
~CSocket ();
39+
~CSocket (); // Delete only - Does not trigger any events
4040

41+
void CloseSocketWithEvent (); // Close socket and trigger event
4142
bool Send (const string& data);
4243
bool DoPulse ();
4344
bool IsConnected ();

sockets/include/CSocketManager.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
class CSocket;
1313

1414
#include <vector>
15+
#include <deque>
16+
#include <assert.h>
1517
#include "ml_sockets.h"
1618

1719
class CSocketManager
@@ -20,7 +22,7 @@ class CSocketManager
2022
static void DoPulse();
2123

2224
static void SocketAdd (CSocket*& pSocket);
23-
static bool SocketRemove(CSocket*& pSocket);
25+
static void SocketRemove(CSocket*& pSocket);
2426
static bool GetSocket (CSocket*& pSocket, void* pUserdata);
2527

2628
static void HandleStop ();

sockets/include/ml_sockets.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,17 @@ using namespace std;
4747
// Function for making sure a pointer has a value before deleting it; possibly prevents crashes
4848
#define SAFE_DELETE(p) { if (p) { delete (p); (p) = NULL; } }
4949

50+
// List item removal
51+
template < class TL, class T >
52+
void ListRemove ( TL& itemList, const T& item )
53+
{
54+
typename TL ::iterator it = itemList.begin ();
55+
for ( ; it != itemList.end () ; ++it )
56+
if ( item == *it )
57+
{
58+
itemList.erase ( it );
59+
break;
60+
}
61+
}
62+
5063
#endif

sockets/src/CSocket.cpp

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ CSocket::CSocket(lua_State *luaVM, const string& strHost, const unsigned short&
1616
m_usPort = usPort;
1717
m_pLuaVM = luaVM;
1818
m_pUserdata = NULL;
19+
m_pSocket = ERR_INVALID_SOCKET;
1920

2021
// Prepare data for connection (cancel on failure)
2122
if (!ProcessTargetLocation(strHost, usPort))
@@ -51,9 +52,18 @@ CSocket::CSocket(lua_State *luaVM, const string& strHost, const unsigned short&
5152
}
5253

5354
CSocket::~CSocket()
55+
{
56+
// Close the socket, if it exists
57+
if (m_pSocket != ERR_INVALID_SOCKET)
58+
{
59+
CloseSocket();
60+
}
61+
}
62+
63+
void CSocket::CloseSocketWithEvent()
5464
{
5565
// Close the socket, if it exists, and trigger the closed event
56-
if (m_pSocket)
66+
if (m_pSocket != ERR_INVALID_SOCKET)
5767
{
5868
CloseSocket();
5969
TriggerEvent("onSockClosed");
@@ -63,17 +73,21 @@ CSocket::~CSocket()
6373
bool CSocket::Send(const string& data)
6474
{
6575
// Make sure the socket exists
66-
if (!m_pSocket)
76+
if (m_pSocket == ERR_INVALID_SOCKET)
6777
return false;
6878

79+
// Pretend zero length send was ok
80+
if (data.length() == 0)
81+
return true;
82+
6983
// Send the data and return whether it was successful
7084
return (send(m_pSocket, data.c_str(), data.length(), 0) != ERR_SEND_FAILURE);
7185
}
7286

7387
bool CSocket::DoPulse()
7488
{
7589
// Make sure the socket exists before taking action
76-
if (m_pSocket)
90+
if (m_pSocket != ERR_INVALID_SOCKET)
7791
{
7892
// Wait for connect to complete before proceeding
7993
if (!m_bConnected)
@@ -134,7 +148,7 @@ bool CSocket::DoPulse()
134148
bool CSocket::IsConnected()
135149
{
136150
// If there's no socket, then we don't have a connection
137-
if (!m_pSocket)
151+
if (m_pSocket == ERR_INVALID_SOCKET)
138152
return false;
139153

140154
// If there is, show whether there is a connection
@@ -210,7 +224,7 @@ void CSocket::CloseSocket()
210224
#endif
211225

212226
// Unset the socket variable, so there's no mistaking there
213-
m_pSocket = NULL;
227+
m_pSocket = ERR_INVALID_SOCKET;
214228
}
215229

216230
int CSocket::HandleConnection(const int& iError)

sockets/src/CSocketManager.cpp

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,17 @@
1010

1111
// Vector for holding all sockets
1212
vector <CSocket*> vecSockets;
13+
deque <CSocket*> processQueue;
14+
deque <CSocket*> deleteList;
1315

1416
void CSocketManager::DoPulse()
1517
{
1618
// Loop through all sockets
17-
for (unsigned int i = 0; i < vecSockets.size(); ++i)
19+
processQueue = deque <CSocket*>(vecSockets.begin(), vecSockets.end());
20+
while (!processQueue.empty())
1821
{
19-
// Get the socket by the ID
20-
CSocket* pSocket = vecSockets[i];
22+
CSocket* pSocket = processQueue.front();
23+
processQueue.pop_front();
2124

2225
// Do a pulse at the socket
2326
if (!pSocket->DoPulse())
@@ -26,6 +29,14 @@ void CSocketManager::DoPulse()
2629
SocketRemove(pSocket);
2730
}
2831
}
32+
33+
// Finally cleanup sockets that were removed
34+
while (!deleteList.empty())
35+
{
36+
CSocket* pSocket = deleteList.front();
37+
deleteList.pop_front();
38+
SAFE_DELETE(pSocket);
39+
}
2940
}
3041

3142
void CSocketManager::SocketAdd(CSocket*& pSocket)
@@ -34,26 +45,13 @@ void CSocketManager::SocketAdd(CSocket*& pSocket)
3445
vecSockets.push_back(pSocket);
3546
}
3647

37-
bool CSocketManager::SocketRemove(CSocket*& pSocket)
48+
void CSocketManager::SocketRemove(CSocket*& pSocket)
3849
{
39-
// Check if an socket was actually specified
40-
if (pSocket == NULL)
41-
return false;
42-
43-
// Loop through all sockets
44-
for (unsigned int i = 0; i < vecSockets.size(); ++i)
45-
{
46-
// If the current is the one we're looking for...
47-
if (vecSockets[i] == pSocket)
48-
{
49-
// Remove it from the vector and delete it, then return true
50-
vecSockets.erase(vecSockets.begin() + i);
51-
SAFE_DELETE(pSocket);
52-
return true;
53-
}
54-
}
55-
56-
return false;
50+
ListRemove(vecSockets, pSocket);
51+
ListRemove(processQueue, pSocket);
52+
pSocket->CloseSocketWithEvent();
53+
ListRemove(deleteList, pSocket);
54+
deleteList.push_back(pSocket);
5755
}
5856

5957
bool CSocketManager::GetSocket(CSocket*& pSocket, void* pUserdata)
@@ -82,4 +80,11 @@ void CSocketManager::HandleStop()
8280
// Triggered at module stop. Simply destroys all sockets
8381
for (unsigned int i = 0; i < vecSockets.size(); ++i)
8482
SAFE_DELETE(vecSockets[i]);
83+
84+
for (unsigned int i = 0; i < deleteList.size(); ++i)
85+
SAFE_DELETE(deleteList[i]);
86+
87+
vecSockets.clear();
88+
processQueue.clear();
89+
deleteList.clear();
8590
}

0 commit comments

Comments
 (0)