From ae7b06ff8ad775a945bd677effd72b7fafa13d8d Mon Sep 17 00:00:00 2001 From: Ben Longbons Date: Thu, 17 Apr 2014 16:10:11 -0700 Subject: Die sensibly, take 1 --- src/mmo/socket.cpp | 34 ++++++++++++++++++++-------------- src/mmo/socket.hpp | 10 +++++++++- 2 files changed, 29 insertions(+), 15 deletions(-) (limited to 'src/mmo') 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(TimeT::now()) - static_cast(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 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 uint8_t *pod_addressof_m(T& structure) -- cgit v1.2.3-60-g2f50