summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorBen Longbons <b.r.longbons@gmail.com>2013-05-18 17:37:33 -0700
committerBen Longbons <b.r.longbons@gmail.com>2013-05-18 18:49:39 -0700
commitac359e696f162090840dab488a6ef4981d35bbda (patch)
tree2ee04de23428bba264d1e39c80d5f50180d1b555 /src/common
parentfd00d50574064db9edfcccc4286ed8f1b55b185a (diff)
downloadtmwa-ac359e696f162090840dab488a6ef4981d35bbda.tar.gz
tmwa-ac359e696f162090840dab488a6ef4981d35bbda.tar.bz2
tmwa-ac359e696f162090840dab488a6ef4981d35bbda.tar.xz
tmwa-ac359e696f162090840dab488a6ef4981d35bbda.zip
Tweak a little memory management in char-server
Diffstat (limited to 'src/common')
-rw-r--r--src/common/mmo.hpp2
-rw-r--r--src/common/sanity.hpp7
-rw-r--r--src/common/socket.cpp47
-rw-r--r--src/common/socket.hpp28
4 files changed, 49 insertions, 35 deletions
diff --git a/src/common/mmo.hpp b/src/common/mmo.hpp
index 32d4285..e72bf80 100644
--- a/src/common/mmo.hpp
+++ b/src/common/mmo.hpp
@@ -203,7 +203,7 @@ struct storage
struct map_session_data;
-struct gm_account
+struct GM_Account
{
int account_id;
int level;
diff --git a/src/common/sanity.hpp b/src/common/sanity.hpp
index e54739f..74e24df 100644
--- a/src/common/sanity.hpp
+++ b/src/common/sanity.hpp
@@ -29,12 +29,15 @@
# endif // __GNUC_MINOR__ == 6
# ifdef __GLIBCXX__
// versions of libstdc++ from gcc
-// 4.6.0, 4.6.1, 4.6.2, 4.6.3
+// 4.6.0, 4.6.1, 4.6.2, 4.6.3, 4.6.4
# if __GLIBCXX__ == 20110325 \
|| __GLIBCXX__ == 20110627 \
|| __GLIBCXX__ == 20111026 \
|| __GLIBCXX__ == 20120301 \
- || __GLIBCXX__ == 20121127 // prerelease in Debian wheezy
+ || __GLIBCXX__ == 20130412 \
+ /* various Debian snapshots */ \
+ || __GLIBCXX__ == 20121127 \
+ || __GLIBCXX__ == 20130114
# define WORKAROUND_GCC46_LIBRARY
# endif // __GLIBCXX__ == ...
# endif // defined __GLIBCXX__
diff --git a/src/common/socket.cpp b/src/common/socket.cpp
index 2acbeb8..db944cc 100644
--- a/src/common/socket.cpp
+++ b/src/common/socket.cpp
@@ -29,13 +29,13 @@ const uint32_t RFIFO_SIZE = 65536;
static
const uint32_t WFIFO_SIZE = 65536;
-struct socket_data *session[FD_SETSIZE];
+std::array<std::unique_ptr<struct socket_data>, FD_SETSIZE> session;
/// clean up by discarding handled bytes
inline
void RFIFOFLUSH(int fd)
{
- memmove(session[fd]->rdata, RFIFOP(fd, 0), RFIFOREST(fd));
+ memmove(&session[fd]->rdata[0], RFIFOP(fd, 0), RFIFOREST(fd));
session[fd]->rdata_size = RFIFOREST(fd);
session[fd]->rdata_pos = 0;
}
@@ -53,9 +53,9 @@ static
void null_parse(int fd);
/// Default parser for new connections
static
-void(*default_func_parse)(int) = null_parse;
+void (*default_func_parse)(int) = null_parse;
-void set_defaultparse(void(*defaultparse)(int))
+void set_defaultparse(void (*defaultparse)(int))
{
default_func_parse = defaultparse;
}
@@ -67,7 +67,7 @@ void recv_to_fifo(int fd)
if (session[fd]->eof)
return;
- ssize_t len = read(fd, session[fd]->rdata + session[fd]->rdata_size,
+ ssize_t len = read(fd, &session[fd]->rdata[session[fd]->rdata_size],
RFIFOSPACE(fd));
if (len > 0)
@@ -87,14 +87,14 @@ void send_from_fifo(int fd)
if (session[fd]->eof)
return;
- ssize_t len = write(fd, session[fd]->wdata, session[fd]->wdata_size);
+ ssize_t len = write(fd, &session[fd]->wdata[0], session[fd]->wdata_size);
if (len > 0)
{
session[fd]->wdata_size -= len;
if (session[fd]->wdata_size)
{
- memmove(session[fd]->wdata, session[fd]->wdata + len,
+ memmove(&session[fd]->wdata[0], &session[fd]->wdata[len],
session[fd]->wdata_size);
}
session[fd]->connected = 1;
@@ -160,9 +160,9 @@ void connect_client(int listen_fd)
fcntl(fd, F_SETFL, O_NONBLOCK);
- CREATE(session[fd], struct socket_data, 1);
- CREATE(session[fd]->rdata, uint8_t, RFIFO_SIZE);
- CREATE(session[fd]->wdata, uint8_t, WFIFO_SIZE);
+ session[fd].reset(new socket_data());
+ session[fd]->rdata.new_(RFIFO_SIZE);
+ session[fd]->wdata.new_(WFIFO_SIZE);
session[fd]->max_rdata = RFIFO_SIZE;
session[fd]->max_wdata = WFIFO_SIZE;
@@ -219,7 +219,7 @@ int make_listen_port(uint16_t port)
FD_SET(fd, &readfds);
- CREATE(session[fd], struct socket_data, 1);
+ session[fd].reset(new socket_data());
session[fd]->func_recv = connect_client;
session[fd]->created = TimeT::now();
@@ -265,9 +265,9 @@ int make_connection(uint32_t ip, uint16_t port)
FD_SET(fd, &readfds);
- CREATE(session[fd], struct socket_data, 1);
- CREATE(session[fd]->rdata, uint8_t, RFIFO_SIZE);
- CREATE(session[fd]->wdata, uint8_t, WFIFO_SIZE);
+ session[fd].reset(new socket_data());
+ session[fd]->rdata.new_(RFIFO_SIZE);
+ session[fd]->wdata.new_(WFIFO_SIZE);
session[fd]->max_rdata = RFIFO_SIZE;
session[fd]->max_wdata = WFIFO_SIZE;
@@ -293,12 +293,11 @@ void delete_session(int fd)
FD_CLR(fd, &readfds);
if (session[fd])
{
- free(session[fd]->rdata);
- free(session[fd]->wdata);
- free(session[fd]->session_data);
- free(session[fd]);
+ session[fd]->rdata.delete_();
+ session[fd]->wdata.delete_();
+ session[fd]->session_data.reset();
+ session[fd].reset();
}
- session[fd] = NULL;
// just close() would try to keep sending buffers
shutdown(fd, SHUT_RDWR);
@@ -314,22 +313,22 @@ void delete_session(int fd)
void realloc_fifo(int fd, size_t rfifo_size, size_t wfifo_size)
{
- struct socket_data *s = session[fd];
+ const std::unique_ptr<socket_data>& s = session[fd];
if (s->max_rdata != rfifo_size && s->rdata_size < rfifo_size)
{
- RECREATE(s->rdata, uint8_t, rfifo_size);
+ s->rdata.resize(rfifo_size);
s->max_rdata = rfifo_size;
}
if (s->max_wdata != wfifo_size && s->wdata_size < wfifo_size)
{
- RECREATE(s->wdata, uint8_t, wfifo_size);
+ s->wdata.resize(wfifo_size);
s->max_wdata = wfifo_size;
}
}
void WFIFOSET(int fd, size_t len)
{
- struct socket_data *s = session[fd];
+ std::unique_ptr<socket_data>& s = session[fd];
if (s->wdata_size + len + 16384 > s->max_wdata)
{
realloc_fifo(fd, s->max_rdata, s->max_wdata << 1);
@@ -413,7 +412,7 @@ void do_socket(void)
void RFIFOSKIP(int fd, size_t len)
{
- struct socket_data *s = session[fd];
+ std::unique_ptr<socket_data>& s = session[fd];
s->rdata_pos += len;
if (s->rdata_size < s->rdata_pos)
diff --git a/src/common/socket.hpp b/src/common/socket.hpp
index d7c6b9c..d526379 100644
--- a/src/common/socket.hpp
+++ b/src/common/socket.hpp
@@ -7,9 +7,21 @@
# include <cstdio>
+# include <array>
+
+# include "dumb_ptr.hpp"
# include "utils.hpp"
# include "timer.t.hpp"
+struct SessionData
+{
+};
+struct SessionDeleter
+{
+ // defined per-server
+ void operator()(SessionData *sd);
+};
+
// Struct declaration
struct socket_data
@@ -23,7 +35,7 @@ struct socket_data
/// Since this is a single-threaded application, it can't block
/// These are the read/write queues
- uint8_t *rdata, *wdata;
+ dumb_ptr<uint8_t[]> rdata, wdata;
size_t max_rdata, max_wdata;
/// How much is actually in the queue
size_t rdata_size, wdata_size;
@@ -37,15 +49,15 @@ struct socket_data
/// Only called when select() indicates the socket is ready
/// If, after that, nothing is read, it sets eof
// These could probably be hard-coded with a little work
- void(*func_recv)(int);
- void(*func_send)(int);
+ void (*func_recv)(int);
+ void (*func_send)(int);
/// This is the important one
/// Set to different functions depending on whether the connection
/// is a player or a server/ladmin
/// Can be set explicitly or via set_defaultparse
- void(*func_parse)(int);
+ void (*func_parse)(int);
/// Server-specific data type
- void *session_data;
+ std::unique_ptr<SessionData, SessionDeleter> session_data;
};
// save file descriptors for important stuff
@@ -56,7 +68,7 @@ constexpr int CONNECT_TIMEOUT = 15;
/// Everyone who has connected
// note: call delete_session(i) to null out an element
-extern struct socket_data *session[FD_SETSIZE];
+extern std::array<std::unique_ptr<socket_data>, FD_SETSIZE> session;
/// Maximum used FD, +1
extern int fd_max;
@@ -102,7 +114,7 @@ size_t RFIFOREST(int fd)
inline
const void *RFIFOP(int fd, size_t pos)
{
- return session[fd]->rdata + session[fd]->rdata_pos + pos;
+ return &session[fd]->rdata[session[fd]->rdata_pos + pos];
}
inline
uint8_t RFIFOB(int fd, size_t pos)
@@ -156,7 +168,7 @@ size_t WFIFOSPACE(int fd)
inline
void *WFIFOP(int fd, size_t pos)
{
- return session[fd]->wdata + session[fd]->wdata_size + pos;
+ return &session[fd]->wdata[session[fd]->wdata_size + pos];
}
inline
uint8_t& WFIFOB(int fd, size_t pos)