Make GSettingsSchemaKey public
[platform/upstream/glib.git] / gio / giomodule.c
1 /* GIO - GLib Input, Output and Streaming Library
2  * 
3  * Copyright (C) 2006-2007 Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Author: Alexander Larsson <alexl@redhat.com>
21  */
22
23 #include "config.h"
24
25 #include <string.h>
26
27 #include "giomodule.h"
28 #include "giomodule-priv.h"
29 #include "glocalfilemonitor.h"
30 #include "glocaldirectorymonitor.h"
31 #include "gnativevolumemonitor.h"
32 #include "gproxyresolver.h"
33 #include "gproxy.h"
34 #include "gsettingsbackendinternal.h"
35 #include "gsocks4proxy.h"
36 #include "gsocks4aproxy.h"
37 #include "gsocks5proxy.h"
38 #include "gtlsbackend.h"
39 #include "gvfs.h"
40 #include "gnotificationbackend.h"
41 #ifdef G_OS_WIN32
42 #include "gregistrysettingsbackend.h"
43 #endif
44 #include <glib/gstdio.h>
45
46 #ifdef G_OS_UNIX
47 #include "gdesktopappinfo.h"
48 #endif
49
50 /**
51  * SECTION:giomodule
52  * @short_description: Loadable GIO Modules
53  * @include: gio/gio.h
54  *
55  * Provides an interface and default functions for loading and unloading 
56  * modules. This is used internally to make GIO extensible, but can also
57  * be used by others to implement module loading.
58  * 
59  **/
60
61 /**
62  * SECTION:extensionpoints
63  * @short_description: Extension Points
64  * @include: gio.h
65  * @see_also: <link linkend="extending-gio">Extending GIO</link>
66  *
67  * #GIOExtensionPoint provides a mechanism for modules to extend the
68  * functionality of the library or application that loaded it in an 
69  * organized fashion.  
70  *
71  * An extension point is identified by a name, and it may optionally
72  * require that any implementation must by of a certain type (or derived
73  * thereof). Use g_io_extension_point_register() to register an
74  * extension point, and g_io_extension_point_set_required_type() to
75  * set a required type.
76  *
77  * A module can implement an extension point by specifying the #GType 
78  * that implements the functionality. Additionally, each implementation
79  * of an extension point has a name, and a priority. Use
80  * g_io_extension_point_implement() to implement an extension point.
81  * 
82  *  |[
83  *  GIOExtensionPoint *ep;
84  *
85  *  /&ast; Register an extension point &ast;/
86  *  ep = g_io_extension_point_register ("my-extension-point");
87  *  g_io_extension_point_set_required_type (ep, MY_TYPE_EXAMPLE);
88  *  ]|
89  *
90  *  |[
91  *  /&ast; Implement an extension point &ast;/
92  *  G_DEFINE_TYPE (MyExampleImpl, my_example_impl, MY_TYPE_EXAMPLE);
93  *  g_io_extension_point_implement ("my-extension-point",
94  *                                  my_example_impl_get_type (),
95  *                                  "my-example",
96  *                                  10);
97  *  ]|
98  *
99  *  It is up to the code that registered the extension point how
100  *  it uses the implementations that have been associated with it.
101  *  Depending on the use case, it may use all implementations, or
102  *  only the one with the highest priority, or pick a specific
103  *  one by name.
104  *
105  *  To avoid opening all modules just to find out what extension
106  *  points they implement, GIO makes use of a caching mechanism,
107  *  see <link linkend="gio-querymodules">gio-querymodules</link>.
108  *  You are expected to run this command after installing a
109  *  GIO module.
110  *
111  *  The <envar>GIO_EXTRA_MODULES</envar> environment variable can be
112  *  used to specify additional directories to automatically load modules
113  *  from. This environment variable has the same syntax as the
114  *  <envar>PATH</envar>. If two modules have the same base name in different
115  *  directories, then the latter one will be ignored. If additional
116  *  directories are specified GIO will load modules from the built-in
117  *  directory last.
118  */
119
120 /**
121  * GIOModuleScope:
122  *
123  * Represents a scope for loading IO modules. A scope can be used for blocking
124  * duplicate modules, or blocking a module you don't want to load.
125  *
126  * The scope can be used with g_io_modules_load_all_in_directory_with_scope()
127  * or g_io_modules_scan_all_in_directory_with_scope().
128  *
129  * Since: 2.30
130  */
131 struct _GIOModuleScope {
132   GIOModuleScopeFlags flags;
133   GHashTable *basenames;
134 };
135
136 /**
137  * g_io_module_scope_new:
138  * @flags: flags for the new scope
139  *
140  * Create a new scope for loading of IO modules. A scope can be used for
141  * blocking duplicate modules, or blocking a module you don't want to load.
142  *
143  * Specify the %G_IO_MODULE_SCOPE_BLOCK_DUPLICATES flag to block modules
144  * which have the same base name as a module that has already been seen
145  * in this scope.
146  *
147  * Returns: (transfer full): the new module scope
148  *
149  * Since: 2.30
150  */
151 GIOModuleScope *
152 g_io_module_scope_new (GIOModuleScopeFlags flags)
153 {
154   GIOModuleScope *scope = g_new0 (GIOModuleScope, 1);
155   scope->flags = flags;
156   scope->basenames = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
157   return scope;
158 }
159
160 /**
161  * g_io_module_scope_free:
162  * @scope: a module loading scope
163  *
164  * Free a module scope.
165  *
166  * Since: 2.30
167  */
168 void
169 g_io_module_scope_free (GIOModuleScope *scope)
170 {
171   if (!scope)
172     return;
173   g_hash_table_destroy (scope->basenames);
174   g_free (scope);
175 }
176
177 /**
178  * g_io_module_scope_block:
179  * @scope: a module loading scope
180  * @basename: the basename to block
181  *
182  * Block modules with the given @basename from being loaded when
183  * this scope is used with g_io_modules_scan_all_in_directory_with_scope()
184  * or g_io_modules_load_all_in_directory_with_scope().
185  *
186  * Since: 2.30
187  */
188 void
189 g_io_module_scope_block (GIOModuleScope *scope,
190                          const gchar    *basename)
191 {
192   gchar *key;
193
194   g_return_if_fail (scope != NULL);
195   g_return_if_fail (basename != NULL);
196
197   key = g_strdup (basename);
198   g_hash_table_insert (scope->basenames, key, key);
199 }
200
201 static gboolean
202 _g_io_module_scope_contains (GIOModuleScope *scope,
203                              const gchar    *basename)
204 {
205   return g_hash_table_lookup (scope->basenames, basename) ? TRUE : FALSE;
206 }
207
208 struct _GIOModule {
209   GTypeModule parent_instance;
210
211   gchar       *filename;
212   GModule     *library;
213   gboolean     initialized; /* The module was loaded at least once */
214
215   void (* load)   (GIOModule *module);
216   void (* unload) (GIOModule *module);
217 };
218
219 struct _GIOModuleClass
220 {
221   GTypeModuleClass parent_class;
222
223 };
224
225 static void      g_io_module_finalize      (GObject      *object);
226 static gboolean  g_io_module_load_module   (GTypeModule  *gmodule);
227 static void      g_io_module_unload_module (GTypeModule  *gmodule);
228
229 struct _GIOExtension {
230   char *name;
231   GType type;
232   gint priority;
233 };
234
235 struct _GIOExtensionPoint {
236   GType required_type;
237   char *name;
238   GList *extensions;
239   GList *lazy_load_modules;
240 };
241
242 static GHashTable *extension_points = NULL;
243 G_LOCK_DEFINE_STATIC(extension_points);
244
245 G_DEFINE_TYPE (GIOModule, g_io_module, G_TYPE_TYPE_MODULE);
246
247 static void
248 g_io_module_class_init (GIOModuleClass *class)
249 {
250   GObjectClass     *object_class      = G_OBJECT_CLASS (class);
251   GTypeModuleClass *type_module_class = G_TYPE_MODULE_CLASS (class);
252
253   object_class->finalize     = g_io_module_finalize;
254
255   type_module_class->load    = g_io_module_load_module;
256   type_module_class->unload  = g_io_module_unload_module;
257 }
258
259 static void
260 g_io_module_init (GIOModule *module)
261 {
262 }
263
264 static void
265 g_io_module_finalize (GObject *object)
266 {
267   GIOModule *module = G_IO_MODULE (object);
268
269   g_free (module->filename);
270
271   G_OBJECT_CLASS (g_io_module_parent_class)->finalize (object);
272 }
273
274 static gboolean
275 g_io_module_load_module (GTypeModule *gmodule)
276 {
277   GIOModule *module = G_IO_MODULE (gmodule);
278
279   if (!module->filename)
280     {
281       g_warning ("GIOModule path not set");
282       return FALSE;
283     }
284
285   module->library = g_module_open (module->filename, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
286
287   if (!module->library)
288     {
289       g_printerr ("%s\n", g_module_error ());
290       return FALSE;
291     }
292
293   /* Make sure that the loaded library contains the required methods */
294   if (! g_module_symbol (module->library,
295                          "g_io_module_load",
296                          (gpointer) &module->load) ||
297       ! g_module_symbol (module->library,
298                          "g_io_module_unload",
299                          (gpointer) &module->unload))
300     {
301       g_printerr ("%s\n", g_module_error ());
302       g_module_close (module->library);
303
304       return FALSE;
305     }
306
307   /* Initialize the loaded module */
308   module->load (module);
309   module->initialized = TRUE;
310
311   return TRUE;
312 }
313
314 static void
315 g_io_module_unload_module (GTypeModule *gmodule)
316 {
317   GIOModule *module = G_IO_MODULE (gmodule);
318
319   module->unload (module);
320
321   g_module_close (module->library);
322   module->library = NULL;
323
324   module->load   = NULL;
325   module->unload = NULL;
326 }
327
328 /**
329  * g_io_module_new:
330  * @filename: filename of the shared library module.
331  * 
332  * Creates a new GIOModule that will load the specific
333  * shared library when in use.
334  * 
335  * Returns: a #GIOModule from given @filename, 
336  * or %NULL on error.
337  **/
338 GIOModule *
339 g_io_module_new (const gchar *filename)
340 {
341   GIOModule *module;
342
343   g_return_val_if_fail (filename != NULL, NULL);
344
345   module = g_object_new (G_IO_TYPE_MODULE, NULL);
346   module->filename = g_strdup (filename);
347
348   return module;
349 }
350
351 static gboolean
352 is_valid_module_name (const gchar        *basename,
353                       GIOModuleScope     *scope)
354 {
355   gboolean result;
356
357 #if !defined(G_OS_WIN32) && !defined(G_WITH_CYGWIN)
358   if (!g_str_has_prefix (basename, "lib") ||
359       !g_str_has_suffix (basename, ".so"))
360     return FALSE;
361 #else
362   if (!g_str_has_suffix (basename, ".dll"))
363     return FALSE;
364 #endif
365
366   result = TRUE;
367   if (scope)
368     {
369       result = _g_io_module_scope_contains (scope, basename) ? FALSE : TRUE;
370       if (result && (scope->flags & G_IO_MODULE_SCOPE_BLOCK_DUPLICATES))
371         g_io_module_scope_block (scope, basename);
372     }
373
374   return result;
375 }
376
377
378 /**
379  * g_io_modules_scan_all_in_directory_with_scope:
380  * @dirname: pathname for a directory containing modules to scan.
381  * @scope: a scope to use when scanning the modules
382  *
383  * Scans all the modules in the specified directory, ensuring that
384  * any extension point implemented by a module is registered.
385  *
386  * This may not actually load and initialize all the types in each
387  * module, some modules may be lazily loaded and initialized when
388  * an extension point it implementes is used with e.g.
389  * g_io_extension_point_get_extensions() or
390  * g_io_extension_point_get_extension_by_name().
391  *
392  * If you need to guarantee that all types are loaded in all the modules,
393  * use g_io_modules_load_all_in_directory().
394  *
395  * Since: 2.30
396  **/
397 void
398 g_io_modules_scan_all_in_directory_with_scope (const char     *dirname,
399                                                GIOModuleScope *scope)
400 {
401   const gchar *name;
402   char *filename;
403   GDir *dir;
404   GStatBuf statbuf;
405   char *data;
406   time_t cache_mtime;
407   GHashTable *cache;
408
409   if (!g_module_supported ())
410     return;
411
412   dir = g_dir_open (dirname, 0, NULL);
413   if (!dir)
414     return;
415
416   filename = g_build_filename (dirname, "giomodule.cache", NULL);
417
418   cache = g_hash_table_new_full (g_str_hash, g_str_equal,
419                                  g_free, (GDestroyNotify)g_strfreev);
420
421   cache_mtime = 0;
422   if (g_stat (filename, &statbuf) == 0 &&
423       g_file_get_contents (filename, &data, NULL, NULL))
424     {
425       char **lines;
426       int i;
427
428       /* Cache mtime is the time the cache file was created, any file
429        * that has a ctime before this was created then and not modified
430        * since then (userspace can't change ctime). Its possible to change
431        * the ctime forward without changing the file content, by e.g.
432        * chmoding the file, but this is uncommon and will only cause us
433        * to not use the cache so will not cause bugs.
434        */
435       cache_mtime = statbuf.st_mtime;
436
437       lines = g_strsplit (data, "\n", -1);
438       g_free (data);
439
440       for (i = 0;  lines[i] != NULL; i++)
441         {
442           char *line = lines[i];
443           char *file;
444           char *colon;
445           char **extension_points;
446
447           if (line[0] == '#')
448             continue;
449
450           colon = strchr (line, ':');
451           if (colon == NULL || line == colon)
452             continue; /* Invalid line, ignore */
453
454           *colon = 0; /* terminate filename */
455           file = g_strdup (line);
456           colon++; /* after colon */
457
458           while (g_ascii_isspace (*colon))
459             colon++;
460
461           extension_points = g_strsplit (colon, ",", -1);
462           g_hash_table_insert (cache, file, extension_points);
463         }
464       g_strfreev (lines);
465     }
466
467   while ((name = g_dir_read_name (dir)))
468     {
469       if (is_valid_module_name (name, scope))
470         {
471           GIOExtensionPoint *extension_point;
472           GIOModule *module;
473           gchar *path;
474           char **extension_points;
475           int i;
476
477           path = g_build_filename (dirname, name, NULL);
478           module = g_io_module_new (path);
479
480           extension_points = g_hash_table_lookup (cache, name);
481           if (extension_points != NULL &&
482               g_stat (path, &statbuf) == 0 &&
483               statbuf.st_ctime <= cache_mtime)
484             {
485               /* Lazy load/init the library when first required */
486               for (i = 0; extension_points[i] != NULL; i++)
487                 {
488                   extension_point =
489                     g_io_extension_point_register (extension_points[i]);
490                   extension_point->lazy_load_modules =
491                     g_list_prepend (extension_point->lazy_load_modules,
492                                     module);
493                 }
494             }
495           else
496             {
497               /* Try to load and init types */
498               if (g_type_module_use (G_TYPE_MODULE (module)))
499                 g_type_module_unuse (G_TYPE_MODULE (module)); /* Unload */
500               else
501                 { /* Failure to load */
502                   g_printerr ("Failed to load module: %s\n", path);
503                   g_object_unref (module);
504                   g_free (path);
505                   continue;
506                 }
507             }
508
509           g_free (path);
510         }
511     }
512
513   g_dir_close (dir);
514
515   g_hash_table_destroy (cache);
516
517   g_free (filename);
518 }
519
520 /**
521  * g_io_modules_scan_all_in_directory:
522  * @dirname: pathname for a directory containing modules to scan.
523  *
524  * Scans all the modules in the specified directory, ensuring that
525  * any extension point implemented by a module is registered.
526  *
527  * This may not actually load and initialize all the types in each
528  * module, some modules may be lazily loaded and initialized when
529  * an extension point it implementes is used with e.g.
530  * g_io_extension_point_get_extensions() or
531  * g_io_extension_point_get_extension_by_name().
532  *
533  * If you need to guarantee that all types are loaded in all the modules,
534  * use g_io_modules_load_all_in_directory().
535  *
536  * Since: 2.24
537  **/
538 void
539 g_io_modules_scan_all_in_directory (const char *dirname)
540 {
541   g_io_modules_scan_all_in_directory_with_scope (dirname, NULL);
542 }
543
544 /**
545  * g_io_modules_load_all_in_directory_with_scope:
546  * @dirname: pathname for a directory containing modules to load.
547  * @scope: a scope to use when scanning the modules.
548  *
549  * Loads all the modules in the specified directory.
550  *
551  * If don't require all modules to be initialized (and thus registering
552  * all gtypes) then you can use g_io_modules_scan_all_in_directory()
553  * which allows delayed/lazy loading of modules.
554  *
555  * Returns: (element-type GIOModule) (transfer full): a list of #GIOModules loaded
556  *      from the directory,
557  *      All the modules are loaded into memory, if you want to
558  *      unload them (enabling on-demand loading) you must call
559  *      g_type_module_unuse() on all the modules. Free the list
560  *      with g_list_free().
561  *
562  * Since: 2.30
563  **/
564 GList *
565 g_io_modules_load_all_in_directory_with_scope (const char     *dirname,
566                                                GIOModuleScope *scope)
567 {
568   const gchar *name;
569   GDir        *dir;
570   GList *modules;
571
572   if (!g_module_supported ())
573     return NULL;
574
575   dir = g_dir_open (dirname, 0, NULL);
576   if (!dir)
577     return NULL;
578
579   modules = NULL;
580   while ((name = g_dir_read_name (dir)))
581     {
582       if (is_valid_module_name (name, scope))
583         {
584           GIOModule *module;
585           gchar     *path;
586
587           path = g_build_filename (dirname, name, NULL);
588           module = g_io_module_new (path);
589
590           if (!g_type_module_use (G_TYPE_MODULE (module)))
591             {
592               g_printerr ("Failed to load module: %s\n", path);
593               g_object_unref (module);
594               g_free (path);
595               continue;
596             }
597           
598           g_free (path);
599
600           modules = g_list_prepend (modules, module);
601         }
602     }
603   
604   g_dir_close (dir);
605
606   return modules;
607 }
608
609 /**
610  * g_io_modules_load_all_in_directory:
611  * @dirname: pathname for a directory containing modules to load.
612  *
613  * Loads all the modules in the specified directory.
614  *
615  * If don't require all modules to be initialized (and thus registering
616  * all gtypes) then you can use g_io_modules_scan_all_in_directory()
617  * which allows delayed/lazy loading of modules.
618  *
619  * Returns: (element-type GIOModule) (transfer full): a list of #GIOModules loaded
620  *      from the directory,
621  *      All the modules are loaded into memory, if you want to
622  *      unload them (enabling on-demand loading) you must call
623  *      g_type_module_unuse() on all the modules. Free the list
624  *      with g_list_free().
625  **/
626 GList *
627 g_io_modules_load_all_in_directory (const char *dirname)
628 {
629   return g_io_modules_load_all_in_directory_with_scope (dirname, NULL);
630 }
631
632 static gpointer
633 try_class (GIOExtension *extension,
634            guint         is_supported_offset)
635 {
636   GType type = g_io_extension_get_type (extension);
637   typedef gboolean (*verify_func) (void);
638   gpointer class;
639
640   class = g_type_class_ref (type);
641   if (!is_supported_offset || (* G_STRUCT_MEMBER(verify_func, class, is_supported_offset)) ())
642     return class;
643
644   g_type_class_unref (class);
645   return NULL;
646 }
647
648 /**
649  * _g_io_module_get_default_type:
650  * @extension_point: the name of an extension point
651  * @envvar: (allow-none): the name of an environment variable to
652  *     override the default implementation.
653  * @is_supported_offset: a vtable offset, or zero
654  *
655  * Retrieves the default class implementing @extension_point.
656  *
657  * If @envvar is not %NULL, and the environment variable with that
658  * name is set, then the implementation it specifies will be tried
659  * first. After that, or if @envvar is not set, all other
660  * implementations will be tried in order of decreasing priority.
661  *
662  * If @is_supported_offset is non-zero, then it is the offset into the
663  * class vtable at which there is a function that takes no arguments and
664  * returns a boolean.  This function will be called on each candidate
665  * implementation to check if it is actually usable or not.
666  *
667  * The result is cached after it is generated the first time, and
668  * the function is thread-safe.
669  *
670  * Return value: (transfer none): an object implementing
671  *     @extension_point, or %NULL if there are no usable
672  *     implementations.
673  */
674 GType
675 _g_io_module_get_default_type (const gchar *extension_point,
676                                const gchar *envvar,
677                                guint        is_supported_offset)
678 {
679   static GRecMutex default_modules_lock;
680   static GHashTable *default_modules;
681   const char *use_this;
682   GList *l;
683   GIOExtensionPoint *ep;
684   GIOExtension *extension, *preferred;
685   gpointer impl;
686
687   g_rec_mutex_lock (&default_modules_lock);
688   if (default_modules)
689     {
690       gpointer key;
691
692       if (g_hash_table_lookup_extended (default_modules, extension_point, &key, &impl))
693         {
694           g_rec_mutex_unlock (&default_modules_lock);
695           return impl ? G_OBJECT_CLASS_TYPE (impl) : G_TYPE_INVALID;
696         }
697     }
698   else
699     {
700       default_modules = g_hash_table_new (g_str_hash, g_str_equal);
701     }
702
703   _g_io_modules_ensure_loaded ();
704   ep = g_io_extension_point_lookup (extension_point);
705
706   if (!ep)
707     {
708       g_warn_if_reached ();
709       g_rec_mutex_unlock (&default_modules_lock);
710       return G_TYPE_INVALID;
711     }
712
713   use_this = envvar ? g_getenv (envvar) : NULL;
714   if (use_this)
715     {
716       preferred = g_io_extension_point_get_extension_by_name (ep, use_this);
717       if (preferred)
718         {
719           impl = try_class (preferred, is_supported_offset);
720           if (impl)
721             goto done;
722         }
723       else
724         g_warning ("Can't find module '%s' specified in %s", use_this, envvar);
725     }
726   else
727     preferred = NULL;
728
729   for (l = g_io_extension_point_get_extensions (ep); l != NULL; l = l->next)
730     {
731       extension = l->data;
732       if (extension == preferred)
733         continue;
734
735       impl = try_class (extension, is_supported_offset);
736       if (impl)
737         goto done;
738     }
739
740   impl = NULL;
741
742  done:
743   g_hash_table_insert (default_modules, g_strdup (extension_point), impl);
744   g_rec_mutex_unlock (&default_modules_lock);
745
746   return impl ? G_OBJECT_CLASS_TYPE (impl) : G_TYPE_INVALID;
747 }
748
749 static gpointer
750 try_implementation (GIOExtension         *extension,
751                     GIOModuleVerifyFunc   verify_func)
752 {
753   GType type = g_io_extension_get_type (extension);
754   gpointer impl;
755
756   if (g_type_is_a (type, G_TYPE_INITABLE))
757     return g_initable_new (type, NULL, NULL, NULL);
758   else
759     {
760       impl = g_object_new (type, NULL);
761       if (!verify_func || verify_func (impl))
762         return impl;
763
764       g_object_unref (impl);
765       return NULL;
766     }
767 }
768
769 /**
770  * _g_io_module_get_default:
771  * @extension_point: the name of an extension point
772  * @envvar: (allow-none): the name of an environment variable to
773  *     override the default implementation.
774  * @verify_func: (allow-none): a function to call to verify that
775  *     a given implementation is usable in the current environment.
776  *
777  * Retrieves the default object implementing @extension_point.
778  *
779  * If @envvar is not %NULL, and the environment variable with that
780  * name is set, then the implementation it specifies will be tried
781  * first. After that, or if @envvar is not set, all other
782  * implementations will be tried in order of decreasing priority.
783  *
784  * If an extension point implementation implements #GInitable, then
785  * that implementation will only be used if it initializes
786  * successfully. Otherwise, if @verify_func is not %NULL, then it will
787  * be called on each candidate implementation after construction, to
788  * check if it is actually usable or not.
789  *
790  * The result is cached after it is generated the first time, and
791  * the function is thread-safe.
792  *
793  * Return value: (transfer none): an object implementing
794  *     @extension_point, or %NULL if there are no usable
795  *     implementations.
796  */
797 gpointer
798 _g_io_module_get_default (const gchar         *extension_point,
799                           const gchar         *envvar,
800                           GIOModuleVerifyFunc  verify_func)
801 {
802   static GRecMutex default_modules_lock;
803   static GHashTable *default_modules;
804   const char *use_this;
805   GList *l;
806   GIOExtensionPoint *ep;
807   GIOExtension *extension, *preferred;
808   gpointer impl;
809
810   g_rec_mutex_lock (&default_modules_lock);
811   if (default_modules)
812     {
813       gpointer key;
814
815       if (g_hash_table_lookup_extended (default_modules, extension_point,
816                                         &key, &impl))
817         {
818           g_rec_mutex_unlock (&default_modules_lock);
819           return impl;
820         }
821     }
822   else
823     {
824       default_modules = g_hash_table_new (g_str_hash, g_str_equal);
825     }
826
827   _g_io_modules_ensure_loaded ();
828   ep = g_io_extension_point_lookup (extension_point);
829
830   if (!ep)
831     {
832       g_warn_if_reached ();
833       g_rec_mutex_unlock (&default_modules_lock);
834       return NULL;
835     }
836
837   use_this = envvar ? g_getenv (envvar) : NULL;
838   if (use_this)
839     {
840       preferred = g_io_extension_point_get_extension_by_name (ep, use_this);
841       if (preferred)
842         {
843           impl = try_implementation (preferred, verify_func);
844           if (impl)
845             goto done;
846         }
847       else
848         g_warning ("Can't find module '%s' specified in %s", use_this, envvar);
849     }
850   else
851     preferred = NULL;
852
853   for (l = g_io_extension_point_get_extensions (ep); l != NULL; l = l->next)
854     {
855       extension = l->data;
856       if (extension == preferred)
857         continue;
858
859       impl = try_implementation (extension, verify_func);
860       if (impl)
861         goto done;
862     }
863
864   impl = NULL;
865
866  done:
867   g_hash_table_insert (default_modules,
868                        g_strdup (extension_point),
869                        impl ? g_object_ref (impl) : NULL);
870   g_rec_mutex_unlock (&default_modules_lock);
871
872   return impl;
873 }
874
875 G_LOCK_DEFINE_STATIC (registered_extensions);
876 G_LOCK_DEFINE_STATIC (loaded_dirs);
877
878 extern GType _g_fen_directory_monitor_get_type (void);
879 extern GType _g_fen_file_monitor_get_type (void);
880 extern GType _g_inotify_directory_monitor_get_type (void);
881 extern GType _g_inotify_file_monitor_get_type (void);
882 extern GType _g_kqueue_directory_monitor_get_type (void);
883 extern GType _g_kqueue_file_monitor_get_type (void);
884 extern GType _g_unix_volume_monitor_get_type (void);
885 extern GType _g_local_vfs_get_type (void);
886
887 extern GType _g_win32_volume_monitor_get_type (void);
888 extern GType g_win32_directory_monitor_get_type (void);
889 extern GType _g_winhttp_vfs_get_type (void);
890
891 extern GType _g_dummy_proxy_resolver_get_type (void);
892 extern GType _g_dummy_tls_backend_get_type (void);
893 extern GType g_network_monitor_base_get_type (void);
894 #ifdef HAVE_NETLINK
895 extern GType _g_network_monitor_netlink_get_type (void);
896 #endif
897
898 #ifdef G_OS_UNIX
899 extern GType g_fdo_notification_backend_get_type (void);
900 extern GType g_gtk_notification_backend_get_type (void);
901 #endif
902
903 #ifdef G_PLATFORM_WIN32
904
905 #include <windows.h>
906
907 static HMODULE gio_dll = NULL;
908
909 #ifdef DLL_EXPORT
910
911 BOOL WINAPI DllMain (HINSTANCE hinstDLL,
912                      DWORD     fdwReason,
913                      LPVOID    lpvReserved);
914
915 BOOL WINAPI
916 DllMain (HINSTANCE hinstDLL,
917          DWORD     fdwReason,
918          LPVOID    lpvReserved)
919 {
920   if (fdwReason == DLL_PROCESS_ATTACH)
921       gio_dll = hinstDLL;
922
923   return TRUE;
924 }
925
926 #endif
927
928 void *
929 _g_io_win32_get_module (void)
930 {
931   if (!gio_dll)
932     GetModuleHandleExA (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
933                         (const char *) _g_io_win32_get_module,
934                         &gio_dll);
935   return gio_dll;
936 }
937
938 #undef GIO_MODULE_DIR
939
940 /* GIO_MODULE_DIR is used only in code called just once,
941  * so no problem leaking this
942  */
943 #define GIO_MODULE_DIR \
944   g_build_filename (g_win32_get_package_installation_directory_of_module (gio_dll), \
945                     "lib/gio/modules", \
946                     NULL)
947
948 #endif
949
950 void
951 _g_io_modules_ensure_extension_points_registered (void)
952 {
953   static gboolean registered_extensions = FALSE;
954   GIOExtensionPoint *ep;
955
956   G_LOCK (registered_extensions);
957   
958   if (!registered_extensions)
959     {
960       registered_extensions = TRUE;
961       
962 #ifdef G_OS_UNIX
963 #if !GLIB_CHECK_VERSION (3, 0, 0)
964       ep = g_io_extension_point_register (G_DESKTOP_APP_INFO_LOOKUP_EXTENSION_POINT_NAME);
965       G_GNUC_BEGIN_IGNORE_DEPRECATIONS
966       g_io_extension_point_set_required_type (ep, G_TYPE_DESKTOP_APP_INFO_LOOKUP);
967       G_GNUC_END_IGNORE_DEPRECATIONS
968 #endif
969 #endif
970       
971       ep = g_io_extension_point_register (G_LOCAL_DIRECTORY_MONITOR_EXTENSION_POINT_NAME);
972       g_io_extension_point_set_required_type (ep, G_TYPE_LOCAL_DIRECTORY_MONITOR);
973       
974       ep = g_io_extension_point_register (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME);
975       g_io_extension_point_set_required_type (ep, G_TYPE_LOCAL_FILE_MONITOR);
976       
977       ep = g_io_extension_point_register (G_NFS_DIRECTORY_MONITOR_EXTENSION_POINT_NAME);
978       g_io_extension_point_set_required_type (ep, G_TYPE_LOCAL_DIRECTORY_MONITOR);
979
980       ep = g_io_extension_point_register (G_NFS_FILE_MONITOR_EXTENSION_POINT_NAME);
981       g_io_extension_point_set_required_type (ep, G_TYPE_LOCAL_FILE_MONITOR);
982
983       ep = g_io_extension_point_register (G_VOLUME_MONITOR_EXTENSION_POINT_NAME);
984       g_io_extension_point_set_required_type (ep, G_TYPE_VOLUME_MONITOR);
985       
986       ep = g_io_extension_point_register (G_NATIVE_VOLUME_MONITOR_EXTENSION_POINT_NAME);
987       g_io_extension_point_set_required_type (ep, G_TYPE_NATIVE_VOLUME_MONITOR);
988       
989       ep = g_io_extension_point_register (G_VFS_EXTENSION_POINT_NAME);
990       g_io_extension_point_set_required_type (ep, G_TYPE_VFS);
991
992       ep = g_io_extension_point_register ("gsettings-backend");
993       g_io_extension_point_set_required_type (ep, G_TYPE_OBJECT);
994
995       ep = g_io_extension_point_register (G_PROXY_RESOLVER_EXTENSION_POINT_NAME);
996       g_io_extension_point_set_required_type (ep, G_TYPE_PROXY_RESOLVER);
997
998       ep = g_io_extension_point_register (G_PROXY_EXTENSION_POINT_NAME);
999       g_io_extension_point_set_required_type (ep, G_TYPE_PROXY);
1000
1001       ep = g_io_extension_point_register (G_TLS_BACKEND_EXTENSION_POINT_NAME);
1002       g_io_extension_point_set_required_type (ep, G_TYPE_TLS_BACKEND);
1003
1004       ep = g_io_extension_point_register (G_NETWORK_MONITOR_EXTENSION_POINT_NAME);
1005       g_io_extension_point_set_required_type (ep, G_TYPE_NETWORK_MONITOR);
1006
1007       ep = g_io_extension_point_register (G_NOTIFICATION_BACKEND_EXTENSION_POINT_NAME);
1008       g_io_extension_point_set_required_type (ep, G_TYPE_NOTIFICATION_BACKEND);
1009     }
1010   
1011   G_UNLOCK (registered_extensions);
1012 }
1013
1014 void
1015 _g_io_modules_ensure_loaded (void)
1016 {
1017   static gboolean loaded_dirs = FALSE;
1018   const char *module_path;
1019   GIOModuleScope *scope;
1020
1021   _g_io_modules_ensure_extension_points_registered ();
1022   
1023   G_LOCK (loaded_dirs);
1024
1025   if (!loaded_dirs)
1026     {
1027       loaded_dirs = TRUE;
1028       scope = g_io_module_scope_new (G_IO_MODULE_SCOPE_BLOCK_DUPLICATES);
1029
1030       /* First load any overrides, extras */
1031       module_path = g_getenv ("GIO_EXTRA_MODULES");
1032       if (module_path)
1033         {
1034           gchar **paths;
1035           int i;
1036
1037           paths = g_strsplit (module_path, G_SEARCHPATH_SEPARATOR_S, 0);
1038
1039           for (i = 0; paths[i] != NULL; i++)
1040             {
1041               g_io_modules_scan_all_in_directory_with_scope (paths[i], scope);
1042             }
1043
1044           g_strfreev (paths);
1045         }
1046
1047       /* Then load the compiled in path */
1048       g_io_modules_scan_all_in_directory_with_scope (GIO_MODULE_DIR, scope);
1049
1050       g_io_module_scope_free (scope);
1051
1052       /* Initialize types from built-in "modules" */
1053       g_type_ensure (g_null_settings_backend_get_type ());
1054       g_type_ensure (g_memory_settings_backend_get_type ());
1055 #if defined(HAVE_SYS_INOTIFY_H) || defined(HAVE_LINUX_INOTIFY_H)
1056       g_type_ensure (_g_inotify_directory_monitor_get_type ());
1057       g_type_ensure (_g_inotify_file_monitor_get_type ());
1058 #endif
1059 #if defined(HAVE_KQUEUE)
1060       g_type_ensure (_g_kqueue_directory_monitor_get_type ());
1061       g_type_ensure (_g_kqueue_file_monitor_get_type ());
1062 #endif
1063 #if defined(HAVE_FEN)
1064       g_type_ensure (_g_fen_directory_monitor_get_type ());
1065       g_type_ensure (_g_fen_file_monitor_get_type ());
1066 #endif
1067 #ifdef G_OS_WIN32
1068       g_type_ensure (_g_win32_volume_monitor_get_type ());
1069       g_type_ensure (g_win32_directory_monitor_get_type ());
1070       g_type_ensure (g_registry_backend_get_type ());
1071 #endif
1072 #ifdef HAVE_CARBON
1073       g_nextstep_settings_backend_get_type ();
1074 #endif
1075 #ifdef G_OS_UNIX
1076       g_type_ensure (_g_unix_volume_monitor_get_type ());
1077       g_type_ensure (g_fdo_notification_backend_get_type ());
1078       g_type_ensure (g_gtk_notification_backend_get_type ());
1079 #endif
1080 #ifdef G_OS_WIN32
1081       g_type_ensure (_g_winhttp_vfs_get_type ());
1082 #endif
1083       g_type_ensure (_g_local_vfs_get_type ());
1084       g_type_ensure (_g_dummy_proxy_resolver_get_type ());
1085       g_type_ensure (_g_socks4a_proxy_get_type ());
1086       g_type_ensure (_g_socks4_proxy_get_type ());
1087       g_type_ensure (_g_socks5_proxy_get_type ());
1088       g_type_ensure (_g_dummy_tls_backend_get_type ());
1089       g_type_ensure (g_network_monitor_base_get_type ());
1090 #ifdef HAVE_NETLINK
1091       g_type_ensure (_g_network_monitor_netlink_get_type ());
1092 #endif
1093     }
1094
1095   G_UNLOCK (loaded_dirs);
1096 }
1097
1098 static void
1099 g_io_extension_point_free (GIOExtensionPoint *ep)
1100 {
1101   g_free (ep->name);
1102   g_free (ep);
1103 }
1104
1105 /**
1106  * g_io_extension_point_register:
1107  * @name: The name of the extension point
1108  *
1109  * Registers an extension point.
1110  *
1111  * Returns: (transfer none): the new #GIOExtensionPoint. This object is
1112  *    owned by GIO and should not be freed.
1113  */
1114 GIOExtensionPoint *
1115 g_io_extension_point_register (const char *name)
1116 {
1117   GIOExtensionPoint *ep;
1118   
1119   G_LOCK (extension_points);
1120   if (extension_points == NULL)
1121     extension_points = g_hash_table_new_full (g_str_hash,
1122                                               g_str_equal,
1123                                               NULL,
1124                                               (GDestroyNotify)g_io_extension_point_free);
1125
1126   ep = g_hash_table_lookup (extension_points, name);
1127   if (ep != NULL)
1128     {
1129       G_UNLOCK (extension_points);
1130       return ep;
1131     }
1132
1133   ep = g_new0 (GIOExtensionPoint, 1);
1134   ep->name = g_strdup (name);
1135   
1136   g_hash_table_insert (extension_points, ep->name, ep);
1137   
1138   G_UNLOCK (extension_points);
1139
1140   return ep;
1141 }
1142
1143 /**
1144  * g_io_extension_point_lookup:
1145  * @name: the name of the extension point
1146  *
1147  * Looks up an existing extension point.
1148  *
1149  * Returns: (transfer none): the #GIOExtensionPoint, or %NULL if there
1150  *    is no registered extension point with the given name.
1151  */
1152 GIOExtensionPoint *
1153 g_io_extension_point_lookup (const char *name)
1154 {
1155   GIOExtensionPoint *ep;
1156
1157   G_LOCK (extension_points);
1158   ep = NULL;
1159   if (extension_points != NULL)
1160     ep = g_hash_table_lookup (extension_points, name);
1161   
1162   G_UNLOCK (extension_points);
1163
1164   return ep;
1165   
1166 }
1167
1168 /**
1169  * g_io_extension_point_set_required_type:
1170  * @extension_point: a #GIOExtensionPoint
1171  * @type: the #GType to require
1172  *
1173  * Sets the required type for @extension_point to @type. 
1174  * All implementations must henceforth have this type.
1175  */
1176 void
1177 g_io_extension_point_set_required_type (GIOExtensionPoint *extension_point,
1178                                         GType              type)
1179 {
1180   extension_point->required_type = type;
1181 }
1182
1183 /**
1184  * g_io_extension_point_get_required_type:
1185  * @extension_point: a #GIOExtensionPoint
1186  *
1187  * Gets the required type for @extension_point.
1188  *
1189  * Returns: the #GType that all implementations must have, 
1190  *     or #G_TYPE_INVALID if the extension point has no required type
1191  */
1192 GType
1193 g_io_extension_point_get_required_type (GIOExtensionPoint *extension_point)
1194 {
1195   return extension_point->required_type;
1196 }
1197
1198 static void
1199 lazy_load_modules (GIOExtensionPoint *extension_point)
1200 {
1201   GIOModule *module;
1202   GList *l;
1203
1204   for (l = extension_point->lazy_load_modules; l != NULL; l = l->next)
1205     {
1206       module = l->data;
1207
1208       if (!module->initialized)
1209         {
1210           if (g_type_module_use (G_TYPE_MODULE (module)))
1211             g_type_module_unuse (G_TYPE_MODULE (module)); /* Unload */
1212           else
1213             g_printerr ("Failed to load module: %s\n",
1214                         module->filename);
1215         }
1216     }
1217 }
1218
1219 /**
1220  * g_io_extension_point_get_extensions:
1221  * @extension_point: a #GIOExtensionPoint
1222  *
1223  * Gets a list of all extensions that implement this extension point.
1224  * The list is sorted by priority, beginning with the highest priority.
1225  *
1226  * Returns: (element-type GIOExtension) (transfer none): a #GList of
1227  * #GIOExtension<!-- -->s. The list is owned by GIO and should not be
1228  * modified.
1229  */
1230 GList *
1231 g_io_extension_point_get_extensions (GIOExtensionPoint *extension_point)
1232 {
1233   lazy_load_modules (extension_point);
1234   return extension_point->extensions;
1235 }
1236
1237 /**
1238  * g_io_extension_point_get_extension_by_name:
1239  * @extension_point: a #GIOExtensionPoint
1240  * @name: the name of the extension to get
1241  *
1242  * Finds a #GIOExtension for an extension point by name.
1243  *
1244  * Returns: (transfer none): the #GIOExtension for @extension_point that has the
1245  *    given name, or %NULL if there is no extension with that name
1246  */
1247 GIOExtension *
1248 g_io_extension_point_get_extension_by_name (GIOExtensionPoint *extension_point,
1249                                             const char        *name)
1250 {
1251   GList *l;
1252
1253   lazy_load_modules (extension_point);
1254   for (l = extension_point->extensions; l != NULL; l = l->next)
1255     {
1256       GIOExtension *e = l->data;
1257
1258       if (e->name != NULL &&
1259           strcmp (e->name, name) == 0)
1260         return e;
1261     }
1262   
1263   return NULL;
1264 }
1265
1266 static gint
1267 extension_prio_compare (gconstpointer  a,
1268                         gconstpointer  b)
1269 {
1270   const GIOExtension *extension_a = a, *extension_b = b;
1271
1272   if (extension_a->priority > extension_b->priority)
1273     return -1;
1274
1275   if (extension_b->priority > extension_a->priority)
1276     return 1;
1277
1278   return 0;
1279 }
1280
1281 /**
1282  * g_io_extension_point_implement:
1283  * @extension_point_name: the name of the extension point
1284  * @type: the #GType to register as extension 
1285  * @extension_name: the name for the extension
1286  * @priority: the priority for the extension
1287  *
1288  * Registers @type as extension for the extension point with name
1289  * @extension_point_name. 
1290  *
1291  * If @type has already been registered as an extension for this 
1292  * extension point, the existing #GIOExtension object is returned.
1293  *
1294  * Returns: (transfer none): a #GIOExtension object for #GType
1295  */
1296 GIOExtension *
1297 g_io_extension_point_implement (const char *extension_point_name,
1298                                 GType       type,
1299                                 const char *extension_name,
1300                                 gint        priority)
1301 {
1302   GIOExtensionPoint *extension_point;
1303   GIOExtension *extension;
1304   GList *l;
1305
1306   g_return_val_if_fail (extension_point_name != NULL, NULL);
1307
1308   extension_point = g_io_extension_point_lookup (extension_point_name);
1309   if (extension_point == NULL)
1310     {
1311       g_warning ("Tried to implement non-registered extension point %s", extension_point_name);
1312       return NULL;
1313     }
1314   
1315   if (extension_point->required_type != 0 &&
1316       !g_type_is_a (type, extension_point->required_type))
1317     {
1318       g_warning ("Tried to register an extension of the type %s to extension point %s. "
1319                  "Expected type is %s.",
1320                  g_type_name (type),
1321                  extension_point_name, 
1322                  g_type_name (extension_point->required_type));
1323       return NULL;
1324     }      
1325
1326   /* It's safe to register the same type multiple times */
1327   for (l = extension_point->extensions; l != NULL; l = l->next)
1328     {
1329       extension = l->data;
1330       if (extension->type == type)
1331         return extension;
1332     }
1333   
1334   extension = g_slice_new0 (GIOExtension);
1335   extension->type = type;
1336   extension->name = g_strdup (extension_name);
1337   extension->priority = priority;
1338   
1339   extension_point->extensions = g_list_insert_sorted (extension_point->extensions,
1340                                                       extension, extension_prio_compare);
1341   
1342   return extension;
1343 }
1344
1345 /**
1346  * g_io_extension_ref_class:
1347  * @extension: a #GIOExtension
1348  *
1349  * Gets a reference to the class for the type that is 
1350  * associated with @extension.
1351  *
1352  * Returns: (transfer full): the #GTypeClass for the type of @extension
1353  */
1354 GTypeClass *
1355 g_io_extension_ref_class (GIOExtension *extension)
1356 {
1357   return g_type_class_ref (extension->type);
1358 }
1359
1360 /**
1361  * g_io_extension_get_type:
1362  * @extension: a #GIOExtension
1363  *
1364  * Gets the type associated with @extension.
1365  *
1366  * Returns: the type of @extension
1367  */
1368 GType
1369 g_io_extension_get_type (GIOExtension *extension)
1370 {
1371   return extension->type;
1372 }
1373
1374 /**
1375  * g_io_extension_get_name:
1376  * @extension: a #GIOExtension
1377  *
1378  * Gets the name under which @extension was registered.
1379  *
1380  * Note that the same type may be registered as extension
1381  * for multiple extension points, under different names.
1382  *
1383  * Returns: the name of @extension.
1384  */
1385 const char *
1386 g_io_extension_get_name (GIOExtension *extension)
1387 {
1388   return extension->name;
1389 }
1390
1391 /**
1392  * g_io_extension_get_priority:
1393  * @extension: a #GIOExtension
1394  *
1395  * Gets the priority with which @extension was registered.
1396  *
1397  * Returns: the priority of @extension
1398  */
1399 gint
1400 g_io_extension_get_priority (GIOExtension *extension)
1401 {
1402   return extension->priority;
1403 }