source: roaraudio/roard/plugins.c @ 5275:811818eb5b81

Last change on this file since 5275:811818eb5b81 was 5275:811818eb5b81, checked in by phi, 12 years ago

Improved plugin loader a lot (Closes: #190)

File size: 4.1 KB
RevLine 
[3353]1//plugins.c:
2
3/*
[4708]4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2011
[3353]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
[3517]21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
[3353]23 *
24 */
25
26#include "roard.h"
27
[3355]28#define MAX_PLUGINS    8
29
[3362]30static struct _roard_plugin {
31 struct roar_dl_lhandle     * lhandle;
32 struct roard_plugins_sched * sched;
[5275]33 int protocols[MAX_PROTOS];
[3362]34} g_plugins[MAX_PLUGINS];
35static struct _roard_plugin * _pp = NULL;
[3355]36
[3362]37static struct _roard_plugin * _find_free(void) {
[3355]38 int i;
39
40 for (i = 0; i < MAX_PLUGINS; i++) {
[3362]41  if ( g_plugins[i].lhandle == NULL ) {
42   memset(&(g_plugins[i]), 0, sizeof(struct _roard_plugin));
[3355]43   return &(g_plugins[i]);
[3362]44  }
[3355]45 }
46
47 return NULL;
48}
49
[3354]50int plugins_preinit  (void) {
[3355]51 memset(g_plugins, 0, sizeof(g_plugins));
52
[3354]53 return 0;
54}
55
[5275]56static void inline plugins_delete(struct _roard_plugin * plugin) {
57 int i;
58
59 if ( plugin->sched != NULL )
60  if ( plugin->sched->free != NULL )
61   plugin->sched->free();
62
63 for (i = 0; i < MAX_PROTOS; i++) {
64  if ( plugin->protocols[i] != -1 ) {
65   clients_unregister_proto(plugin->protocols[i]);
66  }
67 }
68
69 roar_dl_close(plugin->lhandle);
70 memset(plugin, 0, sizeof(struct _roard_plugin));
71 plugin->lhandle = NULL;
72}
73
[3354]74int plugins_init  (void) {
[3355]75 int i;
76
77 for (i = 0; i < MAX_PLUGINS; i++) {
[3362]78  if ( g_plugins[i].lhandle != NULL ) {
79   _pp = &(g_plugins[i]);
80
[4682]81   _pp->sched = NULL;
82
[5275]83   if ( roar_dl_ra_init(g_plugins[i].lhandle, NULL, NULL) == -1 ) {
84    ROAR_WARN("plugins_init(void): Can not RA init lib at %p: %s", g_plugins[i].lhandle, roar_error2str(roar_error));
85    plugins_delete(&(g_plugins[i]));
86    continue;
87   }
[3362]88
[4682]89   if ( g_plugins[i].sched != NULL )
90    if ( g_plugins[i].sched->init != NULL )
91     g_plugins[i].sched->init();
[3362]92
93   _pp = NULL;
[3355]94  }
95 }
96
[3354]97 return 0;
98}
[3353]99
[3354]100int plugins_free  (void) {
[3355]101 int i;
102
103 for (i = 0; i < MAX_PLUGINS; i++) {
[3362]104  if ( g_plugins[i].lhandle != NULL ) {
[5275]105   plugins_delete(&(g_plugins[i]));
[3355]106  }
107 }
108
[3357]109 return plugins_preinit();
[3354]110}
111
[3362]112int plugins_update   (void) {
113 int ret = 0;
114 int i;
115
116 for (i = 0; i < MAX_PLUGINS; i++)
117  if ( g_plugins[i].lhandle != NULL )
[4682]118   if ( g_plugins[i].sched != NULL )
119    if ( g_plugins[i].sched->update != NULL )
120     if ( g_plugins[i].sched->update() == -1 )
121      ret = -1;
[3362]122
123 return ret;
124}
125
[5275]126int plugins_load  (const char * filename, const char * args) {
[3362]127 struct _roard_plugin * next = _find_free();
[5275]128 struct roar_dl_librarypara * para;
129 int i;
[3355]130
131 if ( next == NULL )
132  return -1;
133
[5275]134 for (i = 0; i < MAX_PROTOS; i++)
135  next->protocols[i] = -1;
136
137 if ( (para = roar_dl_para_new(args, NULL, ROARD_DL_APPNAME, ROARD_DL_ABIVERSION)) == NULL ) {
138  ROAR_WARN("Can not load plugin (allocate para set): %s: %s", filename, roar_error2str(roar_error));
139  return -1;
140 }
141
142 next->lhandle = roar_dl_open(filename, ROAR_DL_FLAG_DEFAUTS, 0 /* we delay this until plugins_init() */, para);
143 roar_dl_para_unref(para);
144
[3365]145 if ( next->lhandle == NULL ) {
146  ROAR_ERR("plugins_load(filename='%s'): can not load plugin: %s", filename, roar_dl_errstr(NULL));
[3355]147  return -1;
[3365]148 }
[3355]149
150 return 0;
[3354]151}
[3353]152
[3362]153int plugins_reg_sched(struct roard_plugins_sched * sched) {
154 if ( _pp == NULL )
155  return -1;
156
157 _pp->sched = sched;
158
159 return 0;
160}
161
[4680]162int plugins_reg_proto(struct roard_proto         * proto) {
[5275]163 int i;
164
[4680]165 if ( _pp == NULL )
166  return -1;
167
[5275]168 for (i = 0; i < MAX_PROTOS; i++) {
169  if ( _pp->protocols[i] == -1 ) {
170   _pp->protocols[i] = proto->proto;
171   break;
172  }
173 }
174
175 if ( i == MAX_PROTOS ) {
176  roar_err_set(ROAR_ERROR_NOMEM);
177  return -1;
178 }
179
[4680]180 return clients_register_proto(proto);
181}
182
[3353]183//ll
Note: See TracBrowser for help on using the repository browser.