Permalink
Browse files

Modules: Add a module version of CJob

Signed-off-by: Uli Schlachter <psychon@znc.in>
  • Loading branch information...
1 parent 0fddbba commit 308df2151192f297516d5f8cf0fdacd4adcf4d7a @psychon psychon committed Aug 6, 2014
Showing with 89 additions and 0 deletions.
  1. +37 −0 include/znc/Modules.h
  2. +2 −0 include/znc/Threads.h
  3. +50 −0 src/Modules.cpp
View
@@ -19,6 +19,7 @@
#include <znc/zncconfig.h>
#include <znc/WebModules.h>
+#include <znc/Threads.h>
#include <znc/main.h>
#include <set>
#include <queue>
@@ -177,6 +178,29 @@ class CFPTimer : public CTimer {
FPTimer_t m_pFBCallback;
};
+#ifdef HAVE_PTHREAD
+/// A CJob version which can be safely used in modules. The job will be
+/// cancelled when the module is unloaded.
+class CModuleJob : public CJob {
+public:
+ CModuleJob(CModule *pModule, const CString& sName, const CString& sDesc)
+ : CJob(), m_pModule(pModule), m_sName(sName), m_sDescription(sDesc) {
+ }
+ virtual ~CModuleJob();
+
+ // Getters
+ CModule* GetModule() const { return m_pModule; }
+ const CString& GetName() const { return m_sName; }
+ const CString& GetDescription() const { return m_sDescription; }
+ // !Getters
+
+protected:
+ CModule* m_pModule;
+ const CString m_sName;
+ const CString m_sDescription;
+};
+#endif
+
class CModInfo {
public:
typedef CModule* (*ModLoader)(ModHandle p, CUser* pUser, CIRCNetwork* pNetwork, const CString& sModName, const CString& sModPath);
@@ -885,6 +909,16 @@ class CModule {
virtual void ListSockets();
// !Socket stuff
+#ifdef HAVE_PTHREAD
+ // Job stuff
+ void AddJob(CModuleJob *pJob);
+ void CancelJob(CModuleJob *pJob);
+ bool CancelJob(const CString& sJobName);
+ void CancelJobs(const std::set<CModuleJob*>& sJobs);
+ bool UnlinkJob(CModuleJob *pJob);
+ // !Job stuff
+#endif
+
// Command stuff
/// Register the "Help" command.
void AddHelpCommand();
@@ -1052,6 +1086,9 @@ class CModule {
CString m_sDescription;
std::set<CTimer*> m_sTimers;
std::set<CSocket*> m_sSockets;
+#ifdef HAVE_PTHREAD
+ std::set<CModuleJob*> m_sJobs;
+#endif
ModHandle m_pDLL;
CSockManager* m_pManager;
CUser* m_pUser;
@@ -213,6 +213,8 @@ class CThread {
* After you create a new instance of your class, you can pass it to
* CThreadPool()::Get().addJob(job) to start it. The thread pool automatically
* deletes your class after it finished.
+ *
+ * For modules you should use CModuleJob instead.
*/
class CJob {
public:
View
@@ -157,6 +157,10 @@ CModule::~CModule() {
}
SaveRegistry();
+
+#ifdef HAVE_PTHREAD
+ CancelJobs(m_sJobs);
+#endif
}
void CModule::SetUser(CUser* pUser) { m_pUser = pUser; }
@@ -449,6 +453,52 @@ void CModule::ListSockets() {
PutModule(Table);
}
+#ifdef HAVE_PTHREAD
+CModuleJob::~CModuleJob()
+{
+ m_pModule->UnlinkJob(this);
+}
+
+void CModule::AddJob(CModuleJob *pJob)
+{
+ CThreadPool::Get().addJob(pJob);
+ m_sJobs.insert(pJob);
+}
+
+void CModule::CancelJob(CModuleJob *pJob)
+{
+ if (pJob == NULL)
+ return;
+ // Destructor calls UnlinkJob and removes the job from m_sJobs
+ CThreadPool::Get().cancelJob(pJob);
+}
+
+bool CModule::CancelJob(const CString& sJobName)
+{
+ set<CModuleJob*>::iterator it;
+ for (it = m_sJobs.begin(); it != m_sJobs.end(); ++it) {
+ if ((*it)->GetName().Equals(sJobName)) {
+ CancelJob(*it);
+ return true;
+ }
+ }
+ return false;
+}
+
+void CModule::CancelJobs(const std::set<CModuleJob*>& sJobs)
+{
+ set<CJob*> sPlainJobs(sJobs.begin(), sJobs.end());
+
+ // Destructor calls UnlinkJob and removes the jobs from m_sJobs
+ CThreadPool::Get().cancelJobs(sPlainJobs);
+}
+
+bool CModule::UnlinkJob(CModuleJob *pJob)
+{
+ return 0 != m_sJobs.erase(pJob);
+}
+#endif
+
bool CModule::AddCommand(const CModCommand& Command)
{
if (Command.GetFunction() == NULL)

0 comments on commit 308df21

Please sign in to comment.