source: roaraudio/roard/plugins.c @ 5312:27ec111dc8c5

Last change on this file since 5312:27ec111dc8c5 was 5312:27ec111dc8c5, checked in by phi, 12 years ago

added support for seperate contextes for roardl/plugins. Currently incudes error state and a global per handle data segment. This does not work for statically linked librarys (yet). support for per-context notify core needs to be added/completed.

File size: 4.5 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   roar_dl_context_restore(plugin->lhandle);
62   plugin->sched->free();
63   roar_dl_context_store(plugin->lhandle);
64  }
65 }
66
67 for (i = 0; i < MAX_PROTOS; i++) {
68  if ( plugin->protocols[i] != -1 ) {
69   clients_unregister_proto(plugin->protocols[i]);
70  }
71 }
72
73 roar_dl_close(plugin->lhandle);
74 memset(plugin, 0, sizeof(struct _roard_plugin));
75 plugin->lhandle = NULL;
76}
77
78int plugins_init  (void) {
79 int i;
80
81 for (i = 0; i < MAX_PLUGINS; i++) {
82  if ( g_plugins[i].lhandle != NULL ) {
83   _pp = &(g_plugins[i]);
84
85   _pp->sched = NULL;
86
87   if ( roar_dl_ra_init(g_plugins[i].lhandle, NULL, NULL) == -1 ) {
88    ROAR_WARN("plugins_init(void): Can not RA init lib at %p: %s", g_plugins[i].lhandle, roar_error2str(roar_error));
89    plugins_delete(&(g_plugins[i]));
90    continue;
91   }
92
93   if ( g_plugins[i].sched != NULL ) {
94    if ( g_plugins[i].sched->init != NULL ) {
95     roar_dl_context_restore(g_plugins[i].lhandle);
96     g_plugins[i].sched->init();
97     roar_dl_context_store(g_plugins[i].lhandle);
98    }
99   }
100
101   _pp = NULL;
102  }
103 }
104
105 return 0;
106}
107
108int plugins_free  (void) {
109 int i;
110
111 for (i = 0; i < MAX_PLUGINS; i++) {
112  if ( g_plugins[i].lhandle != NULL ) {
113   plugins_delete(&(g_plugins[i]));
114  }
115 }
116
117 return plugins_preinit();
118}
119
120int plugins_update   (void) {
121 int ret = 0;
122 int i;
123
124 for (i = 0; i < MAX_PLUGINS; i++) {
125  if ( g_plugins[i].lhandle != NULL ) {
126   if ( g_plugins[i].sched != NULL ) {
127    if ( g_plugins[i].sched->update != NULL ) {
128     roar_dl_context_restore(g_plugins[i].lhandle);
129     if ( g_plugins[i].sched->update() == -1 )
130      ret = -1;
131     roar_dl_context_store(g_plugins[i].lhandle);
132    }
133   }
134  }
135 }
136
137 return ret;
138}
139
140int plugins_load  (const char * filename, const char * args) {
141 struct _roard_plugin * next = _find_free();
142 struct roar_dl_librarypara * para;
143 int i;
144
145 if ( next == NULL )
146  return -1;
147
148 for (i = 0; i < MAX_PROTOS; i++)
149  next->protocols[i] = -1;
150
151 if ( (para = roar_dl_para_new(args, NULL, ROARD_DL_APPNAME, ROARD_DL_ABIVERSION)) == NULL ) {
152  ROAR_WARN("Can not load plugin (allocate para set): %s: %s", filename, roar_error2str(roar_error));
153  return -1;
154 }
155
156 next->lhandle = roar_dl_open(filename, ROAR_DL_FLAG_DEFAUTS, 0 /* we delay this until plugins_init() */, para);
157 roar_dl_para_unref(para);
158
159 if ( next->lhandle == NULL ) {
160  ROAR_ERR("plugins_load(filename='%s'): can not load plugin: %s", filename, roar_dl_errstr(NULL));
161  return -1;
162 }
163
164 return 0;
165}
166
167int plugins_reg_sched(struct roard_plugins_sched * sched) {
168 if ( _pp == NULL )
169  return -1;
170
171 _pp->sched = sched;
172
173 return 0;
174}
175
176int plugins_reg_proto(struct roard_proto         * proto) {
177 int i;
178
179 if ( _pp == NULL )
180  return -1;
181
182 for (i = 0; i < MAX_PROTOS; i++) {
183  if ( _pp->protocols[i] == -1 ) {
184   _pp->protocols[i] = proto->proto;
185   break;
186  }
187 }
188
189 if ( i == MAX_PROTOS ) {
190  roar_err_set(ROAR_ERROR_NOMEM);
191  return -1;
192 }
193
194 return clients_register_proto(proto, _pp->lhandle);
195}
196
197//ll
Note: See TracBrowser for help on using the repository browser.