4 This file is part of polypaudio.
6 polypaudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published
8 by the Free Software Foundation; either version 2 of the License,
9 or (at your option) any later version.
11 polypaudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with polypaudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
36 #define UNLOAD_POLL_TIME 10
38 static void timeout_callback(struct pa_mainloop_api
*m
, void *id
, const struct timeval
*tv
, void *userdata
) {
39 struct pa_core
*c
= userdata
;
41 assert(c
&& c
->mainloop
== m
&& c
->auto_unload_mainloop_source
== id
);
43 pa_module_unload_unused(c
);
45 gettimeofday(&ntv
, NULL
);
46 ntv
.tv_sec
+= UNLOAD_POLL_TIME
;
47 m
->enable_time(m
, id
, &ntv
);
50 struct pa_module
* pa_module_load(struct pa_core
*c
, const char *name
, const char *argument
) {
51 struct pa_module
*m
= NULL
;
56 m
= pa_xmalloc(sizeof(struct pa_module
));
58 m
->name
= pa_xstrdup(name
);
59 m
->argument
= pa_xstrdup(argument
);
61 if (!(m
->dl
= lt_dlopenext(name
)))
64 if (!(m
->init
= lt_dlsym(m
->dl
, "pa_module_init")))
67 if (!(m
->done
= lt_dlsym(m
->dl
, "pa_module_done")))
76 if (m
->init(c
, m
) < 0)
80 c
->modules
= pa_idxset_new(NULL
, NULL
);
82 if (!c
->auto_unload_mainloop_source
) {
84 gettimeofday(&ntv
, NULL
);
85 ntv
.tv_sec
+= UNLOAD_POLL_TIME
;
86 c
->auto_unload_mainloop_source
= c
->mainloop
->source_time(c
->mainloop
, &ntv
, timeout_callback
, c
);
88 assert(c
->auto_unload_mainloop_source
);
91 r
= pa_idxset_put(c
->modules
, m
, &m
->index
);
92 assert(r
>= 0 && m
->index
!= PA_IDXSET_INVALID
);
94 fprintf(stderr
, "module: loaded %u \"%s\" with argument \"%s\".\n", m
->index
, m
->name
, m
->argument
);
100 pa_xfree(m
->argument
);
112 static void pa_module_free(struct pa_module
*m
) {
113 assert(m
&& m
->done
&& m
->core
);
118 fprintf(stderr
, "module: unloaded %u \"%s\".\n", m
->index
, m
->name
);
121 pa_xfree(m
->argument
);
126 void pa_module_unload(struct pa_core
*c
, struct pa_module
*m
) {
130 if (!(m
= pa_idxset_remove_by_data(c
->modules
, m
, NULL
)))
136 void pa_module_unload_by_index(struct pa_core
*c
, uint32_t index
) {
138 assert(c
&& index
!= PA_IDXSET_INVALID
);
141 if (!(m
= pa_idxset_remove_by_index(c
->modules
, index
)))
147 static void free_callback(void *p
, void *userdata
) {
148 struct pa_module
*m
= p
;
153 void pa_module_unload_all(struct pa_core
*c
) {
159 pa_idxset_free(c
->modules
, free_callback
, NULL
);
162 if (c
->auto_unload_mainloop_source
)
163 c
->mainloop
->cancel_time(c
->mainloop
, c
->auto_unload_mainloop_source
);
164 c
->auto_unload_mainloop_source
= NULL
;
167 static int unused_callback(void *p
, uint32_t index
, int *del
, void *userdata
) {
168 struct pa_module
*m
= p
;
169 time_t *now
= userdata
;
170 assert(p
&& del
&& now
);
172 if (m
->n_used
== 0 && m
->auto_unload
&& m
->last_used_time
+m
->core
->auto_unload_time
<= *now
) {
180 void pa_module_unload_unused(struct pa_core
*c
) {
188 pa_idxset_foreach(c
->modules
, unused_callback
, &now
);
192 struct pa_core
*core
;
196 static void module_unload_once_callback(void *userdata
) {
197 struct once_info
*i
= userdata
;
199 pa_module_unload_by_index(i
->core
, i
->index
);
203 void pa_module_unload_request(struct pa_core
*c
, struct pa_module
*m
) {
207 i
= pa_xmalloc(sizeof(struct once_info
));
210 pa_mainloop_api_once(c
->mainloop
, module_unload_once_callback
, i
);
213 void pa_module_set_used(struct pa_module
*m
, int used
) {
216 if (m
->n_used
!= used
&& used
== 0)
217 time(&m
->last_used_time
);