source: roaraudio/roard/plugins.c @ 5639:b8cdcac37ffe

Last change on this file since 5639:b8cdcac37ffe was 5639:b8cdcac37ffe, checked in by phi, 12 years ago

Removed roard's sched support (Closes: #277)

File size: 8.3 KB
Line 
1//plugins.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2012
5 *
6 *  This file is part of roard a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  RoarAudio is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 */
25
26#include "roard.h"
27
28#define MAX_PLUGINS    8
29
30static struct _roard_plugin {
31 struct roar_dl_lhandle     * lhandle;
32 int protocols[MAX_PROTOS];
33} g_plugins[MAX_PLUGINS];
34static struct _roard_plugin * _pp = NULL;
35
36static int _plugins_inited = 0;
37
38static int plugin_callback(enum roar_dl_fnreg_action action, int fn, int subtype, const void * object, size_t objectlen, int version, int options, void * userdata, struct roar_dl_lhandle * lhandle);
39static const struct roar_dl_fnreg _plugin_callbacks = {
40 .fn = -1,
41 .subtype = -1,
42 .version = -1,
43 .callback = plugin_callback,
44 .userdata = NULL
45};
46
47static struct _roard_plugin * _find_free(void) {
48 int i;
49
50 ROAR_DBG("_find_free(void) = ?");
51
52 for (i = 0; i < MAX_PLUGINS; i++) {
53  if ( g_plugins[i].lhandle == NULL ) {
54   memset(&(g_plugins[i]), 0, sizeof(struct _roard_plugin));
55   ROAR_DBG("_find_free(void) = %p // i=%i", &(g_plugins[i]), i);
56   return &(g_plugins[i]);
57  }
58 }
59
60 ROAR_DBG("_find_free(void) = NULL");
61 return NULL;
62}
63
64int plugins_preinit  (void) {
65 ROAR_DBG("plugins_preinit(void) = ?");
66
67 memset(g_plugins, 0, sizeof(g_plugins));
68
69#ifdef DEBUG
70 print_pluginlist(FORMAT_NATIVE);
71#endif
72
73 ROAR_DBG("plugins_preinit(void) = 0");
74 return 0;
75}
76
77static inline void plugins_delete(struct _roard_plugin * plugin) {
78 int i;
79
80 ROAR_DBG("plugins_delete(plugin=%p) = ?", plugin);
81
82 roar_dl_appsched_trigger(plugin->lhandle, ROAR_DL_APPSCHED_FREE);
83
84 for (i = 0; i < MAX_PROTOS; i++) {
85  if ( plugin->protocols[i] != -1 ) {
86   clients_unregister_proto(plugin->protocols[i]);
87  }
88 }
89
90 roar_dl_close(plugin->lhandle);
91 memset(plugin, 0, sizeof(struct _roard_plugin));
92 plugin->lhandle = NULL;
93}
94
95static int plugins_init_one(struct _roard_plugin * plugin) {
96 if ( plugin == NULL )
97  return -1;
98
99 ROAR_DBG("plugins_init_one(plugin=%p) = ?", plugin);
100
101 _pp = plugin;
102
103 if ( roar_dl_ra_init(plugin->lhandle, NULL, NULL) == -1 ) {
104  ROAR_WARN("plugins_init(void): Can not RA init lib at %p: %s", plugin->lhandle, roar_error2str(roar_error));
105  plugins_delete(plugin);
106  return -1;
107 }
108
109 roar_dl_appsched_trigger(plugin->lhandle, ROAR_DL_APPSCHED_INIT);
110
111 _pp = NULL;
112
113 return 0;
114}
115
116int plugins_init  (void) {
117 size_t i;
118
119 ROAR_DBG("plugins_init(void) = ?");
120
121#ifdef DEBUG
122 print_pluginlist(FORMAT_NATIVE);
123#endif
124
125 if ( _plugins_inited ) {
126  ROAR_DBG("plugins_init(void) = -1 // error=BUSY");
127  roar_err_set(ROAR_ERROR_BUSY);
128  return -1;
129 }
130
131 ROAR_DL_RFNREG(ROAR_DL_HANDLE_APPLICATION, _plugin_callbacks);
132
133 for (i = 0; i < MAX_PLUGINS; i++) {
134  if ( g_plugins[i].lhandle != NULL ) {
135   plugins_init_one(&(g_plugins[i]));
136  }
137 }
138
139 _plugins_inited = 1;
140
141#ifdef DEBUG
142 print_pluginlist(FORMAT_NATIVE);
143#endif
144
145 ROAR_DBG("plugins_init(void) = 0");
146 return 0;
147}
148
149int plugins_free  (void) {
150 int i;
151
152 ROAR_DBG("plugins_free(void) = ?");
153
154 for (i = 0; i < MAX_PLUGINS; i++) {
155  if ( g_plugins[i].lhandle != NULL ) {
156   plugins_delete(&(g_plugins[i]));
157  }
158 }
159
160 return plugins_preinit();
161}
162
163int plugins_update   (void) {
164 int ret = 0;
165 int i;
166
167 for (i = 0; i < MAX_PLUGINS; i++) {
168  if ( g_plugins[i].lhandle != NULL ) {
169   if ( roar_dl_appsched_trigger(g_plugins[i].lhandle, ROAR_DL_APPSCHED_UPDATE) == -1 )
170    if ( roar_error != ROAR_ERROR_NOENT )
171     ret = -1;
172  }
173 }
174
175 return ret;
176}
177
178int plugins_load  (const char * filename, const char * args) {
179 struct _roard_plugin * next = _find_free();
180 struct roar_dl_librarypara * para;
181 int i;
182
183 ROAR_DBG("plugins_load(filename=\"%s\", args=\"%s\") = ?", filename, args);
184
185 if ( next == NULL )
186  return -1;
187
188 for (i = 0; i < MAX_PLUGINS; i++)
189  next->protocols[i] = -1;
190
191 if ( (para = roar_dl_para_new(args, NULL, ROARD_DL_APPNAME, ROARD_DL_ABIVERSION)) == NULL ) {
192  ROAR_WARN("Can not load plugin (allocate para set): %s: %s", filename, roar_error2str(roar_error));
193  return -1;
194 }
195
196 next->lhandle = roar_dl_open(filename, ROAR_DL_FLAG_PLUGIN, 0 /* we delay this until plugins_init() */, para);
197 roar_dl_para_unref(para);
198
199 if ( next->lhandle == NULL ) {
200  ROAR_ERR("plugins_load(filename='%s'): can not load plugin: %s", filename, roar_dl_errstr(NULL));
201  return -1;
202 }
203
204 if ( _plugins_inited )
205  return plugins_init_one(next);
206
207 return 0;
208}
209
210void print_pluginlist(enum output_format format) {
211 const struct roar_dl_libraryname * libname;
212 struct _roard_plugin * p;
213 size_t i;
214
215 switch (format) {
216  case FORMAT_NATIVE:
217    printf("  Name\n");
218    printf("   Attributes\n");
219    printf("-----------------------------------------------------\n");
220   break;
221  case FORMAT_WIKI:
222  case FORMAT_CSV:
223  default:
224    roar_err_set(ROAR_ERROR_NOTSUP);
225    return;
226 }
227
228 for (i = 0; i < MAX_PLUGINS; i++) {
229  p = &(g_plugins[i]);
230  if ( p->lhandle == NULL )
231   continue;
232
233  libname = roar_dl_getlibname(p->lhandle);
234  if ( libname == NULL ) {
235  } else {
236   printf("  %s\n", libname->libname);
237   printf("   Flags:       %s\n", "");
238   if ( libname->description != NULL )
239    printf("   Description: %s\n", libname->description);
240   if ( libname->contact != NULL )
241    printf("   Contact:     %s\n", libname->contact);
242  }
243 }
244}
245
246int plugins_reg_proto(struct roard_proto         * proto) {
247 int i;
248
249 if ( _pp == NULL )
250  return -1;
251
252 for (i = 0; i < MAX_PROTOS; i++) {
253  if ( _pp->protocols[i] == -1 ) {
254   _pp->protocols[i] = proto->proto;
255   break;
256  }
257 }
258
259 if ( i == MAX_PROTOS ) {
260  roar_err_set(ROAR_ERROR_NOMEM);
261  return -1;
262 }
263
264 return clients_register_proto(proto, _pp->lhandle);
265}
266
267static int plugin_callback(enum roar_dl_fnreg_action action, int fn, int subtype, const void * object, size_t objectlen, int version, int options, void * userdata, struct roar_dl_lhandle * lhandle) {
268
269 (void)options, (void)userdata;
270
271 ROAR_DBG("plugin_callback(action=%i, fn=%i, subtype=%i, object=%p, objectlen=%llu, version=%i, options=0x%x, userdata=%p, lhandle=%p) = ?", (int)action, fn, subtype, object, (long long unsigned int)objectlen, version, options, userdata, lhandle);
272
273 switch (fn) {
274  case ROAR_DL_FN_PROTO:
275    if ( subtype != ROAR_DL_PROTO_SUBTYPE ) {
276     ROAR_DBG("plugin_callback(action=%i, fn=%i, subtype=%i, object=%p, objectlen=%llu, version=%i, options=0x%x, userdata=%p, lhandle=%p) = -1 // error=TYPEMM", (int)action, fn, subtype, object, (long long unsigned int)objectlen, version, options, userdata, lhandle);
277
278     roar_err_set(ROAR_ERROR_TYPEMM);
279     return -1;
280    }
281    if ( objectlen != ROAR_DL_PROTO_SIZE ) {
282     ROAR_DBG("plugin_callback(action=%i, fn=%i, subtype=%i, object=%p, objectlen=%llu, version=%i, options=0x%x, userdata=%p, lhandle=%p) = -1 // error=BADLIB", (int)action, fn, subtype, object, (long long unsigned int)objectlen, version, options, userdata, lhandle);
283     roar_err_set(ROAR_ERROR_BADLIB);
284     return -1;
285    }
286    if ( version != ROAR_DL_PROTO_VERSION ) {
287     ROAR_DBG("plugin_callback(action=%i, fn=%i, subtype=%i, object=%p, objectlen=%llu, version=%i, options=0x%x, userdata=%p, lhandle=%p) = -1 // error=BADVERSION", (int)action, fn, subtype, object, (long long unsigned int)objectlen, version, options, userdata, lhandle);
288     roar_err_set(ROAR_ERROR_BADVERSION);
289     return -1;
290    }
291    switch (action) {
292     case ROAR_DL_FNREG:
293       return clients_register_proto_common(object, lhandle);
294      break;
295     case ROAR_DL_FNUNREG:
296       return clients_unregister_proto(((const struct roard_proto *)object)->proto);
297      break;
298    }
299   break;
300 }
301
302 ROAR_DBG("plugin_callback(action=%i, fn=%i, subtype=%i, object=%p, objectlen=%llu, version=%i, options=0x%x, userdata=%p, lhandle=%p) = -1 // error=NOTSUP", (int)action, fn, subtype, object, (long long unsigned int)objectlen, version, options, userdata, lhandle);
303 roar_err_set(ROAR_ERROR_NOTSUP);
304 return -1;
305}
306
307//ll
Note: See TracBrowser for help on using the repository browser.