فهرست منبع

* Chain WHO requests to try avoiding Max SendQ

Bryan Drewery 16 سال پیش
والد
کامیت
6cd064e4c2
4فایلهای تغییر یافته به همراه46 افزوده شده و 7 حذف شده
  1. 1 0
      doc/UPDATES
  2. 27 0
      src/mod/irc.mod/chan.c
  3. 17 6
      src/mod/irc.mod/irc.c
  4. 1 1
      src/mod/irc.mod/irc.h

+ 1 - 0
doc/UPDATES

@@ -5,6 +5,7 @@
 * On ratbox type servers, use an optimized queue for better throughput on the queue.
 * Add cmd_play for playing files to irc. (ASCII art gallery exhibition)
 * Utilize CPRIVMSG/CNOTICE if available.
+* Chain WHO requests to try avoiding Max SendQ
 
 1.2.17 - http://wraith.botpack.net/milestone/1.2.17
 * Binary / shell / startup changes

+ 27 - 0
src/mod/irc.mod/chan.c

@@ -1499,6 +1499,13 @@ void recheck_channel(struct chanset_t *chan, int dobans)
   --stacking;
 }
 
+static int got001(char *from, char *msg)
+{
+  //Just connected, cleanup some vars
+  chained_who.clear();
+  return 0;
+}
+
 /* got 302: userhost
  * <server> 302 <to> :<nick??user@host>
  */
@@ -2018,7 +2025,26 @@ static int got315(char *from, char *msg)
 
   newsplit(&msg);
   chname = newsplit(&msg);
+
+  if (!chained_who.isEmpty()) {
+    // Send off next WHO request
+    while (1) {
+      if (chained_who.isEmpty()) break;
+      // Dequeue the next chan in the chain
+      chan = findchan(bd::String(chained_who.dequeue()).c_str());
+      if (chan) {
+        if (!strcmp(chan->name, chname)) continue; // First reply got queued too
+        if (!shouldjoin(chan)) continue; // No longer care about this channel
+        // Somehow got the WHO already
+        if (channel_active(chan) && !channel_pending(chan)) continue;
+        send_chan_who(chained_who_idx, chan);
+        break;
+      }
+    }
+  }
+
   chan = findchan(chname);
+
   /* May have left the channel before the who info came in */
   if (!chan || !channel_pending(chan))
     return 0;
@@ -3366,6 +3392,7 @@ static int gotnotice(char *from, char *msg)
 
 static cmd_t irc_raw[] =
 {
+  {"001",       "",     (Function) got001,      "irc:001", LEAF},
   {"302",       "",     (Function) got302,      "irc:302", LEAF},
 #ifdef CACHE
   {"341",       "",     (Function) got341,      "irc:341", LEAF},

+ 17 - 6
src/mod/irc.mod/irc.c

@@ -56,6 +56,7 @@
 #include "src/mod/ctcp.mod/ctcp.h"
 #include <bdlib/src/String.h>
 #include <bdlib/src/HashTable.h>
+#include <bdlib/src/Queue.h>
 #include <bdlib/src/base64.h>
 
 #include <stdarg.h>
@@ -92,6 +93,9 @@ static bool include_lk = 1;      /* For correct calculation
 bd::HashTable<bd::String, unsigned long> bot_counters;
 static unsigned long my_counter = 0;
 
+static bd::Queue<bd::String> chained_who;
+static int chained_who_idx;
+
 static int
 voice_ok(memberlist *m, struct chanset_t *chan)
 {
@@ -1333,17 +1337,24 @@ reset_chan_info(struct chanset_t *chan)
     }
     /* These 2 need to get out asap, so into the mode queue */
     dprintf(DP_MODE, "MODE %s\n", chan->name);
-    send_chan_who(DP_MODE, chan);
+    send_chan_who(DP_MODE, chan, 1);
     /* clear_channel nuked the data...so */
     dprintf(DP_HELP, "TOPIC %s\n", chan->name);//Topic is very low priority
   }
 }
 
-static void send_chan_who(int queue, struct chanset_t *chan) {
-    if (use_354) /* Added benefit of getting numeric IP! :) */
-      dprintf(queue, "WHO %s %%c%%h%%n%%u%%f%%r%%d%%i\n", chan->name);
-    else
-      dprintf(queue, "WHO %s\n", chan->name);
+static void send_chan_who(int queue, struct chanset_t *chan, bool chain) {
+  if (chain) {
+    if (!chained_who.contains(chan->name))
+      chained_who.enqueue(chan->name);
+    chained_who_idx = queue;
+    if (chained_who.size() > 1)
+      return;
+  }
+  if (use_354) /* Added benefit of getting numeric IP! :) */
+    dprintf(queue, "WHO %s %%c%%h%%n%%u%%f%%r%%d%%i\n", chan->name);
+  else
+    dprintf(queue, "WHO %s\n", chan->name);
 }
 
 /* If i'm the only person on the channel, and i'm not op'd,

+ 1 - 1
src/mod/irc.mod/irc.h

@@ -94,7 +94,7 @@ static void check_lonely_channel(struct chanset_t *chan);
 static int gotmode(char *, char *);
 void unset_im(struct chanset_t* chan);
 void detected_drone_flood(struct chanset_t* chan, memberlist*);
-static void send_chan_who(int queue, struct chanset_t* chan);
+static void send_chan_who(int queue, struct chanset_t* chan, bool chain = 0);
 #define newban(chan, mask, who)         new_mask((chan)->channel.ban, mask, who)
 #define newexempt(chan, mask, who)      new_mask((chan)->channel.exempt, mask, who)
 #define newinvite(chan, mask, who)      new_mask((chan)->channel.invite, mask, who)