~ubuntu-branches/ubuntu/quantal/libbonobo/quantal-201207170711

« back to all changes in this revision

Viewing changes to activation-server/object-directory-corba.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2005-02-18 14:40:51 UTC
  • mto: (3.1.1 etch) (1.1.25 upstream)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20050218144051-fo4h9qh2gim8x3wt
Tags: upstream-2.8.1
ImportĀ upstreamĀ versionĀ 2.8.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
 
2
/*
 
3
 *  oafd: OAF CORBA dameon.
 
4
 *
 
5
 *  Copyright (C) 1999, 2000 Red Hat, Inc.
 
6
 *  Copyright (C) 1999, 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 General Public License as
 
10
 *  published by the Free Software Foundation; either version 2 of the
 
11
 *  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
 *  General Public License for more details.
 
17
 *
 
18
 *  You should have received a copy of the GNU General Public License
 
19
 *  along with this library; if not, write to the Free Software
 
20
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
21
 *
 
22
 *  Authors: Elliot Lee <sopwith@redhat.com>,
 
23
 *
 
24
 */
 
25
 
 
26
#include "config.h"
 
27
 
 
28
#include <stdio.h>
 
29
#include <time.h>
 
30
#include <glib.h>
 
31
#include <sys/stat.h>
 
32
#include <unistd.h>
 
33
#include <string.h>
 
34
 
 
35
#include "server.h"
 
36
#include "object-directory.h"
 
37
#include "bonobo-activation/bonobo-activation-i18n.h"
 
38
#include "bonobo-activation/bonobo-activation-private.h"
 
39
#include "activation-server-corba-extensions.h"
 
40
 
 
41
/* no longer used. */
 
42
#define RESIDUAL_SERVERS 0
 
43
 
 
44
static GObjectClass *parent_class = NULL;
 
45
static gboolean finished_internal_registration = FALSE;
 
46
 
 
47
typedef struct {
 
48
        char *iid;
 
49
        int   n_servers;
 
50
        struct {
 
51
                Bonobo_ActivationEnvironment environment;
 
52
                CORBA_Object                 server;
 
53
        } servers [1]; /* flexible array */
 
54
} ActiveServerList;
 
55
 
 
56
static ObjectDirectory *main_dir = NULL;
 
57
 
 
58
#ifdef BONOBO_ACTIVATION_DEBUG
 
59
static void
 
60
od_dump_list (ObjectDirectory * od)
 
61
{
 
62
#if 0
 
63
        int i, j, k;
 
64
 
 
65
        for (i = 0; i < od->attr_servers->_length; i++) {
 
66
                g_print ("IID %s, type %s, location %s\n",
 
67
                         od->attr_servers->_buffer[i].iid,
 
68
                         od->attr_servers->_buffer[i].server_type,
 
69
                         od->attr_servers->_buffer[i].location_info);
 
70
                for (j = 0; j < od->attr_servers->_buffer[i].props._length;
 
71
                     j++) {
 
72
                        Bonobo_ActivationProperty *prop =
 
73
                                &(od->attr_servers->_buffer[i].
 
74
                                  props._buffer[j]);
 
75
                        if (strchr (prop->name, '-') != NULL) /* Translated, likely to
 
76
                                                         be annoying garbage value */
 
77
                                continue;
 
78
 
 
79
                        g_print ("    %s = ", prop->name);
 
80
                        switch (prop->v._d) {
 
81
                        case Bonobo_ACTIVATION_P_STRING:
 
82
                                g_print ("\"%s\"\n", prop->v._u.value_string);
 
83
                                break;
 
84
                        case Bonobo_ACTIVATION_P_NUMBER:
 
85
                                g_print ("%f\n", prop->v._u.value_number);
 
86
                                break;
 
87
                        case Bonobo_ACTIVATION_P_BOOLEAN:
 
88
                                g_print ("%s\n",
 
89
                                         prop->v.
 
90
                                         _u.value_boolean ? "TRUE" : "FALSE");
 
91
                                break;
 
92
                        case Bonobo_ACTIVATION_P_STRINGV:
 
93
                                g_print ("[");
 
94
                                for (k = 0;
 
95
                                     k < prop->v._u.value_stringv._length;
 
96
                                     k++) {
 
97
                                        g_print ("\"%s\"",
 
98
                                                 prop->v._u.
 
99
                                                 value_stringv._buffer[k]);
 
100
                                        if (k <
 
101
                                            (prop->v._u.
 
102
                                             value_stringv._length - 1))
 
103
                                                g_print (", ");
 
104
                                }
 
105
                                g_print ("]\n");
 
106
                                break;
 
107
                        }
 
108
                }
 
109
        }
 
110
#endif
 
111
}
 
112
#endif
 
113
 
 
114
static gboolean
 
115
registry_directory_needs_update (ObjectDirectory *od,
 
116
                                 const char      *directory)
 
117
{
 
118
        gboolean needs_update;
 
119
        struct stat statbuf;
 
120
        time_t old_mtime;
 
121
 
 
122
        if (stat (directory, &statbuf) != 0) {
 
123
                return FALSE;
 
124
        }
 
125
 
 
126
        old_mtime = (time_t) g_hash_table_lookup (
 
127
                od->registry_directory_mtimes, directory);
 
128
 
 
129
        g_hash_table_insert (od->registry_directory_mtimes,
 
130
                             (gpointer) directory,
 
131
                             (gpointer) statbuf.st_mtime);
 
132
 
 
133
        needs_update = (old_mtime != statbuf.st_mtime);
 
134
 
 
135
#ifdef BONOBO_ACTIVATION_DEBUG
 
136
        if (needs_update)
 
137
                g_warning ("Compare old_mtime on '%s' with %ld ==? %ld",
 
138
                           directory,
 
139
                           (long) old_mtime, (long) statbuf.st_mtime);
 
140
#endif
 
141
 
 
142
        return needs_update;
 
143
}
 
144
 
 
145
static void
 
146
update_registry (ObjectDirectory *od, gboolean force_reload)
 
147
{
 
148
        int i;
 
149
        time_t cur_time;
 
150
        gboolean must_load;
 
151
        static gboolean doing_reload = FALSE;
 
152
 
 
153
        if (doing_reload)
 
154
                return;
 
155
        doing_reload = TRUE;
 
156
 
 
157
#ifdef BONOBO_ACTIVATION_DEBUG
 
158
        g_warning ("Update registry %p", od->by_iid);
 
159
#endif
 
160
 
 
161
        /* get first time init right */
 
162
        must_load = (od->by_iid == NULL);
 
163
        
 
164
        cur_time = time (NULL);
 
165
 
 
166
        if (cur_time - 5 > od->time_did_stat) {
 
167
                od->time_did_stat = cur_time;
 
168
                
 
169
                for (i = 0; od->registry_source_directories[i] != NULL; i++) {
 
170
                        if (registry_directory_needs_update 
 
171
                            (od, od->registry_source_directories[i]))
 
172
                                must_load = TRUE;
 
173
                }
 
174
        }
 
175
        
 
176
        if (must_load || force_reload) {
 
177
                /*
 
178
                 * FIXME bugzilla.eazel.com 2727: we should only reload those
 
179
                 * directories that have actually changed instead of reloading
 
180
                 * all when any has changed. 
 
181
                 */
 
182
#ifdef BONOBO_ACTIVATION_DEBUG
 
183
                g_warning ("Re-load %d %d", must_load, force_reload);
 
184
#endif
 
185
                if (od->attr_servers)
 
186
                        CORBA_free (od->attr_servers);
 
187
                od->attr_servers = CORBA_sequence_Bonobo_ServerInfo__alloc ();
 
188
                bonobo_server_info_load (od->registry_source_directories,
 
189
                                         od->attr_servers,
 
190
                                         od->attr_runtime_servers,
 
191
                                         &od->by_iid,
 
192
                                         bonobo_activation_hostname_get ());
 
193
                od->time_did_stat = od->time_list_changed = time (NULL);
 
194
 
 
195
#ifdef BONOBO_ACTIVATION_DEBUG
 
196
                od_dump_list (od);
 
197
#endif
 
198
                if (must_load)
 
199
                        activation_clients_cache_notify ();
 
200
        }
 
201
 
 
202
        doing_reload = FALSE;
 
203
}
 
204
 
 
205
static gchar **
 
206
split_path_unique (const char *colon_delimited_path)
 
207
{
 
208
        int i, max;
 
209
        gboolean different;
 
210
        gchar **ret, **wrk;
 
211
        GSList *l, *tmp = NULL;
 
212
 
 
213
        g_return_val_if_fail (colon_delimited_path != NULL, NULL);
 
214
 
 
215
        wrk = g_strsplit (colon_delimited_path, ":", -1);
 
216
 
 
217
        g_return_val_if_fail (wrk != NULL, NULL);
 
218
 
 
219
        for (max = i = 0; wrk [i]; i++) {
 
220
                different = TRUE;
 
221
                for (l = tmp; l; l = l->next) {
 
222
                        if (!strcmp (l->data, wrk [i])) {
 
223
                                different = FALSE;
 
224
                        } else if (wrk [i] == '\0') {
 
225
                                different = FALSE;
 
226
                        }
 
227
                }
 
228
                if (different) {
 
229
                        tmp = g_slist_prepend (tmp, g_strdup (wrk [i]));
 
230
                        max++;
 
231
                }
 
232
        }
 
233
 
 
234
        tmp = g_slist_reverse (tmp);
 
235
 
 
236
        ret = g_new (char *, max + 1);
 
237
 
 
238
        for (l = tmp, i = 0; l; l = l->next)
 
239
                ret [i++] = l->data;
 
240
 
 
241
        ret [i] = NULL;
 
242
 
 
243
        g_slist_free (tmp);
 
244
        g_strfreev (wrk);
 
245
 
 
246
        return ret;
 
247
}
 
248
 
 
249
static Bonobo_ServerInfoListCache *
 
250
impl_Bonobo_ObjectDirectory__get_servers (
 
251
        PortableServer_Servant           servant,
 
252
        Bonobo_CacheTime                 only_if_newer,
 
253
        CORBA_Environment               *ev)
 
254
{
 
255
        ObjectDirectory *od = OBJECT_DIRECTORY (servant);
 
256
        Bonobo_ServerInfoListCache      *retval;
 
257
 
 
258
        update_registry (od, FALSE);
 
259
 
 
260
        retval = Bonobo_ServerInfoListCache__alloc ();
 
261
 
 
262
        retval->_d = (only_if_newer < od->time_list_changed);
 
263
        if (retval->_d) {
 
264
                retval->_u.server_list = *od->attr_servers;
 
265
                CORBA_sequence_set_release (&retval->_u.server_list,
 
266
                                            CORBA_FALSE);
 
267
        }
 
268
 
 
269
        return retval;
 
270
}
 
271
 
 
272
typedef struct {
 
273
        Bonobo_ImplementationID *seq;
 
274
        int                      last_used;
 
275
} StateCollectionInfo;
 
276
 
 
277
static void
 
278
collate_active_server (char *key, gpointer value, StateCollectionInfo *sci)
 
279
{
 
280
        sci->seq [(sci->last_used)++] = CORBA_string_dup (key);
 
281
}
 
282
 
 
283
static Bonobo_ServerStateCache *
 
284
impl_Bonobo_ObjectDirectory_get_active_servers (
 
285
        PortableServer_Servant           servant,
 
286
        Bonobo_CacheTime                 only_if_newer,
 
287
        CORBA_Environment               *ev)
 
288
{
 
289
        ObjectDirectory *od = OBJECT_DIRECTORY (servant);
 
290
        Bonobo_ServerStateCache         *retval;
 
291
 
 
292
        retval = Bonobo_ServerStateCache__alloc ();
 
293
 
 
294
        retval->_d = (only_if_newer < od->time_active_changed);
 
295
        if (retval->_d) {
 
296
                StateCollectionInfo sci;
 
297
 
 
298
                retval->_u.active_servers._length =
 
299
                        g_hash_table_size (od->active_server_lists);
 
300
                retval->_u.active_servers._buffer = sci.seq =
 
301
                        CORBA_sequence_Bonobo_ImplementationID_allocbuf
 
302
                        (retval->_u.active_servers._length);
 
303
                sci.last_used = 0;
 
304
 
 
305
                g_hash_table_foreach (od->active_server_lists,
 
306
                                      (GHFunc) collate_active_server, &sci);
 
307
                CORBA_sequence_set_release (&(retval->_u.active_servers),
 
308
                                            CORBA_TRUE);
 
309
        }
 
310
 
 
311
        return retval;
 
312
}
 
313
 
 
314
static CORBA_Object 
 
315
od_get_active_server (ObjectDirectory    *od,
 
316
                      const char                         *iid,
 
317
                      const Bonobo_ActivationEnvironment *environment)
 
318
{
 
319
        ActiveServerList *servers;
 
320
        CORBA_Object      retval;
 
321
        int               i;
 
322
 
 
323
        servers = g_hash_table_lookup (od->active_server_lists, iid);
 
324
        if (!servers)
 
325
                return CORBA_OBJECT_NIL;
 
326
 
 
327
        retval = CORBA_OBJECT_NIL;
 
328
 
 
329
        for (i = 0; i < servers->n_servers; i++) {
 
330
                if (Bonobo_ActivationEnvironment_match (
 
331
                                &servers->servers [i].environment,
 
332
                                environment)) {
 
333
                        retval = servers->servers [i].server;
 
334
                        break;
 
335
                }
 
336
        }
 
337
        if (retval != CORBA_OBJECT_NIL &&
 
338
            !CORBA_Object_non_existent (retval, NULL))
 
339
                return CORBA_Object_duplicate (retval, NULL);
 
340
 
 
341
        return CORBA_OBJECT_NIL;
 
342
}
 
343
 
 
344
 
 
345
/*
 
346
 * returns (@merged_environment) new environment as result of
 
347
 * merging activation request environment and client registered
 
348
 * environment; the activation supplied environment takes precedence
 
349
 * over the client one
 
350
 */
 
351
static void
 
352
od_merge_client_environment (ObjectDirectory                    *od,
 
353
                             Bonobo_ServerInfo const            *server,
 
354
                             const Bonobo_ActivationEnvironment *environment,
 
355
                             Bonobo_ActivationEnvironment       *merged_environment,
 
356
                             Bonobo_ActivationClient             client)
 
357
{
 
358
        GArray *array;
 
359
        int i, serverinfo_env_idx;
 
360
        const Bonobo_ActivationEnvironment *client_env;
 
361
        const Bonobo_StringList *serverinfo_env = NULL;
 
362
 
 
363
        array = g_array_new (FALSE, FALSE, sizeof (Bonobo_ActivationEnvValue));
 
364
 
 
365
          /* copy all values from @environment */
 
366
        for (i = 0; i < environment->_length; ++i)
 
367
                g_array_append_val (array, environment->_buffer[i]);
 
368
 
 
369
        if (client == CORBA_OBJECT_NIL)
 
370
                goto exit;
 
371
 
 
372
        /* scan through server properties */
 
373
        if (!server) goto exit;
 
374
        for (i = 0; i < server->props._length; ++i) {
 
375
                if (strcmp (server->props._buffer[i].name, "bonobo:environment") == 0)
 
376
                {
 
377
                        Bonobo_ActivationPropertyValue const *prop =
 
378
                                &server->props._buffer[i].v;
 
379
                        if (prop->_d == Bonobo_ACTIVATION_P_STRINGV)
 
380
                                serverinfo_env = &prop->_u.value_stringv;
 
381
                        else
 
382
                                g_warning ("bonobo:environment should have type stringv");
 
383
                        break;
 
384
                }
 
385
        }
 
386
        if (!serverinfo_env)
 
387
                goto exit;
 
388
 
 
389
        /* do the actual merging */
 
390
        client_env = (const Bonobo_ActivationEnvironment *)
 
391
                g_hash_table_lookup (od->client_envs, client);
 
392
 
 
393
        if (!client_env)
 
394
                goto exit;
 
395
 
 
396
        for (serverinfo_env_idx = 0;
 
397
             serverinfo_env_idx < serverinfo_env->_length; ++serverinfo_env_idx)
 
398
        {
 
399
                CORBA_char *env = serverinfo_env->_buffer[serverinfo_env_idx];
 
400
                gboolean duplicated_env = FALSE;
 
401
 
 
402
                /* check if array already has this environment */
 
403
                for (i = 0; i < environment->_length; ++i) {
 
404
                        if (strcmp (environment->_buffer[i].name, env) == 0) {
 
405
                                duplicated_env = TRUE;
 
406
                                break;
 
407
                        }
 
408
                }
 
409
                if (duplicated_env)
 
410
                        continue;
 
411
 
 
412
                /* look for environment in client_env */
 
413
                for (i = 0; i < client_env->_length; ++i) {
 
414
                        if (strcmp (client_env->_buffer[i].name, env) == 0) {
 
415
                                g_array_append_val (array, client_env->_buffer[i]);
 
416
                                break;
 
417
                        }
 
418
                }
 
419
        }
 
420
exit:
 
421
        /* return the resulting environment */
 
422
        merged_environment->_buffer = (Bonobo_ActivationEnvValue *) array->data;
 
423
        merged_environment->_length = merged_environment->_maximum = array->len;
 
424
        g_array_free (array, FALSE);
 
425
}
 
426
 
 
427
 
 
428
static CORBA_Object
 
429
impl_Bonobo_ObjectDirectory_activate (
 
430
        PortableServer_Servant              servant,
 
431
        const CORBA_char                   *iid,
 
432
        const Bonobo_ActivationContext      ac,
 
433
        const Bonobo_ActivationEnvironment *environment,
 
434
        const Bonobo_ActivationFlags        flags,
 
435
        Bonobo_ActivationClient             client,
 
436
        CORBA_Context                       ctx,
 
437
        CORBA_Environment                  *ev)
 
438
{
 
439
        ObjectDirectory *od = OBJECT_DIRECTORY (servant);
 
440
        CORBA_Object                     retval;
 
441
        Bonobo_ServerInfo               *si;
 
442
        ODActivationInfo                 ai;
 
443
#ifdef BONOBO_ACTIVATION_DEBUG
 
444
        static int                       depth = 0;
 
445
#endif
 
446
        Bonobo_ActivationEnvironment merged_environment;
 
447
 
 
448
        od_merge_client_environment (od, (Bonobo_ServerInfo *)
 
449
                                     g_hash_table_lookup (od->by_iid, iid),
 
450
                                     environment, &merged_environment, client);
 
451
 
 
452
        retval = CORBA_OBJECT_NIL;
 
453
 
 
454
        update_registry (od, FALSE);
 
455
 
 
456
        if (!(flags & Bonobo_ACTIVATION_FLAG_PRIVATE)) {
 
457
                retval = od_get_active_server (od, iid, &merged_environment);
 
458
 
 
459
                if (retval != CORBA_OBJECT_NIL) {
 
460
                        g_free (merged_environment._buffer);
 
461
                        return retval;
 
462
                }
 
463
        }
 
464
 
 
465
        if (flags & Bonobo_ACTIVATION_FLAG_EXISTING_ONLY) {
 
466
                return CORBA_OBJECT_NIL;
 
467
        }
 
468
 
 
469
#ifdef BONOBO_ACTIVATION_DEBUG
 
470
        {
 
471
                int i;
 
472
                depth++;
 
473
                for (i = 0; i < depth; i++)
 
474
                        fputc (' ', stderr);
 
475
                fprintf (stderr, "Activate '%s'\n", iid);
 
476
        }
 
477
#endif
 
478
 
 
479
        ai.ac = ac;
 
480
        ai.flags = flags;
 
481
        ai.ctx = ctx;
 
482
 
 
483
        si = g_hash_table_lookup (od->by_iid, iid);
 
484
 
 
485
        if (si) {
 
486
                retval = od_server_activate (
 
487
                                si, &ai, BONOBO_OBJREF (od), &merged_environment, client, ev);
 
488
 
 
489
                /* If we failed to activate - it may be because our
 
490
                 * request re-entered _during_ the activation
 
491
                 * process resulting in a second process being started
 
492
                 * but failing to register - so we'll look up again here
 
493
                 * to see if we can get it.
 
494
                 * FIXME: we should not be forking redundant processes
 
495
                 * while an activation of that same process is on the
 
496
                 * stack.
 
497
                 * FIXME: we only get away with this hack because we
 
498
                 * try and fork another process & thus allow the reply
 
499
                 * from the initial process to be handled in the event
 
500
                 * loop.
 
501
                 */
 
502
                /* FIXME: this path is theoretically redundant now */
 
503
                if (ev->_major != CORBA_NO_EXCEPTION ||
 
504
                    retval == CORBA_OBJECT_NIL) {
 
505
                        retval = od_get_active_server (od, iid, &merged_environment);
 
506
 
 
507
                        if (retval != CORBA_OBJECT_NIL)
 
508
                                CORBA_exception_free (ev);
 
509
                }
 
510
        }
 
511
 
 
512
#ifdef BONOBO_ACTIVATION_DEBUG
 
513
        {
 
514
                int i;
 
515
                for (i = 0; i < depth; i++)
 
516
                        fputc (' ', stderr);
 
517
                fprintf (stderr, "Activated '%s' = %p\n", iid, retval);
 
518
                depth--;
 
519
        }
 
520
#endif
 
521
        g_free (merged_environment._buffer);
 
522
 
 
523
        return retval;
 
524
}
 
525
 
 
526
extern GMainLoop *main_loop;
 
527
 
 
528
static gboolean
 
529
quit_server_timeout (gpointer user_data)
 
530
{
 
531
#ifdef BONOBO_ACTIVATION_DEBUG
 
532
        g_warning ("Quit server !");
 
533
#endif
 
534
 
 
535
        if (!main_dir ||
 
536
            main_dir->n_active_servers > RESIDUAL_SERVERS ||
 
537
            !activation_clients_is_empty_scan ())
 
538
                g_warning ("Serious error handling server count, not quitting");
 
539
        else
 
540
                g_main_loop_quit (main_loop);
 
541
 
 
542
        main_dir->no_servers_timeout = 0;
 
543
 
 
544
        return FALSE;
 
545
}
 
546
 
 
547
void od_finished_internal_registration (void)
 
548
{
 
549
        finished_internal_registration = TRUE;
 
550
}
 
551
 
 
552
void
 
553
check_quit (void)
 
554
{
 
555
        ObjectDirectory *od = main_dir;
 
556
 
 
557
        /* We had some activity - so push out the shutdown timeout */
 
558
        if (od->no_servers_timeout != 0)
 
559
                g_source_remove (od->no_servers_timeout);
 
560
        od->no_servers_timeout = 0;
 
561
 
 
562
        if (od->n_active_servers <= RESIDUAL_SERVERS &&
 
563
            activation_clients_is_empty_scan ())
 
564
                od->no_servers_timeout = g_timeout_add (
 
565
                        SERVER_IDLE_QUIT_TIMEOUT, quit_server_timeout, NULL);
 
566
 
 
567
        od->time_active_changed = time (NULL);
 
568
}
 
569
 
 
570
static void
 
571
remove_active_server_entry (ActiveServerList *servers,
 
572
                            int               index)
 
573
{
 
574
        CORBA_Object_release (servers->servers [index].server, NULL);
 
575
        CORBA_free (servers->servers [index].environment._buffer);
 
576
 
 
577
        if (index != servers->n_servers - 1)
 
578
                memcpy (&servers->servers [index],
 
579
                        &servers->servers [servers->n_servers - 1],
 
580
                        sizeof (servers->servers [index]));
 
581
 
 
582
        servers->n_servers--;
 
583
}
 
584
 
 
585
static ActiveServerList *
 
586
add_active_server_entry (ActiveServerList                   *servers,
 
587
                         const Bonobo_ActivationEnvironment *environment,
 
588
                         CORBA_Object                        object)
 
589
{
 
590
        int index, i;
 
591
 
 
592
        index = servers->n_servers - 1;
 
593
 
 
594
        if (index != 0)
 
595
                servers = g_realloc (servers,
 
596
                                     sizeof (*servers) + sizeof (servers->servers [0]) * index);
 
597
 
 
598
        servers->servers [index].server = CORBA_Object_duplicate (object, NULL);
 
599
 
 
600
        servers->servers [index].environment._length  = environment->_length;
 
601
        servers->servers [index].environment._maximum = environment->_maximum;
 
602
        servers->servers [index].environment._buffer  =
 
603
                                Bonobo_ActivationEnvironment_allocbuf (environment->_length);
 
604
        servers->servers [index].environment._release = TRUE;
 
605
 
 
606
        for (i = 0; i < environment->_length; i++)
 
607
                Bonobo_ActivationEnvValue_copy (
 
608
                        &servers->servers [index].environment._buffer [i],
 
609
                        &environment->_buffer [i]);
 
610
 
 
611
        return servers;
 
612
}
 
613
 
 
614
static gboolean
 
615
prune_dead_servers (gpointer key,
 
616
                    gpointer value,
 
617
                    gpointer user_data)
 
618
{
 
619
        ObjectDirectory *od = user_data;
 
620
        ActiveServerList                *servers = value;
 
621
        int                              i;
 
622
 
 
623
        for (i = 0; i < servers->n_servers; i++) {
 
624
                ORBitConnectionStatus  status;
 
625
                gboolean               dead;
 
626
 
 
627
                status = ORBit_small_get_connection_status (
 
628
                                        servers->servers [i].server);
 
629
 
 
630
                dead = (status == ORBIT_CONNECTION_DISCONNECTED);
 
631
 
 
632
#ifdef BONOBO_ACTIVATION_DEBUG
 
633
                fprintf (stderr, "IID '%20s' (%p), %s \n",
 
634
                         (char *) key, servers->servers [i].server,
 
635
                         dead ? "dead" : "alive");
 
636
#endif
 
637
                if (dead) {
 
638
                        remove_active_server_entry (servers, i);
 
639
 
 
640
                        od->n_active_servers--;
 
641
                        i--;
 
642
                }
 
643
        }
 
644
        
 
645
        return !servers->n_servers;
 
646
}
 
647
 
 
648
static void
 
649
active_server_cnx_broken (ORBitConnection *cnx,
 
650
                          gpointer         dummy)
 
651
 
 
652
{
 
653
        ObjectDirectory *od = main_dir;
 
654
 
 
655
        if (!od) /* shutting down */
 
656
                return;
 
657
 
 
658
        g_hash_table_foreach_remove (od->active_server_lists,
 
659
                                     prune_dead_servers, od);
 
660
#ifdef BONOBO_ACTIVATION_DEBUG
 
661
        g_warning ("After prune: %d live servers",
 
662
                   od->n_active_servers - RESIDUAL_SERVERS);
 
663
#endif
 
664
 
 
665
        check_quit ();
 
666
}
 
667
 
 
668
static void
 
669
add_active_server (ObjectDirectory    *od,
 
670
                   const char                         *iid,
 
671
                   const Bonobo_ActivationEnvironment *environment,
 
672
                   CORBA_Object                       object)
 
673
{
 
674
        ActiveServerList *servers;
 
675
        ORBitConnection  *cnx;
 
676
 
 
677
        cnx = ORBit_small_get_connection (object);
 
678
        if (cnx) {
 
679
                if (!g_object_get_data (G_OBJECT (cnx), "object_count")) {
 
680
                        g_object_set_data (
 
681
                                G_OBJECT (cnx), "object_count", GUINT_TO_POINTER (1));
 
682
                        
 
683
                        g_signal_connect (
 
684
                                cnx, "broken",
 
685
                                G_CALLBACK (active_server_cnx_broken),
 
686
                                NULL);
 
687
                }
 
688
        } else
 
689
                g_assert (!strcmp (iid, NAMING_CONTEXT_IID) ||
 
690
                          !strcmp(iid, EVENT_SOURCE_IID));
 
691
 
 
692
        servers = g_hash_table_lookup (od->active_server_lists, iid);
 
693
        if (!servers) {
 
694
                servers = g_new0 (ActiveServerList, 1);
 
695
 
 
696
                servers->iid       = g_strdup (iid);
 
697
                servers->n_servers = 1;
 
698
 
 
699
                servers = add_active_server_entry (
 
700
                                servers, environment, object);
 
701
 
 
702
                g_hash_table_insert (
 
703
                        od->active_server_lists, servers->iid, servers);
 
704
        } else {
 
705
                ActiveServerList *new_servers;
 
706
 
 
707
                g_assert (servers->n_servers > 0);
 
708
 
 
709
                servers->n_servers++;
 
710
 
 
711
                new_servers = add_active_server_entry (
 
712
                                        servers, environment, object);
 
713
 
 
714
                if (new_servers != servers) { /* Need to reset the pointer */
 
715
                        g_hash_table_steal (od->active_server_lists, new_servers->iid);
 
716
 
 
717
                        g_hash_table_insert (
 
718
                                od->active_server_lists, new_servers->iid, new_servers);
 
719
                }
 
720
        }
 
721
 
 
722
        if (finished_internal_registration)
 
723
                od->n_active_servers++;
 
724
 
 
725
        if (cnx)
 
726
                check_quit ();
 
727
}
 
728
 
 
729
static void
 
730
active_server_list_free (gpointer data)
 
731
{
 
732
        ActiveServerList *servers = data;
 
733
        int               i;
 
734
 
 
735
        for (i = 0; i < servers->n_servers; i++) {
 
736
                CORBA_Object_release (servers->servers [i].server, NULL);
 
737
                CORBA_free (servers->servers [i].environment._buffer);
 
738
        }
 
739
 
 
740
        g_free (servers);
 
741
}
 
742
 
 
743
static gboolean
 
744
remove_active_server (ObjectDirectory *od,
 
745
                      const char                      *iid,
 
746
                      CORBA_Object                     object)
 
747
{
 
748
        ActiveServerList *servers;
 
749
        gboolean          removed = FALSE;
 
750
        int               i;
 
751
 
 
752
        servers = g_hash_table_lookup (od->active_server_lists, iid);
 
753
        if (!servers)
 
754
                return FALSE;
 
755
 
 
756
        for (i = 0; i < servers->n_servers; i++)
 
757
                if (CORBA_Object_is_equivalent (
 
758
                                servers->servers [i].server, object, NULL)) {
 
759
                        remove_active_server_entry (servers, i);
 
760
                        removed = TRUE;
 
761
                        break;
 
762
                }
 
763
 
 
764
        if (removed)
 
765
                od->n_active_servers--;
 
766
 
 
767
        if (servers->n_servers == 0)
 
768
                g_hash_table_remove (od->active_server_lists, iid);
 
769
 
 
770
        check_quit ();
 
771
 
 
772
        return removed;
 
773
}
 
774
 
 
775
  /* Parse server description and register it, replacing older
 
776
   * definition if necessary.  Returns the regsitered ServerInfo */
 
777
static Bonobo_ServerInfo const *
 
778
od_register_runtime_server_info (ObjectDirectory  *od,
 
779
                                 const char       *iid,
 
780
                                 const CORBA_char *description)
 
781
{
 
782
        Bonobo_ServerInfo *old_serverinfo, *new_serverinfo;
 
783
        GSList *parsed_serverinfo = NULL, *l;
 
784
        int     i;
 
785
 
 
786
        update_registry (od, FALSE);
 
787
 
 
788
        old_serverinfo = (Bonobo_ServerInfo *) g_hash_table_lookup (od->by_iid, iid);
 
789
        if (old_serverinfo)
 
790
                return old_serverinfo;
 
791
        if (!(*description)) /* empty description? */
 
792
                return NULL;
 
793
 
 
794
          /* parse description */
 
795
         bonobo_parse_server_info_memory (description, &parsed_serverinfo,
 
796
                                          bonobo_activation_hostname_get ());
 
797
 
 
798
           /* check for zero entries */
 
799
         if (!parsed_serverinfo)
 
800
                 return NULL;
 
801
           /* check for more than one entry */
 
802
         if (parsed_serverinfo->next) {
 
803
                 g_warning ("More than one <oaf_server> specified, ignoring all");
 
804
                 for (l = parsed_serverinfo; l; l = l->next) {
 
805
                         Bonobo_ServerInfo__freekids (l->data, NULL);
 
806
                         g_free (l->data);
 
807
                 }
 
808
                 g_slist_free (parsed_serverinfo);
 
809
                 return NULL;
 
810
         }
 
811
         new_serverinfo = (Bonobo_ServerInfo *) parsed_serverinfo->data;
 
812
         g_slist_free (parsed_serverinfo);
 
813
 
 
814
         g_ptr_array_add (od->attr_runtime_servers, new_serverinfo);
 
815
         ORBit_sequence_append (od->attr_servers, new_serverinfo);
 
816
           /* rebuild od->by_iid hash table, because
 
817
            * ORBit_sequence_append reallocs _buffer, and that
 
818
            * sometimes changes the addresses of the
 
819
            * serverinfo items */
 
820
         g_hash_table_destroy (od->by_iid);
 
821
         od->by_iid = g_hash_table_new (g_str_hash, g_str_equal);
 
822
         for (i = 0; i < od->attr_servers->_length; ++i)
 
823
                 g_hash_table_insert (od->by_iid,
 
824
                                      od->attr_servers->_buffer[i].iid,
 
825
                                      od->attr_servers->_buffer + i);
 
826
         od->time_list_changed = time (NULL);
 
827
         activation_clients_cache_notify ();
 
828
         return new_serverinfo;
 
829
}
 
830
 
 
831
static Bonobo_RegistrationResult
 
832
impl_Bonobo_ObjectDirectory_register_new_full (
 
833
        PortableServer_Servant              servant,
 
834
        const CORBA_char                   *iid,
 
835
        const Bonobo_ActivationEnvironment *environment,
 
836
        const CORBA_Object                  obj,
 
837
        Bonobo_RegistrationFlags            flags,
 
838
        const CORBA_char                   *description,
 
839
        CORBA_Object                       *existing,
 
840
        Bonobo_ActivationClient             client,
 
841
        CORBA_Environment                  *ev)
 
842
{
 
843
        ObjectDirectory              *od = OBJECT_DIRECTORY (servant);
 
844
        CORBA_Object                  oldobj;
 
845
        Bonobo_ActivationEnvironment  merged_environment;
 
846
        Bonobo_ServerInfo const      *serverinfo;
 
847
 
 
848
        oldobj = od_get_active_server (od, iid, environment);
 
849
        *existing = oldobj;
 
850
 
 
851
        serverinfo = od_register_runtime_server_info (od, iid, description);
 
852
        od_merge_client_environment (od, serverinfo, environment,
 
853
                                     &merged_environment, client);
 
854
 
 
855
        oldobj = od_get_active_server (od, iid, &merged_environment);
 
856
        if (oldobj != CORBA_OBJECT_NIL) {
 
857
                if (!CORBA_Object_non_existent (oldobj, ev)) {
 
858
                        g_free (merged_environment._buffer);
 
859
                        return Bonobo_ACTIVATION_REG_ALREADY_ACTIVE;
 
860
                }
 
861
        }
 
862
 
 
863
        if (!serverinfo) {
 
864
                if (!(flags&Bonobo_REGISTRATION_FLAG_NO_SERVERINFO)) {
 
865
                        g_free (merged_environment._buffer);
 
866
                        return Bonobo_ACTIVATION_REG_NOT_LISTED;
 
867
                }
 
868
        }
 
869
 
 
870
#ifdef BONOBO_ACTIVATION_DEBUG
 
871
        g_warning ("Server register. '%s' : %p", iid, obj);
 
872
#endif
 
873
 
 
874
        add_active_server (od, iid, &merged_environment, obj);
 
875
        g_free (merged_environment._buffer);
 
876
        
 
877
        bonobo_event_source_notify_listeners
 
878
                (od->event_source,
 
879
                 "Bonobo/ObjectDirectory:activation:register",
 
880
                 NULL, ev);
 
881
 
 
882
        return Bonobo_ACTIVATION_REG_SUCCESS;
 
883
}
 
884
 
 
885
static Bonobo_RegistrationResult
 
886
impl_Bonobo_ObjectDirectory_register_new (
 
887
        PortableServer_Servant              servant,
 
888
        const CORBA_char                   *iid,
 
889
        const Bonobo_ActivationEnvironment *environment,
 
890
        const CORBA_Object                  obj,
 
891
        Bonobo_RegistrationFlags            flags,
 
892
        const CORBA_char                   *description,
 
893
        CORBA_Object                       *existing,
 
894
        CORBA_Environment                  *ev)
 
895
{
 
896
        return impl_Bonobo_ObjectDirectory_register_new_full
 
897
                (servant, iid, environment, obj, flags,
 
898
                 description, existing, CORBA_OBJECT_NIL, ev);
 
899
}
 
900
 
 
901
static void
 
902
impl_Bonobo_ObjectDirectory_unregister (
 
903
        PortableServer_Servant  servant,
 
904
        const CORBA_char       *iid,
 
905
        const CORBA_Object      obj,
 
906
        CORBA_Environment      *ev)
 
907
{
 
908
        ObjectDirectory *od = OBJECT_DIRECTORY (servant);
 
909
 
 
910
        if (!remove_active_server (od, iid, obj))
 
911
                CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
 
912
                                     ex_Bonobo_ObjectDirectory_NotRegistered,
 
913
                                     NULL);
 
914
        else 
 
915
                bonobo_event_source_notify_listeners
 
916
                        (od->event_source,
 
917
                         "Bonobo/ObjectDirectory:activation:unregister",
 
918
                         NULL, ev);
 
919
}
 
920
 
 
921
static Bonobo_DynamicPathLoadResult 
 
922
impl_Bonobo_ObjectDirectory_add_path(
 
923
        PortableServer_Servant          servant,
 
924
        const CORBA_char *              add_path,
 
925
        CORBA_Environment               *ev)
 
926
{
 
927
        ObjectDirectory *od = OBJECT_DIRECTORY (servant);
 
928
        int i, j, dir_num, max;
 
929
        char **add_directoies, **ret;
 
930
        GSList *l, *tmp = NULL;
 
931
        gboolean different;
 
932
 
 
933
        if (!od->registry_source_directories) {
 
934
                od->registry_source_directories = split_path_unique (add_path);
 
935
                return Bonobo_DYNAMIC_LOAD_SUCCESS;
 
936
        } else
 
937
                add_directoies = split_path_unique (add_path);
 
938
 
 
939
        if (!add_directoies)
 
940
                return Bonobo_DYNAMIC_LOAD_ERROR;
 
941
 
 
942
        for (max = i = 0; od->registry_source_directories[i]; i++) {
 
943
                tmp = g_slist_append(tmp,g_strdup(od->registry_source_directories[i]));
 
944
                max++;
 
945
        }
 
946
 
 
947
        dir_num = max;
 
948
 
 
949
        for (i = 0; add_directoies[i]; i++) {
 
950
                different = TRUE;
 
951
                for (j = 0; od->registry_source_directories[j]; j++) {
 
952
                        if (!strcmp(add_directoies[i], od->registry_source_directories[j])) {
 
953
                                different = FALSE;
 
954
                                break;
 
955
                        }
 
956
                }       
 
957
                if (different) {
 
958
                        tmp = g_slist_append(tmp, g_strdup(add_directoies[i])); 
 
959
                        max++;
 
960
                }
 
961
        }
 
962
 
 
963
        if (max == dir_num) {
 
964
                g_strfreev(add_directoies);
 
965
                g_slist_free(tmp);
 
966
                return Bonobo_DYNAMIC_LOAD_ALREADY_LISTED;
 
967
        }
 
968
 
 
969
        ret = g_new(char *, max + 1);
 
970
        for (l = tmp, i = 0; l; l = l->next)
 
971
                ret[i++]=l->data;
 
972
 
 
973
        ret[i] = NULL;
 
974
 
 
975
        g_slist_free(tmp);
 
976
        g_strfreev(add_directoies);
 
977
        g_strfreev(od->registry_source_directories);
 
978
 
 
979
        od->registry_source_directories = ret;
 
980
        update_registry(od, TRUE);      
 
981
        return Bonobo_DYNAMIC_LOAD_SUCCESS;
 
982
}
 
983
 
 
984
static Bonobo_DynamicPathLoadResult 
 
985
impl_Bonobo_ObjectDirectory_remove_path(
 
986
        PortableServer_Servant          servant,
 
987
        const CORBA_char *              remove_path,
 
988
        CORBA_Environment               *ev)
 
989
{
 
990
        ObjectDirectory *od = OBJECT_DIRECTORY (servant);
 
991
        char **remove_directoies, **ret;
 
992
        int i, j, max;
 
993
        GSList *l, *tmp = NULL;
 
994
        gboolean different;
 
995
 
 
996
        remove_directoies = split_path_unique (remove_path);
 
997
        if (!remove_directoies)
 
998
                return Bonobo_DYNAMIC_LOAD_ERROR;
 
999
 
 
1000
        for (max = i = 0; od->registry_source_directories[i]; i++) {
 
1001
                different = TRUE;
 
1002
                for (j = 0; remove_directoies[j]; j++) {
 
1003
                        if (!strcmp(od->registry_source_directories[i], remove_directoies[j])) {
 
1004
                                different = FALSE;
 
1005
                                break;
 
1006
                        }
 
1007
                }
 
1008
 
 
1009
                if (different) {
 
1010
                        tmp = g_slist_append(tmp, g_strdup(od->registry_source_directories[i]));
 
1011
                        max++;
 
1012
                }
 
1013
        }
 
1014
 
 
1015
        if (max == i) {
 
1016
                g_slist_free(tmp);
 
1017
                g_strfreev(remove_directoies);
 
1018
                return Bonobo_DYNAMIC_LOAD_NOT_LISTED;
 
1019
        }       
 
1020
        ret = g_new(char *, max + 1);
 
1021
        for (l = tmp, i = 0; l; l = l->next)
 
1022
                ret[i++]=l->data;
 
1023
        ret[i] = NULL;
 
1024
        
 
1025
        g_slist_free(tmp);
 
1026
        g_strfreev(remove_directoies);
 
1027
        g_strfreev(od->registry_source_directories);
 
1028
 
 
1029
        od->registry_source_directories = ret;
 
1030
        update_registry(od, TRUE);
 
1031
        return Bonobo_DYNAMIC_LOAD_SUCCESS;
 
1032
}
 
1033
 
 
1034
 
 
1035
static void
 
1036
client_cnx_broken (ORBitConnection *cnx,
 
1037
                   const Bonobo_ActivationClient  client)
 
1038
{
 
1039
        ObjectDirectory *od = main_dir;
 
1040
        if (!od) /* shutting down */
 
1041
                return;
 
1042
        g_hash_table_remove (od->client_envs, client);
 
1043
}
 
1044
 
 
1045
static void
 
1046
impl_Bonobo_ObjectDirectory_addClientEnv (
 
1047
        PortableServer_Servant         servant,
 
1048
        const Bonobo_ActivationClient  client,
 
1049
        const Bonobo_StringList       *client_env,
 
1050
        CORBA_Environment             *ev)
 
1051
{
 
1052
        Bonobo_ActivationEnvironment *env;
 
1053
        ObjectDirectory *od = OBJECT_DIRECTORY (servant);
 
1054
        int i;
 
1055
        
 
1056
        env = Bonobo_ActivationEnvironment__alloc ();
 
1057
        env->_length  = env->_maximum = client_env->_length;
 
1058
        env->_buffer  = Bonobo_ActivationEnvironment_allocbuf (env->_length);
 
1059
        env->_release = CORBA_TRUE;
 
1060
 
 
1061
        for (i = 0; i < client_env->_length; ++i)
 
1062
        {
 
1063
                const char *keyval = client_env->_buffer[i];
 
1064
                const char *equals = strchr (keyval, '=');
 
1065
                guint       keylen;
 
1066
 
 
1067
                if (!equals) {
 
1068
                        g_warning ("Duff env. var '%s'", keyval);
 
1069
                        continue;
 
1070
                }
 
1071
 
 
1072
                keylen = (guint) (equals - keyval);
 
1073
 
 
1074
                env->_buffer[i].name = CORBA_string_alloc (keylen + 1);
 
1075
                strncpy (env->_buffer[i].name, keyval, keylen);
 
1076
                env->_buffer[i].name[keylen] = 0;
 
1077
                env->_buffer[i].value = CORBA_string_dup (equals + 1);
 
1078
                env->_buffer[i].flags = 0;
 
1079
        }
 
1080
 
 
1081
        g_hash_table_insert (od->client_envs, client, env);
 
1082
 
 
1083
        ORBit_small_listen_for_broken (client, G_CALLBACK (client_cnx_broken),
 
1084
                                       (gpointer) client);
 
1085
}
 
1086
 
 
1087
 
 
1088
Bonobo_ObjectDirectory
 
1089
bonobo_object_directory_get (void)
 
1090
{
 
1091
        if (!main_dir)
 
1092
                return CORBA_OBJECT_NIL;
 
1093
        else
 
1094
                return BONOBO_OBJREF (main_dir);
 
1095
}
 
1096
 
 
1097
Bonobo_EventSource
 
1098
bonobo_object_directory_event_source_get (void)
 
1099
{
 
1100
     if (!main_dir)
 
1101
              return CORBA_OBJECT_NIL;
 
1102
     else
 
1103
              return BONOBO_OBJREF (main_dir->event_source);
 
1104
}
 
1105
 
 
1106
void
 
1107
bonobo_object_directory_init (PortableServer_POA poa,
 
1108
                              const char        *registry_path,
 
1109
                              CORBA_Environment *ev)
 
1110
{
 
1111
        g_assert (main_dir == NULL);
 
1112
 
 
1113
        main_dir = g_object_new (OBJECT_TYPE_DIRECTORY, NULL);
 
1114
 
 
1115
        main_dir->registry_source_directories = split_path_unique (registry_path);
 
1116
        update_registry (main_dir, FALSE);
 
1117
}
 
1118
 
 
1119
void
 
1120
bonobo_object_directory_shutdown (PortableServer_POA poa,
 
1121
                                  CORBA_Environment *ev)
 
1122
{
 
1123
        bonobo_object_set_immortal (BONOBO_OBJECT (main_dir), FALSE);
 
1124
        bonobo_object_unref (BONOBO_OBJECT (main_dir));
 
1125
}
 
1126
 
 
1127
CORBA_Object
 
1128
bonobo_object_directory_re_check_fn (const Bonobo_ActivationEnvironment *environment,
 
1129
                                     const char                         *act_iid,
 
1130
                                     gpointer                            user_data,
 
1131
                                     CORBA_Environment                  *ev)
 
1132
{
 
1133
        CORBA_Object retval;
 
1134
 
 
1135
        retval = od_get_active_server (
 
1136
                main_dir, (Bonobo_ImplementationID) act_iid, environment);
 
1137
 
 
1138
        if (ev->_major != CORBA_NO_EXCEPTION ||
 
1139
            retval == CORBA_OBJECT_NIL) {
 
1140
                char *msg;
 
1141
                Bonobo_GeneralError *errval = Bonobo_GeneralError__alloc ();
 
1142
 
 
1143
                CORBA_exception_free (ev);
 
1144
 
 
1145
                /*
 
1146
                 * If this exception blows ( which it will only do with a multi-object )
 
1147
                 * factory, you need to ensure you register the object you were activated
 
1148
                 * for [use const char *bonobo_activation_iid_get (void); ] is registered
 
1149
                 * with bonobo_activation_active_server_register - _after_ any other
 
1150
                 * servers are registered.
 
1151
                 */
 
1152
                msg = g_strdup_printf (_("Race condition activating server '%s'"), act_iid);
 
1153
                errval->description = CORBA_string_dup (msg);
 
1154
                g_free (msg);
 
1155
 
 
1156
                CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
 
1157
                                     ex_Bonobo_GeneralError, errval);
 
1158
                retval = CORBA_OBJECT_NIL;
 
1159
        }
 
1160
 
 
1161
        return retval;
 
1162
}
 
1163
 
 
1164
void
 
1165
bonobo_object_directory_reload (void)
 
1166
{
 
1167
        g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "reloading our object directory!");
 
1168
 
 
1169
        update_registry (main_dir, TRUE);
 
1170
}
 
1171
 
 
1172
static void 
 
1173
object_directory_finalize (GObject *object)
 
1174
{
 
1175
        ObjectDirectory *od = (ObjectDirectory *) object;
 
1176
 
 
1177
        main_dir = NULL;
 
1178
 
 
1179
        g_hash_table_destroy (od->active_server_lists);
 
1180
        g_hash_table_destroy (od->registry_directory_mtimes);
 
1181
 
 
1182
        g_strfreev (od->registry_source_directories);
 
1183
 
 
1184
        if (od->client_envs) {
 
1185
                g_hash_table_destroy (od->client_envs);
 
1186
                od->client_envs = NULL;
 
1187
        }
 
1188
 
 
1189
        parent_class->finalize (object);
 
1190
}
 
1191
 
 
1192
static void
 
1193
object_directory_class_init (ObjectDirectoryClass *klass)
 
1194
{
 
1195
        GObjectClass *object_class = (GObjectClass *) klass;
 
1196
        POA_Bonobo_ObjectDirectory__epv *epv = &klass->epv;
 
1197
 
 
1198
        parent_class = g_type_class_peek_parent (klass);
 
1199
        object_class->finalize = object_directory_finalize;
 
1200
 
 
1201
        epv->get_servers         = impl_Bonobo_ObjectDirectory__get_servers;
 
1202
        epv->get_active_servers  = impl_Bonobo_ObjectDirectory_get_active_servers;
 
1203
        epv->activate            = impl_Bonobo_ObjectDirectory_activate;
 
1204
        epv->register_new        = impl_Bonobo_ObjectDirectory_register_new;
 
1205
        epv->register_new_full   = impl_Bonobo_ObjectDirectory_register_new_full;
 
1206
        epv->unregister          = impl_Bonobo_ObjectDirectory_unregister;
 
1207
        epv->dynamic_add_path    = impl_Bonobo_ObjectDirectory_add_path;
 
1208
        epv->dynamic_remove_path = impl_Bonobo_ObjectDirectory_remove_path;
 
1209
        epv->addClientEnv        = impl_Bonobo_ObjectDirectory_addClientEnv;
 
1210
}
 
1211
 
 
1212
static void
 
1213
object_directory_init (ObjectDirectory *od)
 
1214
{
 
1215
        bonobo_object_set_immortal (BONOBO_OBJECT (od), TRUE);
 
1216
 
 
1217
        od->by_iid = NULL;
 
1218
 
 
1219
        od->registry_directory_mtimes = g_hash_table_new (g_str_hash, g_str_equal);
 
1220
 
 
1221
        od->active_server_lists =
 
1222
                g_hash_table_new_full (g_str_hash, g_str_equal,
 
1223
                                       g_free, active_server_list_free);
 
1224
        od->no_servers_timeout = 0;
 
1225
 
 
1226
        od->attr_runtime_servers = g_ptr_array_new ();
 
1227
        
 
1228
        od->event_source = bonobo_event_source_new ();
 
1229
        od->client_envs = g_hash_table_new_full
 
1230
                (NULL, NULL, NULL,
 
1231
                 (GDestroyNotify) CORBA_free);
 
1232
}
 
1233
 
 
1234
BONOBO_TYPE_FUNC_FULL (ObjectDirectory,
 
1235
                       Bonobo_ObjectDirectory,
 
1236
                       BONOBO_TYPE_OBJECT,
 
1237
                       object_directory)