7f2bc218e4cb42217661a41de592fea0f4ca5d6e
[profile/ivi/pulseaudio.git] / src / module.c
1 #include <limits.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <assert.h>
5 #include <string.h>
6 #include <errno.h>
7
8 #include "module.h"
9
10 struct module* module_load(struct core *c, const char *name, const char *argument) {
11     struct module *m = NULL;
12     int r;
13     
14     assert(c && name);
15
16     m = malloc(sizeof(struct module));
17     assert(m);
18
19     if (!(m->dl = lt_dlopenext(name)))
20         goto fail;
21
22     if (!(m->init = lt_dlsym(m->dl, "module_init")))
23         goto fail;
24
25     if (!(m->done = lt_dlsym(m->dl, "module_done")))
26         goto fail;
27     
28     m->name = strdup(name);
29     m->argument = argument ? strdup(argument) : NULL;
30     m->userdata = NULL;
31     m->core = c;
32
33     assert(m->init);
34     if (m->init(c, m) < 0)
35         goto fail;
36
37     if (!c->modules)
38         c->modules = idxset_new(NULL, NULL);
39     
40     assert(c->modules);
41     r = idxset_put(c->modules, m, &m->index);
42     assert(r >= 0 && m->index != IDXSET_INVALID);
43
44     fprintf(stderr, "module: loaded %u \"%s\" with argument \"%s\".\n", m->index, m->name, m->argument);
45     
46     return m;
47     
48 fail:
49     if (m) {
50         free(m->argument);
51         free(m->name);
52         
53         if (m->dl)
54             lt_dlclose(m->dl);
55
56         free(m);
57     }
58
59     return NULL;
60 }
61
62 static void module_free(struct module *m) {
63     assert(m && m->done && m->core);
64     m->done(m->core, m);
65
66     lt_dlclose(m->dl);
67     
68     fprintf(stderr, "module: unloaded %u \"%s\".\n", m->index, m->name);
69
70     free(m->name);
71     free(m->argument);
72     free(m);
73 }
74
75
76 void module_unload(struct core *c, struct module *m) {
77     assert(c && m);
78
79     assert(c->modules);
80     if (!(m = idxset_remove_by_data(c->modules, m, NULL)))
81         return;
82
83     module_free(m);
84 }
85
86 void module_unload_by_index(struct core *c, uint32_t index) {
87     struct module *m;
88     assert(c && index != IDXSET_INVALID);
89
90     assert(c->modules);
91     if (!(m = idxset_remove_by_index(c->modules, index)))
92         return;
93
94     module_free(m);
95 }
96
97 void free_callback(void *p, void *userdata) {
98     struct module *m = p;
99     assert(m);
100     module_free(m);
101 }
102
103 void module_unload_all(struct core *c) {
104     assert(c);
105
106     if (!c->modules)
107         return;
108
109     idxset_free(c->modules, free_callback, NULL);
110     c->modules = NULL;
111 }
112