// ServerQueue.C -*- C++ -*-
// Copyright (c) 1997, 1998 Etienne BERNARD
-// Copyright (C) 2002 Clinton Ebadi
+// Copyright (C) 2002,2005,2008 Clinton Ebadi
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+// 02110-1301, USA.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-//#include <limits>
#include "ServerQueue.H"
+
+#include <limits>
+
+#include "Bot.H"
+#include "ServerQueueItem.H"
#include "Utils.H"
+#ifdef USESCRIPTS
+#include "BotInterp.H"
+#include "Interp.H"
+#endif
+
+int ServerQueue::max_penalty = 20;
+
ServerQueue::ServerQueue(Socket * s, bool d)
: Queue(s,d), penalty(0)
{
ServerQueue::~ServerQueue()
{
- penalty = INT_MIN;
+ penalty = std::numeric_limits<int>::min ();
flush();
}
void
ServerQueue::addItem(ServerQueueItem *sqi)
{
+ BotLock queue_lock (queue_mutex);
std::list<ServerQueueItem *>::iterator it, it2;
- for (it = serverQueue.begin(); it != serverQueue.end(); ++it) {
- if ((*it)->priority > sqi->priority)
- break;
- }
- it2 = it; --it2;
- if (it2 != serverQueue.end() && *it2) {
- // All right, we try to merge this item to the previous
- if ((*it2)->merge(sqi)) {
- delete sqi;
- return;
+ for (it = serverQueue.begin(); it != serverQueue.end(); ++it)
+ {
+ if (**it < *sqi)
+ {
+ break;
+ }
}
- }
+
+ it2 = it;
+ --it2;
+ if (it2 != serverQueue.end() && *it2)
+ {
+ // All right, we try to merge this item to the previous
+ if ((*it2)->merge(sqi))
+ {
+ delete sqi;
+ return;
+ }
+ }
+
serverQueue.insert(it, sqi);
}
bool
ServerQueue::flush()
{
+ // Locking around the entire queue flush prevents another thread
+ // from spamming the queue and preventing lower priority messages
+ // from ever being sent
+ BotLock flush_lock (queue_mutex);
+
// Called every second, we decrement the penalty
if (penalty > 0)
- penalty--;
-
- while (!serverQueue.empty() && (penalty < 5)) {
- ServerQueueItem * sqi = (*serverQueue.begin());
- penalty += sqi->penalty + sqi->getLine().length()/100 + 1;
- bool res = sendLine(sqi->getLine());
- serverQueue.erase(serverQueue.begin());
- delete sqi;
- if (!res)
- return false;
- }
+ {
+ penalty--;
+ }
+
+ while (!serverQueue.empty() && (penalty < max_penalty))
+ {
+ ServerQueueItem * sqi = serverQueue.front ();
+ penalty += sqi->penalty + sqi->getLine().length()/100;
+
+ bool res = sendLine(sqi->getLine());
+
+ serverQueue.pop_front ();
+ delete sqi;
+
+ if (!res)
+ {
+ return false;
+ }
+ }
+
return true;
}
Interp::bot->botInterp->RunHooks (Hook::SEND_ACTION,
MNICK + " " + to +
" " + message,
- scm_listify (Utils::
- string2SCM (MNICK),
+ scm_list_n (Utils::
+ str2scm (MNICK),
Utils::
- string2SCM (to),
+ str2scm (to),
Utils::
- string2SCM (message),
+ str2scm (message),
SCM_UNDEFINED));
}
else
Interp::bot->botInterp->RunHooks (Hook::SEND_CTCP,
- MNICK + " " + to + " " +
- command + " " + message,
- scm_listify (Utils::
- string2SCM (MNICK),
- Utils::
- string2SCM (to),
- Utils::
- string2SCM
- (command),
- Utils::
- string2SCM (message),
- SCM_UNDEFINED));
+ MNICK + " " + to + " " +
+ command + " " + message,
+ scm_list_n (Utils::
+ str2scm (MNICK),
+ Utils::
+ str2scm (to),
+ Utils::
+ str2scm
+ (command),
+ Utils::
+ str2scm (message),
+ SCM_UNDEFINED));
#endif
}
// hook stuff
#ifdef USESCRIPTS
if (message[0] != '\001')
- if (Utils::isChannel (dest))
+ if (Utils::channel_p (dest))
Interp::bot->botInterp->RunHooks (Hook::SEND_PUBLIC,
Interp::bot->nickName + " " + dest +
" " + message,
- scm_listify (Utils::
- string2SCM (Interp::bot->nickName),
- Utils::
- string2SCM (dest),
- Utils::
- string2SCM
- (message), SCM_UNDEFINED));
+ scm_list_n
+ (Utils::str2scm
+ (Interp::bot->nickName),
+ Utils::str2scm (dest),
+ Utils::str2scm (message),
+ SCM_UNDEFINED));
else
- Interp::bot->botInterp->RunHooks (Hook::SEND_MESSAGE,
- Interp::bot->nickName + " " +
- message,
- scm_listify (Utils::
- string2SCM (Interp::bot->nickName),
- Utils::
- string2SCM
- (message), SCM_UNDEFINED));
+ Interp::bot->botInterp->RunHooks
+ (Hook::SEND_MESSAGE,
+ Interp::bot->nickName + " " + dest +
+ message,
+ scm_list_n (Utils::str2scm (Interp::bot->nickName),
+ Utils::str2scm (dest),
+ Utils::str2scm
+ (message), SCM_UNDEFINED));
#endif
}
{
addLine(String("WHO ") + who,
WHO_PRIORITY, WHO_PENALTY, ServerQueueItem::WHO);
+
+#ifdef USESCRIPTS
+ Interp::bot->botInterp->RunHooks (Hook::SEND_WHO,
+ who,
+ scm_list_n (Utils::
+ str2scm (who),
+ SCM_UNDEFINED));
+#endif
}
void
{
addLine(String("WHOIS ") + nick,
NICK_PRIORITY, WHOIS_PENALTY, ServerQueueItem::WHOIS);
+
+#ifdef USESCRIPTS
+ Interp::bot->botInterp->RunHooks (Hook::SEND_WHOIS,
+ nick,
+ scm_list_n (Utils::
+ str2scm (nick),
+ SCM_UNDEFINED));
+#endif
}