mirror of
https://github.com/anope/anope.git
synced 2026-07-06 10:33:12 +02:00
Moved signal/thread/mode checking to use signal pipes
This commit is contained in:
@@ -375,6 +375,16 @@ class StackerInfo
|
||||
class CoreExport ModeManager
|
||||
{
|
||||
protected:
|
||||
class ModePipe : public Pipe
|
||||
{
|
||||
public:
|
||||
/** Called when there are modes to be set
|
||||
*/
|
||||
void OnNotify();
|
||||
};
|
||||
|
||||
static ModePipe *mpipe;
|
||||
|
||||
/* List of pairs of user/channels and their stacker info */
|
||||
static std::list<std::pair<Base *, StackerInfo *> > StackerObjects;
|
||||
|
||||
|
||||
+15
-16
@@ -241,22 +241,6 @@ class DatabaseException : public CoreException
|
||||
virtual ~DatabaseException() throw() { }
|
||||
};
|
||||
|
||||
class Signal
|
||||
{
|
||||
static std::vector<Signal *> SignalHandlers;
|
||||
static void SignalHandler(int signal);
|
||||
|
||||
struct sigaction action, old;
|
||||
sig_atomic_t called;
|
||||
public:
|
||||
static void Process();
|
||||
|
||||
int signal;
|
||||
|
||||
Signal(int s);
|
||||
~Signal();
|
||||
virtual void OnSignal() = 0;
|
||||
};
|
||||
|
||||
/** Debug cast to be used instead of dynamic_cast, this uses dynamic_cast
|
||||
* for debug builds and static_cast on releass builds to speed up the program
|
||||
@@ -406,6 +390,21 @@ template class Service<Base>;
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
class Signal : public Pipe
|
||||
{
|
||||
static std::vector<Signal *> SignalHandlers;
|
||||
static void SignalHandler(int signal);
|
||||
|
||||
struct sigaction action, old;
|
||||
public:
|
||||
int signal;
|
||||
|
||||
Signal(int s);
|
||||
~Signal();
|
||||
|
||||
virtual void OnNotify() = 0;
|
||||
};
|
||||
|
||||
class ConvertException : public CoreException
|
||||
{
|
||||
public:
|
||||
|
||||
+11
-30
@@ -12,36 +12,9 @@ typedef pthread_mutex_t MutexHandle;
|
||||
typedef pthread_cond_t CondHandle;
|
||||
#endif
|
||||
|
||||
class ThreadEngine;
|
||||
class Thread;
|
||||
|
||||
extern CoreExport ThreadEngine threadEngine;
|
||||
|
||||
class CoreExport ThreadEngine
|
||||
{
|
||||
public:
|
||||
/* Vector of threads */
|
||||
std::vector<Thread *> threads;
|
||||
|
||||
/** Threadengines constructor
|
||||
*/
|
||||
ThreadEngine();
|
||||
|
||||
/** Threadengines destructor
|
||||
*/
|
||||
~ThreadEngine();
|
||||
|
||||
/** Start a new thread
|
||||
* @param thread A pointer to a newley allocated thread
|
||||
*/
|
||||
void Start(Thread *thread);
|
||||
|
||||
/** Check for finished threads
|
||||
*/
|
||||
void Process();
|
||||
};
|
||||
|
||||
class CoreExport Thread : public Extensible
|
||||
class CoreExport Thread : public Pipe, public Extensible
|
||||
{
|
||||
private:
|
||||
/* Set to true to tell the thread to finish and we are waiting for it */
|
||||
@@ -71,14 +44,22 @@ class CoreExport Thread : public Extensible
|
||||
*/
|
||||
void Exit();
|
||||
|
||||
/** Launch the thread
|
||||
*/
|
||||
void Start();
|
||||
|
||||
/** Returns the exit state of the thread
|
||||
* @return true if we want to exit
|
||||
*/
|
||||
bool GetExitState() const;
|
||||
|
||||
/** Called to run the thread, should be overloaded
|
||||
/** Called when this thread should be joined to
|
||||
*/
|
||||
virtual void Run();
|
||||
void OnNotify();
|
||||
|
||||
/** Called when the thread is run.
|
||||
*/
|
||||
virtual void Run() = 0;
|
||||
};
|
||||
|
||||
class CoreExport Mutex
|
||||
|
||||
@@ -67,8 +67,6 @@ class LDAPService : public LDAPProvider, public Thread, public Condition
|
||||
static const int version = LDAP_VERSION3;
|
||||
if (ldap_set_option(this->con, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_OPT_SUCCESS)
|
||||
throw LDAPException("Unable to set protocol version for " + this->name + ": " + Anope::LastError());
|
||||
|
||||
threadEngine.Start(this);
|
||||
}
|
||||
|
||||
~LDAPService()
|
||||
@@ -400,6 +398,7 @@ class ModuleLDAP : public Module, public Pipe
|
||||
try
|
||||
{
|
||||
LDAPService *ss = new LDAPService(this, connname, server, port, admin_binddn, admin_password);
|
||||
ss->Start();
|
||||
this->LDAPServices.insert(std::make_pair(connname, ss));
|
||||
|
||||
Log(LOG_NORMAL, "ldap") << "LDAP: Successfully connected to server " << connname << " (" << server << ")";
|
||||
|
||||
@@ -164,7 +164,7 @@ class ModuleSQL : public Module, public Pipe
|
||||
ModuleManager::Attach(i, this, 2);
|
||||
|
||||
DThread = new DispatcherThread();
|
||||
threadEngine.Start(DThread);
|
||||
DThread->Start();
|
||||
|
||||
OnReload();
|
||||
}
|
||||
|
||||
+7
-6
@@ -182,7 +182,7 @@ class SignalReload : public Signal
|
||||
public:
|
||||
SignalReload(int sig) : Signal(sig) { }
|
||||
|
||||
void OnSignal()
|
||||
void OnNotify()
|
||||
{
|
||||
Log() << "Received SIGHUP: Saving databases & rehashing configuration";
|
||||
|
||||
@@ -208,7 +208,7 @@ class SignalExit : public Signal
|
||||
public:
|
||||
SignalExit(int sig) : Signal(sig) { }
|
||||
|
||||
void OnSignal()
|
||||
void OnNotify()
|
||||
{
|
||||
#ifndef _WIN32
|
||||
Log() << "Received " << strsignal(this->signal) << " signal (" << this->signal << "), exiting.";
|
||||
@@ -228,7 +228,7 @@ class SignalNothing : public Signal
|
||||
public:
|
||||
SignalNothing(int sig) : Signal(sig) { }
|
||||
|
||||
void OnSignal() { }
|
||||
void OnNotify() { }
|
||||
};
|
||||
|
||||
void Init(int ac, char **av)
|
||||
@@ -397,9 +397,10 @@ void Init(int ac, char **av)
|
||||
/* Announce ourselves to the logfile. */
|
||||
Log() << "Anope " << Anope::Version() << " starting up" << (debug || readonly ? " (options:" : "") << (debug ? " debug" : "") << (readonly ? " readonly" : "") << (debug || readonly ? ")" : "");
|
||||
|
||||
static SignalReload sig_hup(SIGHUP);
|
||||
static SignalExit sig_term(SIGTERM), sig_int(SIGINT);
|
||||
static SignalNothing sig_pipe(SIGPIPE);
|
||||
new SignalReload(SIGHUP);
|
||||
new SignalExit(SIGTERM);
|
||||
new SignalExit(SIGINT);
|
||||
new SignalNothing(SIGPIPE);
|
||||
|
||||
/* Initialize multi-language support */
|
||||
Log(LOG_DEBUG) << "Loading Languages...";
|
||||
|
||||
+4
-2
@@ -51,7 +51,8 @@ bool Mail(User *u, NickCore *nc, BotInfo *service, const Anope::string &subject,
|
||||
else
|
||||
{
|
||||
u->lastmail = nc->lastmail = Anope::CurTime;
|
||||
threadEngine.Start(new MailThread(nc->display, nc->email, subject, message));
|
||||
Thread *t = new MailThread(nc->display, nc->email, subject, message);
|
||||
t->Start();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -64,7 +65,8 @@ bool Mail(NickCore *nc, const Anope::string &subject, const Anope::string &messa
|
||||
return false;
|
||||
|
||||
nc->lastmail = Anope::CurTime;
|
||||
threadEngine.Start(new MailThread(nc->display, nc->email, subject, message));
|
||||
Thread *t = new MailThread(nc->display, nc->email, subject, message);
|
||||
t->Start();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
+2
-24
@@ -207,21 +207,10 @@ void Signal::SignalHandler(int signal)
|
||||
{
|
||||
for (unsigned i = 0, j = SignalHandlers.size(); i < j; ++i)
|
||||
if (SignalHandlers[i]->signal == signal)
|
||||
SignalHandlers[i]->called = true;
|
||||
SignalHandlers[i]->Notify();
|
||||
}
|
||||
|
||||
void Signal::Process()
|
||||
{
|
||||
for (unsigned i = 0, j = SignalHandlers.size(); i < j; ++i)
|
||||
if (SignalHandlers[i]->called == true)
|
||||
{
|
||||
Signal *s = SignalHandlers[i];
|
||||
s->called = false;
|
||||
s->OnSignal();
|
||||
}
|
||||
}
|
||||
|
||||
Signal::Signal(int s) : called(false), signal(s)
|
||||
Signal::Signal(int s) : Pipe(), signal(s)
|
||||
{
|
||||
memset(&this->old, 0, sizeof(this->old));
|
||||
|
||||
@@ -244,7 +233,6 @@ Signal::~Signal()
|
||||
sigaction(this->signal, &this->old, NULL);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/** The following comes from InspIRCd to get the full path of the Anope executable
|
||||
@@ -355,9 +343,6 @@ int main(int ac, char **av, char **envp)
|
||||
{
|
||||
Log(LOG_DEBUG_2) << "Top of main loop";
|
||||
|
||||
/* Process signals */
|
||||
Signal::Process();
|
||||
|
||||
/* Process timers */
|
||||
if (Anope::CurTime - last_check >= Config->TimeoutCheck)
|
||||
{
|
||||
@@ -365,13 +350,6 @@ int main(int ac, char **av, char **envp)
|
||||
last_check = Anope::CurTime;
|
||||
}
|
||||
|
||||
/* Free up any finished threads */
|
||||
threadEngine.Process();
|
||||
|
||||
/* Process any modes that need to be (un)set */
|
||||
if (Me->IsSynced())
|
||||
ModeManager::ProcessModes();
|
||||
|
||||
/* Process the socket engine */
|
||||
SocketEngine::Process();
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "services.h"
|
||||
#include "modules.h"
|
||||
|
||||
ModeManager::ModePipe *ModeManager::mpipe = NULL;
|
||||
/* List of pairs of user/channels and their stacker info */
|
||||
std::list<std::pair<Base *, StackerInfo *> > ModeManager::StackerObjects;
|
||||
|
||||
@@ -345,6 +346,16 @@ void StackerInfo::AddMode(Mode *mode, bool Set, const Anope::string &Param)
|
||||
list->push_back(std::make_pair(mode, Param));
|
||||
}
|
||||
|
||||
/** Called when there are modes to be set
|
||||
*/
|
||||
void ModeManager::ModePipe::OnNotify()
|
||||
{
|
||||
if (!Me || !Me->IsSynced())
|
||||
return;
|
||||
|
||||
ModeManager::ProcessModes();
|
||||
}
|
||||
|
||||
/** Get the stacker info for an item, if one doesnt exist it is created
|
||||
* @param Item The user/channel etc
|
||||
* @return The stacker info
|
||||
@@ -360,6 +371,11 @@ StackerInfo *ModeManager::GetInfo(Base *Item)
|
||||
|
||||
StackerInfo *s = new StackerInfo();
|
||||
StackerObjects.push_back(std::make_pair(Item, s));
|
||||
|
||||
if (mpipe == NULL)
|
||||
mpipe = new ModePipe();
|
||||
mpipe->Notify();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
+6
-27
@@ -1,46 +1,22 @@
|
||||
#include "services.h"
|
||||
|
||||
ThreadEngine threadEngine;
|
||||
|
||||
/** Check for finished threads
|
||||
*/
|
||||
void ThreadEngine::Process()
|
||||
{
|
||||
for (unsigned i = this->threads.size(); i > 0; --i)
|
||||
{
|
||||
Thread *t = this->threads[i - 1];
|
||||
|
||||
if (t->GetExitState())
|
||||
{
|
||||
t->Join();
|
||||
delete t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Threads constructor
|
||||
*/
|
||||
Thread::Thread() : exit(false)
|
||||
{
|
||||
threadEngine.threads.push_back(this);
|
||||
}
|
||||
|
||||
/** Threads destructor
|
||||
*/
|
||||
Thread::~Thread()
|
||||
{
|
||||
std::vector<Thread *>::iterator it = std::find(threadEngine.threads.begin(), threadEngine.threads.end(), this);
|
||||
|
||||
if (it != threadEngine.threads.end())
|
||||
{
|
||||
threadEngine.threads.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
/** Sets the exit state as true informing the thread we want it to shut down
|
||||
*/
|
||||
void Thread::SetExitState()
|
||||
{
|
||||
this->Notify();
|
||||
exit = true;
|
||||
}
|
||||
|
||||
@@ -52,8 +28,11 @@ bool Thread::GetExitState() const
|
||||
return exit;
|
||||
}
|
||||
|
||||
/** Called to run the thread, should be overloaded
|
||||
/** Called when this thread should be joined to
|
||||
*/
|
||||
void Thread::Run()
|
||||
void Thread::OnNotify()
|
||||
{
|
||||
this->Join();
|
||||
this->SetFlag(SF_DEAD);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,22 @@
|
||||
#include "services.h"
|
||||
|
||||
/* Threadengine attributes used by this thread engine */
|
||||
static pthread_attr_t threadengine_attr;
|
||||
static inline pthread_attr_t *get_engine_attr()
|
||||
{
|
||||
/* Threadengine attributes used by this thread engine */
|
||||
static pthread_attr_t attr;
|
||||
static bool inited = false;
|
||||
|
||||
if (inited == false)
|
||||
{
|
||||
if (pthread_attr_init(&attr))
|
||||
throw CoreException("Error calling pthread_attr_init");
|
||||
if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE))
|
||||
throw CoreException("Unable to mark threads as joinable");
|
||||
inited = true;
|
||||
}
|
||||
|
||||
return &attr;
|
||||
}
|
||||
|
||||
/** Entry point used for the threads
|
||||
* @param parameter A Thread* cast to a void*
|
||||
@@ -14,23 +29,6 @@ static void *entry_point(void *parameter)
|
||||
pthread_exit(0);
|
||||
}
|
||||
|
||||
/** Threadengines constructor
|
||||
*/
|
||||
ThreadEngine::ThreadEngine()
|
||||
{
|
||||
if (pthread_attr_init(&threadengine_attr))
|
||||
throw CoreException("ThreadEngine: Error calling pthread_attr_init");
|
||||
if (pthread_attr_setdetachstate(&threadengine_attr, PTHREAD_CREATE_JOINABLE))
|
||||
throw CoreException("ThreadEngine: Unable to mark threads as joinable");
|
||||
}
|
||||
|
||||
/** Threadengines destructor
|
||||
*/
|
||||
ThreadEngine::~ThreadEngine()
|
||||
{
|
||||
pthread_attr_destroy(&threadengine_attr);
|
||||
}
|
||||
|
||||
/** Join to the thread, sets the exit state to true
|
||||
*/
|
||||
void Thread::Join()
|
||||
@@ -47,15 +45,14 @@ void Thread::Exit()
|
||||
pthread_exit(0);
|
||||
}
|
||||
|
||||
/** Start a new thread
|
||||
* @param thread A pointer to a newley allocated thread
|
||||
/** Launch the thread
|
||||
*/
|
||||
void ThreadEngine::Start(Thread *thread)
|
||||
void Thread::Start()
|
||||
{
|
||||
if (pthread_create(&thread->Handle, &threadengine_attr, entry_point, thread))
|
||||
if (pthread_create(&this->Handle, get_engine_attr(), entry_point, this))
|
||||
{
|
||||
delete thread;
|
||||
throw CoreException(Anope::string("Unable to create thread: ") + Anope::LastError());
|
||||
this->SetFlag(SF_DEAD);
|
||||
throw CoreException("Unable to create thread: " + Anope::LastError());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,18 +11,6 @@ static DWORD WINAPI entry_point(void *parameter)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Threadengines constructor
|
||||
*/
|
||||
ThreadEngine::ThreadEngine()
|
||||
{
|
||||
}
|
||||
|
||||
/** Threadengines destructor
|
||||
*/
|
||||
ThreadEngine::~ThreadEngine()
|
||||
{
|
||||
}
|
||||
|
||||
/** Join to the thread, sets the exit state to true
|
||||
*/
|
||||
void Thread::Join()
|
||||
@@ -39,17 +27,16 @@ void Thread::Exit()
|
||||
ExitThread(0);
|
||||
}
|
||||
|
||||
/** Start a new thread
|
||||
* @param thread A pointer to a newley allocated thread
|
||||
/** Launch the thread
|
||||
*/
|
||||
void ThreadEngine::Start(Thread *thread)
|
||||
void Thread::Start()
|
||||
{
|
||||
thread->Handle = CreateThread(NULL, 0, entry_point, thread, 0, NULL);
|
||||
this->Handle = CreateThread(NULL, 0, entry_point, this, 0, NULL);
|
||||
|
||||
if (!thread->Handle)
|
||||
if (!this->Handle)
|
||||
{
|
||||
delete thread;
|
||||
throw CoreException(Anope::string("Unable to create thread: ") + Anope::LastError());
|
||||
this->SetFlag(SF_DEAD);
|
||||
throw CoreException("Unable to create thread: " + Anope::LastError());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user