source: roaraudio/roard/plugins.c @ 5304:b4e9377c2dff

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

Improved plugin loader a lot (Closes: #190)

File size: 4.1 KB
Line 
1//plugins.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2011
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 struct roard_plugins_sched * sched;
33 int protocols[MAX_PROTOS];
34} g_plugins[MAX_PLUGINS];
35static struct _roard_plugin * _pp = NULL;
36
37static struct _roard_plugin * _find_free(void) {
38 int i;
39
40 for (i = 0; i < MAX_PLUGINS; i++) {
41  if ( g_plugins[i].lhandle == NULL ) {
42   memset(&(g_plugins[i]), 0, sizeof(struct _roard_plugin));
43   return &(g_plugins[i]);
44  }
45 }
46
47 return NULL;
48}
49
50int plugins_preinit  (void) {
51 memset(g_plugins, 0, sizeof(g_plugins));
52
53 return 0;
54}
55
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
74int plugins_init  (void) {
75 int i;
76
77 for (i = 0; i < MAX_PLUGINS; i++) {
78  if ( g_plugins[i].lhandle != NULL ) {
79   _pp = &(g_plugins[i]);
80
81   _pp->sched = NULL;
82
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   }
88
89   if ( g_plugins[i].sched != NULL )
90    if ( g_plugins[i].sched->init != NULL )
91     g_plugins[i].sched->init();
92
93   _pp = NULL;
94  }
95 }
96
97 return 0;
98}
99
100int plugins_free  (void) {
101 int i;
102
103 for (i = 0; i < MAX_PLUGINS; i++) {
104  if ( g_plugins[i].lhandle != NULL ) {
105   plugins_delete(&(g_plugins[i]));
106  }
107 }
108
109 return plugins_preinit();
110}
111
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 )
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;
122
123 return ret;
124}
125
126int plugins_load  (const char * filename, const char * args) {
127 struct _roard_plugin * next = _find_free();
128 struct roar_dl_librarypara * para;
129 int i;
130
131 if ( next == NULL )
132  return -1;
133
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
145 if ( next->lhandle == NULL ) {
146  ROAR_ERR("plugins_load(filename='%s'): can not load plugin: %s", filename, roar_dl_errstr(NULL));
147  return -1;
148 }
149
150 return 0;
151}
152
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
162int plugins_reg_proto(struct roard_proto         * proto) {
163 int i;
164
165 if ( _pp == NULL )
166  return -1;
167
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
180 return clients_register_proto(proto);
181}
182
183//ll
Note: See TracBrowser for help on using the repository browser.