summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-Trunk.txt2
-rw-r--r--src/common/socket.c107
-rw-r--r--src/common/socket.h5
3 files changed, 45 insertions, 69 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index 131426683..0a0f06bb8 100644
--- a/Changelog-Trunk.txt
+++ b/Changelog-Trunk.txt
@@ -4,6 +4,8 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
2007/05/10
+ * Adapted the shortlist to use a static array instead of a linked list and
+ enabled it.
* Added Buuyo-Tama's shortlist for send/eof sockets (defined out for now).
* Replaced toupper/tolower in ladmin by TOUPPER/TOLOWER defines. [FlavioJS]
2007/05/07
diff --git a/src/common/socket.c b/src/common/socket.c
index a538f3e31..3d00ed8ce 100644
--- a/src/common/socket.c
+++ b/src/common/socket.c
@@ -15,8 +15,6 @@
#include <sys/types.h>
#ifdef WIN32
- //#define WIN32_LEAN_AND_MEAN
- //#include <windows.h>
#include <winsock2.h>
#include <io.h>
#else
@@ -79,8 +77,9 @@ size_t wfifo_size = (16*1024);
struct socket_data* session[FD_SETSIZE];
#ifdef SEND_SHORTLIST
-struct send_shortlist_node *send_shortlist = NULL;
-fd_set send_shortlist_fd_set;
+int send_shortlist_array[FD_SETSIZE];// we only support FD_SETSIZE sockets, limit the array to that
+int send_shortlist_count = 0;// how many fd's are in the shortlist
+fd_set send_shortlist_fd_set;// to know if specific fd's are already in the shortlist
#endif
int create_session(int fd, RecvFunc func_recv, SendFunc func_send, ParseFunc func_parse);
@@ -153,13 +152,14 @@ void setsocketopts(int fd)
*--------------------------------------*/
void set_eof(int fd)
{
+ if( session_isActive(fd) )
+ {
#ifdef SEND_SHORTLIST
- // Add this socket to the shortlist for eof handling.
- send_shortlist_add_fd(fd);
+ // Add this socket to the shortlist for eof handling.
+ send_shortlist_add_fd(fd);
#endif
-
- if (session_isActive(fd))
session[fd]->eof = 1;
+ }
}
int recv_to_fifo(int fd)
@@ -521,8 +521,8 @@ int do_sendrecv(int next)
last_tick = time(0);
- //PRESEND Need to do this to ensure that the clients get something to do
- //which hopefully will cause them to send packets. [Meruru]
+ // PRESEND Timers are executed before do_sendrecv and can send packets
+ // and/or set sessions to eof. Send remaining data and handle eof sessions.
#ifdef SEND_SHORTLIST
send_shortlist_do_sends();
#else
@@ -536,6 +536,7 @@ int do_sendrecv(int next)
}
#endif
+ // can timeout until the next tick
timeout.tv_sec = next/1000;
timeout.tv_usec = next%1000*1000;
@@ -597,6 +598,7 @@ int do_sendrecv(int next)
}
#endif
+ // POSTSEND Send remaining data and handle eof sessions.
#ifdef SEND_SHORTLIST
send_shortlist_do_sends();
#else
@@ -946,7 +948,7 @@ int socket_config_read(const char* cfgName)
}
-void socket_final (void)
+void socket_final(void)
{
int i;
#ifndef MINICORE
@@ -1106,7 +1108,6 @@ void socket_init(void)
// session[0] is now currently used for disconnected sessions of the map server, and as such,
// should hold enough buffer (it is a vacuum so to speak) as it is never flushed. [Skotlex]
- // ##TODO "flush" this session periodically O.O [FlavioJS]
create_session(0, null_recv, null_send, null_parse);
#ifndef MINICORE
@@ -1159,83 +1160,55 @@ uint16 ntows(uint16 neshort)
#ifdef SEND_SHORTLIST
// Add a fd to the shortlist so that it'll be recognized as a fd that needs
-// sending (or eof handling) done on it.
+// sending or eof handling.
void send_shortlist_add_fd(int fd)
{
- struct send_shortlist_node* new_node;
-
- if (FD_ISSET(fd, &send_shortlist_fd_set))
- // Refuse to add duplicate FDs to the shortlist
- return;
-
- new_node = aMalloc(sizeof(*new_node));
+ if( FD_ISSET(fd, &send_shortlist_fd_set) )
+ return;// Refuse to add duplicate FDs to the shortlist
FD_SET(fd, &send_shortlist_fd_set);
- // Add the new node to the beginning of the shortlist linked list.
- new_node->fd = fd;
- new_node->prev = NULL;
- new_node->next = send_shortlist;
- if (new_node->next)
- new_node->next->prev = new_node;
-
- send_shortlist = new_node;
+ // Add to the end of the shortlist array.
+ send_shortlist_array[send_shortlist_count++] = fd;
}
-// Do pending network sends (and eof handling) from the shortlist.
+// Do pending network sends and eof handling from the shortlist.
void send_shortlist_do_sends()
{
- struct send_shortlist_node
- *current_node = send_shortlist,
- *next_node;
+ int i = 0;
- while (current_node)
- {
- int delete_current_node = 1;
+ // Assume all or most of the fd's don't remain in the shortlist
+ FD_ZERO(&send_shortlist_fd_set);
- next_node = current_node->next;
+ while( i < send_shortlist_count )
+ {
+ int fd = send_shortlist_array[i];
// If this session still exists, perform send operations on it and
// check for the eof state.
- if (session[ current_node->fd ])
+ if( session[fd] )
{
- if (session[ current_node->fd ]->wdata_size)
- session[ current_node->fd ]->func_send( current_node->fd );
+ // Send data
+ if( session[fd]->wdata_size )
+ session[fd]->func_send(fd);
// If it's been marked as eof, call the parse func on it so that
// the socket will be immediately closed.
- if (session[ current_node->fd ]->eof)
- session[ current_node->fd ]->func_parse( current_node->fd );
+ if( session[fd]->eof )
+ session[fd]->func_parse(fd);
// If the session still exists, is not eof and has things left to
- // be sent from it we'll keep it in the send shortlist.
- if (session[ current_node->fd ] &&
- !session[ current_node->fd ]->eof &&
- session[ current_node->fd ]->wdata_size)
- delete_current_node = 0;
- }
-
- // If this session has been marked for removal from the short list,
- // we'll proceed in doing this.
- if (delete_current_node)
- {
- FD_CLR(current_node->fd, &send_shortlist_fd_set);
-
- // Remove its link entry
- if (!current_node->prev)
- send_shortlist = next_node;
- else
- current_node->prev->next = next_node;
-
- if (current_node->next)
- current_node->next->prev = current_node->prev;
-
- // and free its memory
- aFree(current_node);
+ // be sent from it we'll keep it in the shortlist.
+ if( session[fd] && !session[fd]->eof && session[fd]->wdata_size )
+ {
+ FD_SET(fd, &send_shortlist_fd_set);
+ ++i;
+ continue;
+ }
}
- // Iterate to the next node (session) in the short list
- current_node = next_node;
+ // Remove fd from shortlist, move the last fd to the current position
+ send_shortlist_array[i] = send_shortlist_array[--send_shortlist_count];
}
}
#endif
diff --git a/src/common/socket.h b/src/common/socket.h
index a040772a9..a7734963a 100644
--- a/src/common/socket.h
+++ b/src/common/socket.h
@@ -143,10 +143,11 @@ extern int naddr_; // # of ip addresses
void set_eof(int fd);
/// Use a shortlist of sockets instead of iterating all sessions for sockets
-/// that have data to send or need eof processing.
+/// that have data to send or need eof handling.
+/// Adapted to use a static array instead of a linked list.
///
/// @author Buuyo-tama
-//#define SEND_SHORTLIST
+#define SEND_SHORTLIST
#ifdef SEND_SHORTLIST
struct send_shortlist_node {