summaryrefslogtreecommitdiff
path: root/src/modules
diff options
context:
space:
mode:
authorbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2007-03-11 15:53:34 +0000
committerbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2007-03-11 15:53:34 +0000
commit52214a3195d062bc45522e7da58bbe7611d040f6 (patch)
tree9648e735b327dab6cf98804bb39ea4770214b8ca /src/modules
parent9802f6f93554ef1266ba6cac41a7752d25a35380 (diff)
Added OnBufferFlush, improved m_safelist, no longer works on a timer but works on the writeability state of each user who is listing.
Seems to test fine with 500 reet bots all listing at once. (doesnt lock up the ircd while listing them all any more, either, just lags a small amount) git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@6657 e03df62e-2008-0410-955e-edbf42e46eb7
Diffstat (limited to 'src/modules')
-rw-r--r--src/modules/m_safelist.cpp197
1 files changed, 61 insertions, 136 deletions
diff --git a/src/modules/m_safelist.cpp b/src/modules/m_safelist.cpp
index af7fefc6a..1bdfb97bd 100644
--- a/src/modules/m_safelist.cpp
+++ b/src/modules/m_safelist.cpp
@@ -6,7 +6,7 @@
* See: http://www.inspircd.org/wiki/index.php/Credits
*
* This program is free but copyrighted software; see
- * the file COPYING for details.
+ * the file COPYING for details.
*
* ---------------------------------------------------
*/
@@ -33,143 +33,26 @@ class ListData : public classbase
};
/* $ModDesc: A module overriding /list, and making it safe - stop those sendq problems. */
-
-typedef std::vector<userrec *> UserList;
-UserList listusers; /* vector of people doing a /list */
-class ListTimer *timer;
-
-/** To create a timer which recurs every second, we inherit from InspTimer.
- * InspTimer is only one-shot however, so at the end of each Tick() we simply
- * insert another of ourselves into the pending queue :)
- */
-class ListTimer : public InspTimer
-{
- private:
-
- char buffer[MAXBUF];
- chanrec *chan;
- InspIRCd* ServerInstance;
- const std::string glob;
- size_t ServerNameSize;
-
- public:
-
- ListTimer(InspIRCd* Instance, long interval) : InspTimer(interval,Instance->Time()), ServerInstance(Instance)
- {
- ServerNameSize = 4 + strlen(ServerInstance->Config->ServerName);
- }
-
- virtual void Tick(time_t TIME)
- {
- bool go_again = true;
-
- while (go_again)
- {
- go_again = false;
- for (UserList::iterator iter = listusers.begin(); iter != listusers.end(); iter++)
- {
- /*
- * What we do here:
- * - Get where they are up to
- * - If it's more than total number of channels, erase
- * them from the iterator, set go_again to true
- * - If not, spool more channels
- */
- userrec* u = (userrec*)(*iter);
- ListData* ld;
- u->GetExt("safelist_cache", ld);
- if ((size_t)ld->list_position > ServerInstance->chanlist->size())
- {
- u->Shrink("safelist_cache");
- DELETE(ld);
- listusers.erase(iter);
- go_again = true;
- break;
- }
- chan = NULL;
- /* Attempt to fill up to 25% the user's sendq with /LIST output */
- long amount_sent = 0;
- do
- {
- if (!ld->list_position)
- u->WriteServ("321 %s Channel :Users Name",u->nick);
- chan = ServerInstance->GetChannelIndex(ld->list_position);
- /* spool details */
- bool has_user = (chan && chan->HasUser(u));
- if ((chan) && (chan->modes[CM_PRIVATE]))
- {
- bool display = match(chan->name, ld->glob.c_str());
- long users = chan->GetUserCounter();
- if ((users) && (display))
- {
- int counter = snprintf(buffer, MAXBUF, "322 %s *", u->nick);
- amount_sent += counter + ServerNameSize;
- u->WriteServ(std::string(buffer));
- }
- }
- else if ((chan) && (((!(chan->modes[CM_PRIVATE])) && (!(chan->modes[CM_SECRET]))) || (has_user)))
- {
- bool display = match(chan->name, ld->glob.c_str());
- long users = chan->GetUserCounter();
-
- if ((users) && (display))
- {
- int counter = snprintf(buffer, MAXBUF, "322 %s %s %ld :[+%s] %s",u->nick, chan->name, users, chan->ChanModes(has_user), chan->topic);
- /* Increment total plus linefeed */
- amount_sent += counter + ServerNameSize;
- u->WriteServ(std::string(buffer));
- }
- }
- else
- {
- if (!chan)
- {
- if (!ld->list_ended)
- {
- ld->list_ended = true;
- u->WriteServ("323 %s :End of channel list.",u->nick);
- }
- }
- }
-
- ld->list_position++;
- }
- while ((chan != NULL) && (amount_sent < (u->sendqmax / 4)));
- }
- }
-
- if (listusers.size())
- {
- timer = new ListTimer(ServerInstance,1);
- ServerInstance->Timers->AddTimer(timer);
- }
- else
- {
- timer = NULL;
- }
- }
-};
class ModuleSafeList : public Module
{
time_t ThrottleSecs;
+ size_t ServerNameSize;
public:
ModuleSafeList(InspIRCd* Me) : Module::Module(Me)
{
- timer = NULL;
OnRehash(NULL, "");
}
virtual ~ModuleSafeList()
{
- if (timer)
- ServerInstance->Timers->DelTimer(timer);
}
virtual void OnRehash(userrec* user, const std::string &parameter)
{
ConfigReader MyConf(ServerInstance);
ThrottleSecs = MyConf.ReadInteger("safelist", "throttle", "60", 0, true);
+ ServerNameSize = strlen(ServerInstance->Config->ServerName) + 4;
}
virtual Version GetVersion()
@@ -179,7 +62,7 @@ class ModuleSafeList : public Module
void Implements(char* List)
{
- List[I_OnPreCommand] = List[I_OnCleanup] = List[I_OnUserQuit] = List[I_On005Numeric] = List[I_OnRehash] = 1;
+ List[I_OnBufferFlushed] = List[I_OnPreCommand] = List[I_OnCleanup] = List[I_OnUserQuit] = List[I_On005Numeric] = List[I_OnRehash] = 1;
}
/*
@@ -240,21 +123,72 @@ class ModuleSafeList : public Module
*/
ld = new ListData(0,ServerInstance->Time(), pcnt ? parameters[0] : "*");
user->Extend("safelist_cache", ld);
- listusers.push_back(user);
time_t* llt = new time_t;
*llt = ServerInstance->Time();
user->Extend("safelist_last", llt);
- if (!timer)
- {
- timer = new ListTimer(ServerInstance,1);
- ServerInstance->Timers->AddTimer(timer);
- }
+ user->WriteServ("321 %s Channel :Users Name",user->nick);
return 1;
}
+ virtual void OnBufferFlushed(userrec* user)
+ {
+ char buffer[MAXBUF];
+ ListData* ld;
+ if (user->GetExt("safelist_cache", ld))
+ {
+ chanrec* chan = NULL;
+ long amount_sent = 0;
+ do
+ {
+ chan = ServerInstance->GetChannelIndex(ld->list_position);
+ bool has_user = (chan && chan->HasUser(user));
+ if ((chan) && (chan->modes[CM_PRIVATE]))
+ {
+ bool display = match(chan->name, ld->glob.c_str());
+ long users = chan->GetUserCounter();
+ if ((users) && (display))
+ {
+ int counter = snprintf(buffer, MAXBUF, "322 %s *", user->nick);
+ amount_sent += counter + ServerNameSize;
+ user->WriteServ(std::string(buffer));
+ }
+ }
+ else if ((chan) && (((!(chan->modes[CM_PRIVATE])) && (!(chan->modes[CM_SECRET]))) || (has_user)))
+ {
+ bool display = match(chan->name, ld->glob.c_str());
+ long users = chan->GetUserCounter();
+ if ((users) && (display))
+ {
+ int counter = snprintf(buffer, MAXBUF, "322 %s %s %ld :[+%s] %s",user->nick, chan->name, users, chan->ChanModes(has_user), chan->topic);
+ amount_sent += counter + ServerNameSize;
+ user->WriteServ(std::string(buffer));
+ }
+ }
+ else
+ {
+ if (!chan)
+ {
+ if (!ld->list_ended)
+ {
+ ld->list_ended = true;
+ user->WriteServ("323 %s :End of channel list.",user->nick);
+ }
+ }
+ }
+ ld->list_position++;
+ }
+ while ((chan != NULL) && (amount_sent < (user->sendqmax / 4)));
+ if (ld->list_ended)
+ {
+ user->Shrink("safelist_cache");
+ DELETE(ld);
+ }
+ }
+ }
+
virtual void OnCleanup(int target_type, void* item)
{
if(target_type == TYPE_USER)
@@ -267,15 +201,6 @@ class ModuleSafeList : public Module
u->Shrink("safelist_cache");
DELETE(ld);
}
- for (UserList::iterator iter = listusers.begin(); iter != listusers.end(); iter++)
- {
- userrec* u2 = (userrec*)(*iter);
- if (u2 == u)
- {
- listusers.erase(iter);
- break;
- }
- }
time_t* last_list_time;
u->GetExt("safelist_last", last_list_time);
if (last_list_time)