iotivity 0.9.0
[platform/upstream/iotivity.git] / service / protocol-plugin / lib / cpluff / libcpluff / docsrc / mainprog.dox
1 /*-------------------------------------------------------------------------
2  * C-Pluff, a plug-in framework for C
3  * Copyright 2007 Johannes Lehtinen
4  * 
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included
13  * in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  *-----------------------------------------------------------------------*/
23
24 /**
25  * @page cMainProgram Main program
26  *
27  * @section cMainProgramOverview Overview
28  *
29  * The main program is the part of executable that is located outside the
30  * plug-in framework. The main program is responsible for setting up
31  * the plug-in framework and for loading the desired set of
32  * @ref plugin "plug-ins". The main program should preferably be very
33  * thin, a mere plug-in loader, because it can not fully participate in plug-in
34  * interaction. C-Pluff distribution provides a plug-in loader,
35  * @ref cpluff-loader, which can be used as a generic main program for
36  * arbitrary plug-in collections.
37  *
38  * @section cMainProgramResponsibilities Responsibilities
39  *
40  * The main program has several responsibilities:
41  *
42  * - @ref cMainProgramInitFramework "initializing the plug-in framework"
43  * - @ref cMainProgramCreateContext "creating a plug-in context"
44  * - @ref cMainProgramLoad "loading plug-ins"
45  * - @ref cMainProgramExec "controlling plug-in execution"
46  * - @ref cMainProgramChange "changing plug-in configuration" (opt.)
47  * - @ref cMainProgramDestroyFramework "destroying the plug-in framework"
48  *
49  * @subsection cMainProgramInitFramework Initializing the plug-in framework
50  *
51  * Plug-in framework, or the C-Pluff library, must be initialized before its
52  * services can be used.
53  * Initialization is not a thread-safe operation and should generally be
54  * done by the main program before any additional plug-in framework accessing
55  * threads are started. Initialization is done by calling ::cp_init.
56  * Additionally, the main program can use ::cp_set_fatal_error_handler to register
57  * a function that is called when a fatal error occurs. A fatal error is one
58  * that prevents the framework from continuing operation. For example,
59  * errors in operating system locking operations and a NULL pointer being
60  * passed as an argument which is expected to have a non-NULL value are fatal
61  * erors.
62  *
63  * Here is an example of possible initialization code.
64  *
65  * @code
66  * #include <locale.h>
67  * #include <cpluff.h>
68  *
69  * void handle_fatal_error(const char *msg) {
70  *
71  *   // ... log error, flush logs, send bug report, etc. ...
72  *
73  *   fprintf(stderr, "A fatal error occurred: %s\n", msg);
74  *   abort();
75  * }
76  *
77  * void initialize(void) {
78  *   cp_status_t status;
79  *
80  *   setlocale(LC_ALL, "");
81  *   cp_set_fatal_error_handler(handle_fatal_error);
82  *   status = cp_init();
83  *   if (status != CP_OK) {
84  *     // ... handle initialization failure ...
85  *   }
86  * }
87  * @endcode
88  *
89  * @subsection cMainProgramCreateContext Creating a plug-in context
90  *
91  * A plug-in context represents the co-operation environment of a set of
92  * plug-ins from the perspective of a particular participating plug-in or
93  * the perspective of the main program. From main program perspective, a
94  * plug-in context is a container for a set of plug-ins. A plug-in can interact
95  * with other plug-ins in the same container.
96  *
97  * An extensible application can have more than one plug-in container but
98  * usually one container should suffice. Due to the nature of C programs,
99  * plug-ins deployed to different containers are not very well insulated from
100  * each other. For example, global variables provided by a plug-in in one
101  * container are visible to all plug-ins in all containers. Also, by placing
102  * all plug-ins in the same container they can more efficiently share common
103  * base components which themselves might provide extensibility.
104  *
105  * A main program creates a plug-in context, to be used as a container for
106  * plugins, using ::cp_create_context.
107  *
108  * @code
109  * #include <cpluff.h>
110  *
111  * cp_context_t *ctx;
112  *
113  * void create_context(void) {
114  *   cp_status_t status;
115  *
116  *   ctx = cp_create_context(&status);
117  *   if (ctx == NULL) {
118  *     // ... handle initialization failure ...
119  *   }
120  * }
121  * @endcode
122  *
123  * @subsection cMainProgramLoad Loading plug-ins
124  *
125  * An extensible application is made of plug-ins that can be added and removed
126  * dynamically. The plug-ins are loaded by the main program using the services
127  * provided by the framework. The framework provides couple of alternative
128  * ways of loading plug-ins.
129  *
130  * As a lowest level operation, the main program can
131  * load individual plug-ins from known locations using
132  * ::cp_load_plugin_descriptor and ::cp_install_plugin. Here is example code
133  * that loads a set of plug-ins from file system locations listed in a file.
134  *
135  * @code
136  * #include <stdio.h>
137  * #include <cpluff.h>
138  *
139  * extern cp_context_t *ctx;
140  * static const char pluginListFile[] = "/etc/example/plugins.list";
141  *
142  * void load_plugins(void) {
143  *   char plugindir[128];
144  *   FILE *lf;
145  *
146  *   // Open plug-in list file
147  *   lf = fopen(pluginListFile, "r");
148  *   if (lf == NULL) {
149  *     // ... handle loading failure ...
150  *   }
151  *
152  *   // Load each listed plug-in
153  *   while (fgets(plugindir, 128, lf) != NULL) {
154  *     cp_plugin_info_t *plugininfo;
155  *     cp_status_t status;
156  *     int i;
157  *
158  *     // Remove possible trailing newline from plug-in location
159  *     for (i = 0; plugindir[i + 1] != '\0'; i++);
160  *     if (plugindir[i] == '\n') {
161  *       plugindir[i] = '\0';
162  *     }
163  *
164  *     // Load plug-in descriptor
165  *     plugininfo = cp_load_plugin_descriptor(ctx, plugindir, &status);
166  *     if (pinfo == NULL) {
167  *       // ... handle loading failure ...
168  *     }
169  *
170  *     // Install plug-in descriptor
171  *     status = cp_install_plugin(ctx, plugininfo);
172  *     if (status != CP_OK) {
173  *       // ... handle loading failure ...
174  *     }
175  *
176  *     // Release plug-in descriptor information
177  *     cp_release_info(ctx, plugininfo);
178  *   }
179  *
180  *   // Close plug-in list file
181  *   fclose(lf);
182  * }
183  * @endcode
184  *
185  * Alternatively, the main program can register and load plug-in collections.
186  * A plug-in collection is a file system directory which includes individual
187  * plug-ins in subdirectories, one plug-in in each subdirectory. Plug-in
188  * collections can be registered with a plug-in context using
189  * ::cp_register_pcollection. Plug-ins of the collection can then be scanned
190  * and loaded using ::cp_scan_plugins. Here is example code loading plug-ins
191  * from a plug-in collection.
192  * 
193  * @code
194  * #include <cpluff.h>
195  *
196  * extern cp_context_t *ctx;
197  * static const char pluginCollectionDir[] = "/etc/example/plugins";
198  *
199  * void load_plugins(void) {
200  *   cp_status_t status;
201  *
202  *   status = cp_register_pcollection(ctx, pluginCollectionDir);
203  *   if (status != CP_OK) {
204  *     // ... handle loading failure ...
205  *   }
206  *   status = cp_scan_plugins(ctx, 0);
207  *   if (status != CP_OK) {
208  *     // ... handle loading failure ...
209  *     // (notice that some plug-ins might have been loaded)
210  *   }
211  * }
212  * @endcode
213  *
214  * @subsection cMainProgramExec Controlling plug-in execution
215  *
216  * The main program controls plug-in execution by starting and stopping
217  * plug-ins and by executing run functions registered by plug-ins.
218  * Additionally, the main program can pass startup arguments to plug-ins.
219  *
220  * When plug-ins are installed they are not yet activated and their
221  * runtime library is not even loaded at that point. The main program
222  * typically activates plug-ins by starting a main plug-in
223  * responsible for user interface or core application logic. This plug-in
224  * then implicitly causes other plug-ins to be activated via dependencies and
225  * by dynamically resolving symbols provided by other plug-ins. Plug-ins
226  * recursively activate each other until all initially needed plug-ins have
227  * been started. Some plug-ins might be activated at a later time when their
228  * functionality is needed, for example due to user action.
229  *
230  * If a plug-in needs to perform background operations, that is operations
231  * executed outside the invocation of plug-in provided interface functions,
232  * then it can either start a new thread or it can register a run function.
233  * A run function is a function that is typically executed as part of the
234  * main loop by the main program.
235  *
236  * The following example code shows how a main program might initialize
237  * plug-in startup arguments using ::cp_set_context_args, start the core
238  * plug-in using ::cp_start_plugin and then execute plug-in run functions
239  * using ::cp_run_plugins.
240  *
241  * @code
242  * #include <cpluff.h>
243  *
244  * extern cp_context_t *ctx;
245  * static const char corePluginId[] = "org.example.core";
246  *
247  * void run_plugins(char *argv[]) {
248  *   cp_status_t status;
249  *
250  *   // Set plug-in startup arguments
251  *   cp_set_context_args(ctx, argv);
252  *
253  *   // Start the core plug-in, possibly activating other plug-ins as well
254  *   status = cp_start_plugin(ctx, corePluginId);
255  *   if (status != CP_OK) {
256  *     // ... handle startup failure ...
257  *   }
258  *
259  *   // Execute plug-ins until there is no more work to be done
260  *   cp_run_plugins(ctx);
261  * }
262  *
263  * int main(int argc, char *argv[]) {
264  *   // ... do initialization and load plug-ins ...
265  *
266  *   run_plugins(argv);
267  *
268  *   // ... do destruction ...
269  * }
270  * @endcode
271  *
272  * Alternatively, if the main program has some operations it must perform
273  * as part of the main loop, the call to ::cp_run_plugins can be replaced
274  * by code using ::cp_run_plugins_step like in the following example.
275  *
276  * @code
277  * void mainloop(void) {
278  *   int finished = 0;
279  *
280  *   while (!finished) {
281  *     // ... do main program specific operations ...
282  *
283  *     finished = !cp_run_plugins_step(ctx);
284  *   }
285  * }
286  * @endcode
287  *
288  * @subsection cMainProgramChange Changing plug-in configuration
289  *
290  * C-Pluff has been designed to allow dynamic changes to the plug-in
291  * configuration, that is plug-ins being added or removed without shutting
292  * down the application or the framework. It is the responsibility of the
293  * main program to manage such changes if the application is to support
294  * dynamic configuration changes.
295  *
296  * Adding plug-ins is straightforward because there is no need to
297  * consider dependencies of active plug-ins. For example, if one uses
298  * plug-in collections as introduced above then new plug-ins can be
299  * deployed under the plug-in collection directory while the application is
300  * running and the main program can load them incrementally by calling
301  * ::cp_scan_plugins again. This call might be activated by some user interface
302  * element, for example a plug-in manager component which just downloaded and
303  * installed new plug-ins as requested by the user. The flags
304  * #CP_SP_STOP_ALL_ON_INSTALL and #CP_SP_RESTART_ACTIVE
305  * orred together can be used to cause all active plug-ins to be restarted
306  * if they do not otherwise notice the extensions provided by new plug-ins.
307  *
308  * Upgrading plug-ins is almost as straightforward because the C-Pluff
309  * framework manages plug-in dependencies (assuming the plug-ins have
310  * declared their dependencies properly). The new version of a plug-in
311  * can be deployed under the plug-in collection directory in a
312  * new subdirectory parallel to the old version while the application is
313  * running. The main program can then call ::cp_scan_plugins with
314  * #CP_SP_UPGRADE and #CP_SP_RESTART_ACTIVE orred together. This will stop
315  * the old version of the upgraded plug-in (implicitly stopping all plug-ins
316  * that depend on it), unload the plug-in from the framework, install the
317  * new version of the plug-in and finally restart plug-ins that were
318  * active before the operation. The old version of the plug-in can now
319  * be removed from the plug-in collection. Again, #CP_SP_STOP_ALL_ON_UPGRADE
320  * can be added to restart all active plug-ins.
321  *
322  * Deleting plug-ins must be done by first stopping and unloading the
323  * plug-in to be deleted using ::cp_uninstall_plugin. The the plug-in can
324  * be removed from the plug-in collection.
325  *
326  * @subsection cMainProgramDestroyFramework Destroying the plug-in framework
327  *
328  * The plug-in framework can be destroyed and all resources released by
329  * calling ::cp_destroy as many times as ::cp_init has been called. This
330  * is not a thread-safe operation and should generally be done by the main
331  * program just before application exits. The destroy function
332  * stops and unloads all plug-ins and destroys all plug-in contexts before
333  * destroying the core framework.
334  *
335  * Individual plug-in contexts can be destroyed by calling
336  * ::cp_destroy_context. The destroy function stops and unloads all plug-ins
337  * before destroying the context itself.
338  */