source: trunk/third/bonobo-activation/bonobo-activation/bonobo-activation-shlib.c @ 18311

Revision 18311, 9.3 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18310, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
2/*
3 *  bonobo-activation: A library for accessing bonobo-activation-server.
4 *
5 *  Copyright (C) 1999, 2000 Red Hat, Inc.
6 *  Copyright (C) 2000 Eazel, Inc.
7 *
8 *  This library is free software; you can redistribute it and/or
9 *  modify it under the terms of the GNU Library General Public
10 *  License as published by the Free Software Foundation; either
11 *  version 2 of the License, or (at your option) any later version.
12 *
13 *  This library is distributed in the hope that it will be useful,
14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 *  Library General Public License for more details.
17 *
18 *  You should have received a copy of the GNU Library General Public
19 *  License along with this library; if not, write to the Free
20 *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 *  Author: Elliot Lee <sopwith@redhat.com>
23 */
24#include <config.h>
25#include <bonobo-activation/bonobo-activation-shlib.h>
26
27#include <bonobo-activation/Bonobo_GenericFactory.h>
28#include <bonobo-activation/bonobo-activation-i18n.h>
29#include <bonobo-activation/bonobo-activation-init.h>
30#include <bonobo-activation/bonobo-activation-private.h>
31#include <gmodule.h>
32
33/* ORBit-specific hack */
34#include <orbit/poa/poa.h>
35
36typedef struct
37{
38        GModule *loaded;
39        int refcount;
40        char filename[1];
41}
42ActivePluginInfo;
43
44static GHashTable *living_by_filename = NULL;
45
46static void
47gnome_plugin_unload (gpointer data, gpointer user_data)
48{
49        ActivePluginInfo *api = user_data;
50        g_module_close (api->loaded);
51        g_hash_table_remove (living_by_filename, api->filename);
52        g_free (api);
53}
54
55
56/**
57 * bonobo_activation_activate_shlib_server:
58 * @sh:
59 * @ev:
60 *
61 * Private function.
62 *
63 * Return value:
64 */
65CORBA_Object
66bonobo_activation_activate_shlib_server (Bonobo_ActivationResult *sh,
67                                         CORBA_Environment *ev)
68{
69        CORBA_Object retval;
70        const BonoboActivationPlugin *plugin;
71        ActivePluginInfo *local_plugin_info = NULL;
72        const BonoboActivationPluginObject *pobj;
73        int i;
74        PortableServer_POA poa;
75        CORBA_ORB orb;
76        char *filename;
77        const char *iid;
78
79        g_return_val_if_fail (sh->res._d == Bonobo_ACTIVATION_RESULT_SHLIB,
80                              CORBA_OBJECT_NIL);
81        g_return_val_if_fail (sh->res._u.res_shlib._length > 0,
82                              CORBA_OBJECT_NIL);
83
84        /* The location info is at the end to of the string list */
85        filename = sh->res._u.res_shlib._buffer[sh->res._u.res_shlib._length - 1];
86        if (living_by_filename)
87                local_plugin_info =
88                        g_hash_table_lookup (living_by_filename, filename);
89
90        if (!local_plugin_info) {
91                /* We have to load the thing from scratch */
92                GModule *gmod;
93                gboolean success;
94
95                gmod = g_module_open (filename, G_MODULE_BIND_LAZY);
96                if (!gmod) {
97                        char *error_string;
98                        Bonobo_GeneralError *error = Bonobo_GeneralError__alloc ();
99
100                        error_string = g_strdup_printf (
101                                _("g_module_open of `%s' failed with `%s'"),
102                                filename, g_module_error ());
103                        error->description = CORBA_string_dup (error_string);
104                        CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
105                                             ex_Bonobo_GeneralError, error);
106                        g_free (error_string);
107                        return CORBA_OBJECT_NIL; /* Couldn't load it */
108                }
109               
110                success = g_module_symbol (gmod, "Bonobo_Plugin_info",
111                                           (gpointer *) &plugin);
112                if (!success) {
113                        char *error_string;
114                        Bonobo_GeneralError *error = Bonobo_GeneralError__alloc ();
115
116                        g_module_close (gmod);
117
118                        error_string = g_strdup_printf (
119                                _("Can't find symbol Bonobo_Plugin_info in `%s'"),
120                                filename);
121                        error->description = CORBA_string_dup (error_string);
122                        CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
123                                             ex_Bonobo_GeneralError, error);
124                        g_free (error_string);
125                        return CORBA_OBJECT_NIL;
126                }
127
128                local_plugin_info =
129                        g_malloc (sizeof (ActivePluginInfo) +
130                                  strlen (filename) + 1);
131
132                local_plugin_info->refcount = 0;
133                local_plugin_info->loaded = gmod;
134                strcpy (local_plugin_info->filename, filename);
135
136                if (!living_by_filename)
137                        living_by_filename =
138                                g_hash_table_new (g_str_hash, g_str_equal);
139
140                g_hash_table_insert (living_by_filename,
141                                     local_plugin_info->filename,
142                                     local_plugin_info);
143        } else {
144                int success;
145
146                success =
147                        g_module_symbol (local_plugin_info->loaded,
148                                         "Bonobo_Plugin_info",
149                                         (gpointer *) & plugin);
150                if (!success) {
151                        char *error_string;
152                        Bonobo_GeneralError *error = Bonobo_GeneralError__alloc ();
153
154                        error_string = g_strdup_printf (
155                                _("Can't find symbol Bonobo_Plugin_info in `%s'"),
156                                filename);
157                        error->description = CORBA_string_dup (error_string);
158                        CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
159                                             ex_Bonobo_GeneralError, error);
160                        g_free (error_string);
161                        return CORBA_OBJECT_NIL;
162                }
163        }
164
165        retval = CORBA_OBJECT_NIL;
166
167        orb = bonobo_activation_orb_get ();
168        poa = (PortableServer_POA)
169                CORBA_ORB_resolve_initial_references (orb, "RootPOA", ev);
170
171        /* Index into the string list one element from the end to get the iid of the shlib */
172        iid = sh->res._u.res_shlib._buffer[sh->res._u.res_shlib._length - 2];
173        for (pobj = plugin->plugin_object_list; pobj->iid; pobj++) {
174                if (strcmp (iid, pobj->iid) == 0) {
175                        /* Found a match */
176                        break;
177                }
178        }
179
180        if (pobj->iid) {
181                /* Activate the shlib */
182                retval = pobj->activate (poa, pobj->iid, local_plugin_info, ev);
183
184                if (ev->_major != CORBA_NO_EXCEPTION)
185                        retval = CORBA_OBJECT_NIL;
186
187                /* Activate the factiories contained in the shlib */
188                i =  sh->res._u.res_shlib._length - 2;
189                for (i--; i >= 0 && !CORBA_Object_is_nil (retval, ev); i--) {
190                        CORBA_Object new_retval;
191
192                        iid = sh->res._u.res_shlib._buffer[i];
193
194                        new_retval =
195                                Bonobo_GenericFactory_createObject (
196                                        retval, (char *) iid, ev);
197
198                        if (ev->_major != CORBA_NO_EXCEPTION
199                            || CORBA_Object_is_nil (new_retval, ev)) {
200                                if (ev->_major == CORBA_NO_EXCEPTION) {
201                                        Bonobo_GeneralError *error = Bonobo_GeneralError__alloc ();
202                                        char *error_string = g_strdup_printf (
203                                                _("Factory `%s' returned NIL for `%s'"),
204                                                pobj->iid, iid);
205                                        error->description = CORBA_string_dup (error_string);
206                                        CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
207                                                             ex_Bonobo_GeneralError, error);
208                                        g_free (error_string);
209                                       
210                                }
211                                new_retval = CORBA_OBJECT_NIL;
212                        }
213
214                        CORBA_Object_release (retval, ev);
215                        retval = new_retval;
216                }
217        } else {
218                Bonobo_GeneralError *error = Bonobo_GeneralError__alloc ();
219                char *error_string = g_strdup_printf (
220                        _("Shlib `%s' didn't contain `%s'"),
221                        filename, iid);
222                error->description = CORBA_string_dup (error_string);
223                CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
224                                     ex_Bonobo_GeneralError, error);
225                g_free (error_string);
226        }
227
228        CORBA_Object_release ((CORBA_Object) poa, ev);
229
230        return retval;
231}
232
233/**
234 * bonobo_activation_plugin_use:
235 * @servant: The servant that was created
236 * @impl_ptr: The impl_ptr that was passed to the original activation routine
237 *
238 * You should call this routine to activate a shared library-based
239 * CORBA Object. It will be called by OAF if the component exports
240 * correctly an %BonoboActivationPlugin structure named "Bonobo_Plugin_info".
241 */
242void
243bonobo_activation_plugin_use (PortableServer_Servant servant, gpointer impl_ptr)
244{
245        ActivePluginInfo *local_plugin_info = impl_ptr;
246
247        local_plugin_info->refcount++;
248
249#if 0
250        ORBit_servant_set_deathwatch (servant, &(local_plugin_info->refcount),
251                                      gnome_plugin_unload, local_plugin_info);
252#endif
253}
254
255static gboolean
256bonobo_activation_plugin_real_unuse (gpointer impl_ptr)
257{
258        ActivePluginInfo *api;
259
260        g_return_val_if_fail (impl_ptr, FALSE);
261
262        api = impl_ptr;
263
264        api->refcount--;
265
266        if (api->refcount <= 0) {
267                gnome_plugin_unload (&(api->refcount), api);
268        }       
269
270        return FALSE;
271}
272
273/**
274 * bonobo_activation_plugin_unuse:
275 * @impl_ptr: The impl_ptr that was passed to the activation routine
276 *
277 * Side effects: May arrange for the shared library that the
278 * implementation is in to be unloaded.
279 *
280 * When a shlib plugin for a CORBA object is destroying an
281 * implementation, it should call this function to make sure that the
282 * shared library is unloaded as needed.
283 */
284void
285bonobo_activation_plugin_unuse (gpointer impl_ptr)
286{
287        g_idle_add (bonobo_activation_plugin_real_unuse, impl_ptr);
288}
289
Note: See TracBrowser for help on using the repository browser.