1 /*
2  * This file is part of Licq, an instant messaging client for UNIX.
3  * Copyright (C) 2013 Licq Developers <licq-dev@googlegroups.com>
4  *
5  * Please refer to the COPYRIGHT file distributed with this source
6  * distribution for the names of the individual contributors.
7  *
8  * Licq is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * Licq is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with Licq; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21  */
22 
23 #ifndef LICQDAEMON_PLUGININSTANCE_H
24 #define LICQDAEMON_PLUGININSTANCE_H
25 
26 #include <licq/plugin/plugininstance.h>
27 
28 #include "pluginthread.h"
29 
30 #include <boost/enable_shared_from_this.hpp>
31 
32 namespace LicqDaemon
33 {
34 
35 class PluginInstance : public virtual Licq::PluginInstance,
36                        public boost::enable_shared_from_this<PluginInstance>
37 {
38 public:
39   typedef boost::shared_ptr<PluginInstance> Ptr;
40 
41   PluginInstance(int id, PluginThread::Ptr thread);
42   ~PluginInstance();
43 
44   // From Licq::PluginInstance
45   int id() const;
46   boost::shared_ptr<Licq::PluginInterface> internalInterface();
47 
48   /**
49    * Check if a thread belongs to this plugin
50    *
51    * @param thread Thread to test
52    * @return True if thread is the main thread for this plugin
53    */
54   bool isThread(const pthread_t& thread) const;
55 
56   /**
57    * Create the plugin instance
58    *
59    * @param callback Called in the thread just before the instance is created
60    * @return True if the plugin was created successfully
61    */
62   bool create(void (*callback)(const PluginInstance&));
63 
64   /**
65    * Initialize the plugin
66    *
67    * @param argc Number of command line parameters
68    * @param argv Command line parameters
69    * @return True if initialization was successful
70    */
71   bool init(int argc, char** argv);
72 
73   /**
74    * Run the plugin
75    *
76    * @param startCallback Called in the thread just before run is called
77    * @param exitCallback Called in the thread just after run returns
78    */
79   void run(void (*startCallback)(const PluginInstance&),
80            void (*exitCallback)(const PluginInstance&));
81 
82   /**
83    * Tell a plugin to shut down
84    */
85   void shutdown();
86 
87   /**
88    * Wait for the plugin to stop
89    *
90    * @return Exit code from plugin thread
91    */
92   int joinThread();
93 
94   /**
95    * Cancel the plugin's thread
96    */
97   void cancelThread();
98 
99   // For use by unit test
setIsRunning(bool running)100   void setIsRunning(bool running) { myIsRunning = running; }
101 
isRunning()102   bool isRunning() const { return myIsRunning; }
103 
104 protected:
105   virtual void createInterface() = 0;
106   virtual boost::shared_ptr<Licq::PluginInterface> interface() = 0;
107   virtual boost::shared_ptr<const Licq::PluginInterface> interface() const = 0;
108 
109 private:
110   /// Entry point for creating plugin in plugin's thread
111   static void createThreadEntry(void* plugin);
112 
113   /// Entry point for calling init() in plugin's thread
114   static bool initThreadEntry(void* plugin);
115 
116   /// Entry point for calling run() in plugin's thread
117   static void* startThreadEntry(void* plugin);
118 
119   const int myId;
120   PluginThread::Ptr myThread;
121   bool myIsRunning;
122 
123   int myArgc;
124   char** myArgv;
125   char** myArgvCopy;
126 
127   void (*myCreateCallback)(const PluginInstance&);
128   void (*myStartCallback)(const PluginInstance&);
129   void (*myExitCallback)(const PluginInstance&);
130 };
131 
132 } // namespace LicqDaemon
133 
134 #endif
135