summaryrefslogtreecommitdiff
path: root/src/mmo
diff options
context:
space:
mode:
authorBen Longbons <b.r.longbons@gmail.com>2014-04-17 16:10:11 -0700
committerBen Longbons <b.r.longbons@gmail.com>2014-04-17 16:10:11 -0700
commitae7b06ff8ad775a945bd677effd72b7fafa13d8d (patch)
tree3de2693f18a39e57008f63926fedf169da5b23ac /src/mmo
parent15dc4a8c51d0704bb82407c1dc79c751cda7fb42 (diff)
downloadtmwa-ae7b06ff8ad775a945bd677effd72b7fafa13d8d.tar.gz
tmwa-ae7b06ff8ad775a945bd677effd72b7fafa13d8d.tar.bz2
tmwa-ae7b06ff8ad775a945bd677effd72b7fafa13d8d.tar.xz
tmwa-ae7b06ff8ad775a945bd677effd72b7fafa13d8d.zip
Die sensibly, take 1
Diffstat (limited to 'src/mmo')
-rw-r--r--src/mmo/socket.cpp34
-rw-r--r--src/mmo/socket.hpp10
2 files changed, 29 insertions, 15 deletions
diff --git a/src/mmo/socket.cpp b/src/mmo/socket.cpp
index 48cd149..322a1f4 100644
--- a/src/mmo/socket.cpp
+++ b/src/mmo/socket.cpp
@@ -104,17 +104,20 @@ void null_parse(Session *s);
/// Default parser for new connections
static
void (*default_func_parse)(Session *) = null_parse;
+static
+void (*default_delete)(Session *) = nullptr;
-void set_defaultparse(void (*defaultparse)(Session *))
+void set_defaultparse(void (*defaultparse)(Session *), void (*on_delete)(Session *))
{
default_func_parse = defaultparse;
+ default_delete = on_delete;
}
/// Read from socket to the queue
static
void recv_to_fifo(Session *s)
{
- if (s->eof)
+ if (s->private_is_eof())
return;
ssize_t len = s->fd.read(&s->rdata[s->rdata_size],
@@ -127,14 +130,14 @@ void recv_to_fifo(Session *s)
}
else
{
- s->eof = 1;
+ s->set_eof();
}
}
static
void send_from_fifo(Session *s)
{
- if (s->eof)
+ if (s->private_is_eof())
return;
ssize_t len = s->fd.write(&s->wdata[0], s->wdata_size);
@@ -151,7 +154,7 @@ void send_from_fifo(Session *s)
}
else
{
- s->eof = 1;
+ s->set_eof();
}
}
@@ -222,6 +225,7 @@ void connect_client(Session *ls)
s->func_recv = recv_to_fifo;
s->func_send = send_from_fifo;
s->func_parse = default_func_parse;
+ s->func_delete = default_delete;
s->client_ip = IP4Address(client_address.sin_addr);
s->created = TimeT::now();
s->connected = 0;
@@ -340,6 +344,7 @@ Session *make_connection(IP4Address ip, uint16_t port)
s->func_recv = recv_to_fifo;
s->func_send = send_from_fifo;
s->func_parse = default_func_parse;
+ s->func_delete = default_delete;
s->created = TimeT::now();
s->connected = 1;
@@ -359,6 +364,8 @@ void delete_session(Session *s)
fd_max--;
readfds.clr(fd);
{
+ s->func_delete(s);
+
s->rdata.delete_();
s->wdata.delete_();
s->session_data.reset();
@@ -461,23 +468,22 @@ void do_parsepacket(void)
&& static_cast<time_t>(TimeT::now()) - static_cast<time_t>(s->created) > CONNECT_TIMEOUT)
{
PRINTF("Session #%d timed out\n", s);
- s->eof = 1;
+ s->set_eof();
}
- if (!s->rdata_size && !s->eof)
- continue;
- if (s->func_parse)
+ if (s->rdata_size && !s->private_is_eof() && s->func_parse)
{
s->func_parse(s);
/// some func_parse may call delete_session
+ // (that's kind of evil)
s = get_session(i);
- if (s && s->eof)
- {
- delete_session(s);
- s = nullptr;
- }
if (!s)
continue;
}
+ if (s->private_is_eof())
+ {
+ delete_session(s);
+ continue;
+ }
/// Reclaim buffer space for what was read
RFIFOFLUSH(s);
}
diff --git a/src/mmo/socket.hpp b/src/mmo/socket.hpp
index 256c08b..53e0dfd 100644
--- a/src/mmo/socket.hpp
+++ b/src/mmo/socket.hpp
@@ -59,8 +59,14 @@ struct Session
TimeT created;
bool connected;
+private:
/// Flag needed since structure must be freed in a server-dependent manner
bool eof;
+public:
+ void set_eof() { eof = true; }
+ // not everything is a member yet ...
+ bool private_is_eof() { return eof; }
+
/// Currently used by clif_setwaitclose
Timer timed_close;
@@ -87,6 +93,8 @@ struct Session
/// is a player or a server/ladmin
/// Can be set explicitly or via set_defaultparse
void (*func_parse)(Session *);
+ /// Cleanup function since we're not fully RAII yet
+ void (*func_delete)(Session *);
/// Server-specific data type
std::unique_ptr<SessionData, SessionDeleter> session_data;
@@ -141,7 +149,7 @@ void do_parsepacket(void);
/// Change the default parser for newly connected clients
// typically called once per server, but individual clients may identify
// themselves as servers
-void set_defaultparse(void(*defaultparse)(Session *));
+void set_defaultparse(void(*defaultparse)(Session *), void(*defaultdelete)(Session *));
template<class T>
uint8_t *pod_addressof_m(T& structure)