source: trunk/third/bonobo-activation/server/object-directory-corba.c @ 18563

Revision 18563, 26.2 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18562, 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 *  oafd: OAF CORBA dameon.
4 *
5 *  Copyright (C) 1999, 2000 Red Hat, Inc.
6 *  Copyrigfht (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
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/*
42 *    We always have the local NamingContext in the
43 * registry at exit, so quit if only 1 left.
44 */
45#define RESIDUAL_SERVERS 1
46
47/*** App-specific servant structures ***/
48
49typedef struct {
50        /* CORBA servant structure */
51        POA_Bonobo_ObjectDirectory servant;
52
53        /* Information on all servers */
54        GHashTable           *by_iid;
55        Bonobo_ServerInfoList attr_servers;
56        Bonobo_CacheTime      time_list_changed;
57
58        /* CORBA Object tracking */
59        GHashTable      *active_server_lists;
60        guint            n_active_servers;
61        guint            no_servers_timeout;
62        Bonobo_CacheTime time_active_changed;
63
64        /* Source polling bits */
65        char           **registry_source_directories;
66        time_t           time_did_stat;
67        GHashTable      *registry_directory_mtimes;
68
69        CORBA_Object self;
70} impl_POA_Bonobo_ObjectDirectory;
71
72typedef struct {
73        char *iid;
74        int   n_servers;
75        struct {
76                Bonobo_ActivationEnvironment environment;
77                CORBA_Object                 server;
78        } servers [1]; /* flexible array */
79} ActiveServerList;
80
81/*
82 * DON'T FIXME: this smells, here we vandalise the oh so
83 * complicated design and enforce the invariant that there
84 * can only ever be one ObjectDirectory in-proc.
85 */
86static impl_POA_Bonobo_ObjectDirectory *main_dir = NULL;
87
88#ifdef BONOBO_ACTIVATION_DEBUG
89static void
90od_dump_list (impl_POA_Bonobo_ObjectDirectory * od)
91{
92#if 0
93        int i, j, k;
94
95        for (i = 0; i < od->attr_servers._length; i++) {
96                g_print ("IID %s, type %s, location %s\n",
97                         od->attr_servers._buffer[i].iid,
98                         od->attr_servers._buffer[i].server_type,
99                         od->attr_servers._buffer[i].location_info);
100                for (j = 0; j < od->attr_servers._buffer[i].props._length;
101                     j++) {
102                        Bonobo_ActivationProperty *prop =
103                                &(od->attr_servers._buffer[i].
104                                  props._buffer[j]);
105                        if (strchr (prop->name, '-') != NULL) /* Translated, likely to
106                                                         be annoying garbage value */
107                                continue;
108
109                        g_print ("    %s = ", prop->name);
110                        switch (prop->v._d) {
111                        case Bonobo_ACTIVATION_P_STRING:
112                                g_print ("\"%s\"\n", prop->v._u.value_string);
113                                break;
114                        case Bonobo_ACTIVATION_P_NUMBER:
115                                g_print ("%f\n", prop->v._u.value_number);
116                                break;
117                        case Bonobo_ACTIVATION_P_BOOLEAN:
118                                g_print ("%s\n",
119                                         prop->v.
120                                         _u.value_boolean ? "TRUE" : "FALSE");
121                                break;
122                        case Bonobo_ACTIVATION_P_STRINGV:
123                                g_print ("[");
124                                for (k = 0;
125                                     k < prop->v._u.value_stringv._length;
126                                     k++) {
127                                        g_print ("\"%s\"",
128                                                 prop->v._u.
129                                                 value_stringv._buffer[k]);
130                                        if (k <
131                                            (prop->v._u.
132                                             value_stringv._length - 1))
133                                                g_print (", ");
134                                }
135                                g_print ("]\n");
136                                break;
137                        }
138                }
139        }
140#endif
141}
142#endif
143
144static gboolean
145registry_directory_needs_update (impl_POA_Bonobo_ObjectDirectory *servant,
146                                 const char                      *directory)
147{
148        gboolean needs_update;
149        struct stat statbuf;
150        time_t old_mtime;
151
152        if (stat (directory, &statbuf) != 0) {
153                return FALSE;
154        }
155 
156        old_mtime = (time_t) g_hash_table_lookup (
157                servant->registry_directory_mtimes, directory);
158
159        g_hash_table_insert (servant->registry_directory_mtimes,
160                             (gpointer) directory,
161                             (gpointer) statbuf.st_mtime);
162
163        needs_update = (old_mtime != statbuf.st_mtime);
164
165#ifdef BONOBO_ACTIVATION_DEBUG
166        if (needs_update)
167                g_warning ("Compare old_mtime on '%s' with %ld ==? %ld",
168                           directory,
169                           (long) old_mtime, (long) statbuf.st_mtime);
170#endif
171
172        return needs_update;
173}
174
175static void
176update_registry (impl_POA_Bonobo_ObjectDirectory *servant, gboolean force_reload)
177{
178        int i;
179        time_t cur_time;
180        gboolean must_load;
181        static gboolean doing_reload = FALSE;
182
183        if (doing_reload)
184                return;
185        doing_reload = TRUE;
186
187#ifdef BONOBO_ACTIVATION_DEBUG
188        g_warning ("Update registry %p", servant->by_iid);
189#endif
190
191        /* get first time init right */
192        must_load = (servant->by_iid == NULL);
193       
194        cur_time = time (NULL);
195
196        if (cur_time - 5 > servant->time_did_stat) {
197                servant->time_did_stat = cur_time;
198               
199                for (i = 0; servant->registry_source_directories[i] != NULL; i++) {
200                        if (registry_directory_needs_update
201                            (servant, servant->registry_source_directories[i]))
202                                must_load = TRUE;
203                }
204        }
205       
206        if (must_load || force_reload) {
207                /*
208                 * FIXME bugzilla.eazel.com 2727: we should only reload those
209                 * directories that have actually changed instead of reloading
210                 * all when any has changed.
211                 */
212#ifdef BONOBO_ACTIVATION_DEBUG
213                g_warning ("Re-load %d %d", must_load, force_reload);
214#endif
215                bonobo_server_info_load (servant->registry_source_directories,
216                                         &servant->attr_servers,
217                                         &servant->by_iid,
218                                         bonobo_activation_hostname_get ());
219                servant->time_did_stat = servant->time_list_changed = time (NULL);
220
221#ifdef BONOBO_ACTIVATION_DEBUG
222                od_dump_list (servant);
223#endif
224                if (must_load)
225                        activation_clients_cache_notify ();
226        }
227
228        doing_reload = FALSE;
229}
230
231static gchar **
232split_path_unique (const char *colon_delimited_path)
233{
234        int i, max;
235        gboolean different;
236        gchar **ret, **wrk;
237        GSList *l, *tmp = NULL;
238
239        g_return_val_if_fail (colon_delimited_path != NULL, NULL);
240
241        wrk = g_strsplit (colon_delimited_path, ":", -1);
242
243        g_return_val_if_fail (wrk != NULL, NULL);
244
245        for (max = i = 0; wrk [i]; i++) {
246                different = TRUE;
247                for (l = tmp; l; l = l->next) {
248                        if (!strcmp (l->data, wrk [i])) {
249                                different = FALSE;
250                        } else if (wrk [i] == '\0') {
251                                different = FALSE;
252                        }
253                }
254                if (different) {
255                        tmp = g_slist_prepend (tmp, g_strdup (wrk [i]));
256                        max++;
257                }
258        }
259
260        tmp = g_slist_reverse (tmp);
261
262        ret = g_new (char *, max + 1);
263
264        for (l = tmp, i = 0; l; l = l->next)
265                ret [i++] = l->data;
266
267        ret [i] = NULL;
268
269        g_slist_free (tmp);
270        g_strfreev (wrk);
271
272        return ret;
273}
274
275static Bonobo_ServerInfoListCache *
276impl_Bonobo_ObjectDirectory__get_servers (
277        PortableServer_Servant           _servant,
278        Bonobo_CacheTime                 only_if_newer,
279        CORBA_Environment               *ev)
280{
281        impl_POA_Bonobo_ObjectDirectory *servant = _servant;
282        Bonobo_ServerInfoListCache      *retval;
283
284        update_registry (servant, FALSE);
285
286        retval = Bonobo_ServerInfoListCache__alloc ();
287
288        retval->_d = (only_if_newer < servant->time_list_changed);
289        if (retval->_d) {
290                retval->_u.server_list = servant->attr_servers;
291                CORBA_sequence_set_release (&retval->_u.server_list,
292                                            CORBA_FALSE);
293        }
294
295        return retval;
296}
297
298typedef struct {
299        Bonobo_ImplementationID *seq;
300        int                      last_used;
301} StateCollectionInfo;
302
303static void
304collate_active_server (char *key, gpointer value, StateCollectionInfo *sci)
305{
306        sci->seq [(sci->last_used)++] = CORBA_string_dup (key);
307}
308
309static Bonobo_ServerStateCache *
310impl_Bonobo_ObjectDirectory_get_active_servers (
311        PortableServer_Servant           _servant,
312        Bonobo_CacheTime                 only_if_newer,
313        CORBA_Environment               *ev)
314{
315        impl_POA_Bonobo_ObjectDirectory *servant = _servant;
316        Bonobo_ServerStateCache         *retval;
317
318        retval = Bonobo_ServerStateCache__alloc ();
319
320        retval->_d = (only_if_newer < servant->time_active_changed);
321        if (retval->_d) {
322                StateCollectionInfo sci;
323
324                retval->_u.active_servers._length =
325                        g_hash_table_size (servant->active_server_lists);
326                retval->_u.active_servers._buffer = sci.seq =
327                        CORBA_sequence_Bonobo_ImplementationID_allocbuf
328                        (retval->_u.active_servers._length);
329                sci.last_used = 0;
330
331                g_hash_table_foreach (servant->active_server_lists,
332                                      (GHFunc) collate_active_server, &sci);
333                CORBA_sequence_set_release (&(retval->_u.active_servers),
334                                            CORBA_TRUE);
335        }
336
337        return retval;
338}
339
340static CORBA_Object
341od_get_active_server (impl_POA_Bonobo_ObjectDirectory    *servant,
342                      const char                         *iid,
343                      const Bonobo_ActivationEnvironment *environment)
344{
345        ActiveServerList *servers;
346        CORBA_Object      retval;
347        int               i;
348
349        servers = g_hash_table_lookup (servant->active_server_lists, iid);
350        if (!servers)
351                return CORBA_OBJECT_NIL;
352
353        retval = CORBA_OBJECT_NIL;
354
355        for (i = 0; i < servers->n_servers; i++)
356                if (Bonobo_ActivationEnvironment_match (
357                                &servers->servers [i].environment,
358                                environment)) {
359                        retval = servers->servers [i].server;
360                }
361
362        if (retval != CORBA_OBJECT_NIL &&
363            !CORBA_Object_non_existent (retval, NULL))
364                return CORBA_Object_duplicate (retval, NULL);
365
366        return CORBA_OBJECT_NIL;
367}
368
369static CORBA_Object
370impl_Bonobo_ObjectDirectory_activate (
371        PortableServer_Servant              _servant,
372        const CORBA_char                   *iid,
373        const Bonobo_ActivationContext      ac,
374        const Bonobo_ActivationEnvironment *environment,
375        const Bonobo_ActivationFlags        flags,
376        CORBA_Context                       ctx,
377        CORBA_Environment                  *ev)
378{
379        impl_POA_Bonobo_ObjectDirectory *servant = _servant;
380        CORBA_Object                     retval;
381        Bonobo_ServerInfo               *si;
382        ODActivationInfo                 ai;
383#ifdef BONOBO_ACTIVATION_DEBUG
384        static int                       depth = 0;
385#endif
386
387        retval = CORBA_OBJECT_NIL;
388
389        update_registry (servant, FALSE);
390
391        if (!(flags & Bonobo_ACTIVATION_FLAG_PRIVATE)) {
392                retval = od_get_active_server (servant, iid, environment);
393
394                if (retval != CORBA_OBJECT_NIL)
395                        return retval;
396        }
397
398        if (flags & Bonobo_ACTIVATION_FLAG_EXISTING_ONLY) {
399                return CORBA_OBJECT_NIL;
400        }
401
402#ifdef BONOBO_ACTIVATION_DEBUG
403        {
404                int i;
405                depth++;
406                for (i = 0; i < depth; i++)
407                        fputc (' ', stderr);
408                fprintf (stderr, "Activate '%s'\n", iid);
409        }
410#endif
411
412        ai.ac = ac;
413        ai.flags = flags;
414        ai.ctx = ctx;
415
416        si = g_hash_table_lookup (servant->by_iid, iid);
417
418        if (si) {
419                retval = od_server_activate (
420                                si, &ai, servant->self, environment, ev);
421
422                /* If we failed to activate - it may be because our
423                 * request re-entered _during_ the activation
424                 * process resulting in a second process being started
425                 * but failing to register - so we'll look up again here
426                 * to see if we can get it.
427                 * FIXME: we should not be forking redundant processes
428                 * while an activation of that same process is on the
429                 * stack.
430                 * FIXME: we only get away with this hack because we
431                 * try and fork another process & thus allow the reply
432                 * from the initial process to be handled in the event
433                 * loop.
434                 */
435                /* FIXME: this path is theoretically redundant now */
436                if (ev->_major != CORBA_NO_EXCEPTION ||
437                    retval == CORBA_OBJECT_NIL) {
438                        retval = od_get_active_server (servant, iid, environment);
439
440                        if (retval != CORBA_OBJECT_NIL)
441                                CORBA_exception_free (ev);
442                }
443        }
444
445#ifdef BONOBO_ACTIVATION_DEBUG
446        {
447                int i;
448                for (i = 0; i < depth; i++)
449                        fputc (' ', stderr);
450                fprintf (stderr, "Activated '%s' = %p\n", iid, retval);
451                depth--;
452        }
453#endif
454
455        return retval;
456}
457
458extern GMainLoop *main_loop;
459
460static gboolean
461quit_server_timeout (gpointer user_data)
462{
463#ifdef BONOBO_ACTIVATION_DEBUG
464        g_warning ("Quit server !");
465#endif
466
467        if (!main_dir ||
468            main_dir->n_active_servers > RESIDUAL_SERVERS ||
469            !activation_clients_is_empty_scan ())
470                g_warning ("Serious error handling server count, not quitting");
471        else
472                g_main_loop_quit (main_loop);
473
474        main_dir->no_servers_timeout = 0;
475
476        return FALSE;
477}
478
479void
480check_quit (void)
481{
482        impl_POA_Bonobo_ObjectDirectory *servant = main_dir;
483
484        /* We had some activity - so push out the shutdown timeout */
485        if (servant->no_servers_timeout != 0)
486                g_source_remove (servant->no_servers_timeout);
487        servant->no_servers_timeout = 0;
488
489        if (servant->n_active_servers <= RESIDUAL_SERVERS &&
490            activation_clients_is_empty_scan ())
491                servant->no_servers_timeout = g_timeout_add (
492                        SERVER_IDLE_QUIT_TIMEOUT, quit_server_timeout, NULL);
493
494        servant->time_active_changed = time (NULL);
495}
496
497static void
498remove_active_server_entry (ActiveServerList *servers,
499                            int               index)
500{
501        CORBA_Object_release (servers->servers [index].server, NULL);
502        CORBA_free (servers->servers [index].environment._buffer);
503
504        if (index != servers->n_servers - 1)
505                memcpy (servers->servers [index].server,
506                        servers->servers [servers->n_servers - 1].server,
507                        sizeof (servers->servers [index].server));
508
509        servers->n_servers--;
510}
511
512static ActiveServerList *
513add_active_server_entry (ActiveServerList                   *servers,
514                         const Bonobo_ActivationEnvironment *environment,
515                         CORBA_Object                        object)
516{
517        int index, i;
518
519        index = servers->n_servers - 1;
520
521        if (index != 0)
522                servers = g_realloc (servers,
523                                     sizeof (*servers) + sizeof (servers->servers [0]) * index);
524
525        servers->servers [index].server = CORBA_Object_duplicate (object, NULL);
526
527        servers->servers [index].environment._length  = environment->_length;
528        servers->servers [index].environment._maximum = environment->_maximum;
529        servers->servers [index].environment._buffer  =
530                                Bonobo_ActivationEnvironment_allocbuf (environment->_length);
531        servers->servers [index].environment._release = TRUE;
532
533        for (i = 0; i < environment->_length; i++)
534                Bonobo_ActivationEnvValue_copy (
535                        &servers->servers [index].environment._buffer [i],
536                        &environment->_buffer [i]);
537
538        return servers;
539}
540
541static gboolean
542prune_dead_servers (gpointer key,
543                    gpointer value,
544                    gpointer user_data)
545{
546        impl_POA_Bonobo_ObjectDirectory *servant = user_data;
547        ActiveServerList                *servers = value;
548        int                              i;
549
550        for (i = 0; i < servers->n_servers; i++) {
551                ORBitConnectionStatus  status;
552                gboolean               dead;
553
554                status = ORBit_small_get_connection_status (
555                                        servers->servers [i].server);
556
557                dead = (status == ORBIT_CONNECTION_DISCONNECTED);
558
559#ifdef BONOBO_ACTIVATION_DEBUG
560                fprintf (stderr, "IID '%20s' (%p), %s \n",
561                         (char *) key, servers->servers [i].server,
562                         dead ? "dead" : "alive");
563#endif
564                if (dead) {
565                        remove_active_server_entry (servers, i);
566
567                        servant->n_active_servers--;
568                        i--;
569                }
570        }
571       
572        return !servers->n_servers;
573}
574
575static void
576active_server_cnx_broken (ORBitConnection *cnx,
577                          gpointer         dummy)
578
579{
580        impl_POA_Bonobo_ObjectDirectory *servant = main_dir;
581
582        if (!servant) /* shutting down */
583                return;
584
585        g_hash_table_foreach_remove (servant->active_server_lists,
586                                     prune_dead_servers, servant);
587#ifdef BONOBO_ACTIVATION_DEBUG
588        g_warning ("After prune: %d live servers",
589                   servant->n_active_servers - RESIDUAL_SERVERS);
590#endif
591
592        check_quit ();
593}
594
595static void
596add_active_server (impl_POA_Bonobo_ObjectDirectory    *servant,
597                   const char                         *iid,
598                   const Bonobo_ActivationEnvironment *environment,
599                   CORBA_Object                       object)
600{
601        ActiveServerList *servers;
602        ORBitConnection  *cnx;
603
604        cnx = ORBit_small_get_connection (object);
605        if (cnx) {
606                if (!g_object_get_data (G_OBJECT (cnx), "object_count")) {
607                        g_object_set_data (
608                                G_OBJECT (cnx), "object_count", GUINT_TO_POINTER (1));
609                       
610                        g_signal_connect (
611                                cnx, "broken",
612                                G_CALLBACK (active_server_cnx_broken),
613                                NULL);
614                }
615        } else
616                g_assert (!strcmp (iid, NAMING_CONTEXT_IID));
617
618        servers = g_hash_table_lookup (servant->active_server_lists, iid);
619        if (!servers) {
620                servers = g_new0 (ActiveServerList, 1);
621
622                servers->iid       = g_strdup (iid);
623                servers->n_servers = 1;
624
625                servers = add_active_server_entry (
626                                servers, environment, object);
627
628                g_hash_table_insert (
629                        servant->active_server_lists, servers->iid, servers);
630        } else {
631                ActiveServerList *new_servers;
632
633                g_assert (servers->n_servers > 0);
634
635                servers->n_servers++;
636
637                new_servers = add_active_server_entry (
638                                        servers, environment, object);
639
640                if (new_servers != servers) { /* Need to reset the pointer */
641                        g_hash_table_steal (servant->active_server_lists, servers->iid);
642
643                        g_hash_table_insert (
644                                servant->active_server_lists, servers->iid, new_servers);
645                }
646        }
647
648        servant->n_active_servers++;
649
650        if (cnx)
651                check_quit ();
652}
653
654static void
655active_server_list_free (gpointer data)
656{
657        ActiveServerList *servers = data;
658        int               i;
659
660        for (i = 0; i < servers->n_servers; i++) {
661                CORBA_Object_release (servers->servers [i].server, NULL);
662                CORBA_free (servers->servers [i].environment._buffer);
663        }
664
665        g_free (servers);
666}
667
668static gboolean
669remove_active_server (impl_POA_Bonobo_ObjectDirectory *servant,
670                      const char                      *iid,
671                      CORBA_Object                     object)
672{
673        ActiveServerList *servers;
674        gboolean          removed = FALSE;
675        int               i;
676
677        servers = g_hash_table_lookup (servant->active_server_lists, iid);
678        g_return_val_if_fail (servers != NULL, FALSE);
679
680        for (i = 0; i < servers->n_servers; i++)
681                /* ORBit2 ensures reference uniqueness */
682                if (CORBA_Object_is_equivalent (
683                                servers->servers [i].server, object, NULL)) {
684                        remove_active_server_entry (servers, i);
685                        removed = TRUE;
686                        break;
687                }
688
689        servant->n_active_servers--;
690
691        if (servers->n_servers == 0)
692                g_hash_table_remove (servant->active_server_lists, iid);
693
694        check_quit ();
695
696        return removed;
697}
698
699static Bonobo_RegistrationResult
700impl_Bonobo_ObjectDirectory_register_new (
701        PortableServer_Servant              _servant,
702        const CORBA_char                   *iid,
703        const Bonobo_ActivationEnvironment *environment,
704        const CORBA_Object                  obj,
705        CORBA_Environment                  *ev)
706{
707        impl_POA_Bonobo_ObjectDirectory *servant = _servant;
708        CORBA_Object                     oldobj;
709
710        oldobj = od_get_active_server (servant, iid, environment);
711
712        if (oldobj != CORBA_OBJECT_NIL) {
713                CORBA_Object_release (oldobj, NULL);
714                if (!CORBA_Object_non_existent (oldobj, ev))
715                        return Bonobo_ACTIVATION_REG_ALREADY_ACTIVE;
716        }
717
718        if (!g_hash_table_lookup (servant->by_iid, iid))
719                return Bonobo_ACTIVATION_REG_NOT_LISTED;
720
721#ifdef BONOBO_ACTIVATION_DEBUG
722        g_warning ("Server register. '%s' : %p", iid, obj);
723#endif
724
725        add_active_server (servant, iid, environment, obj);
726
727        return Bonobo_ACTIVATION_REG_SUCCESS;
728}
729
730static void
731impl_Bonobo_ObjectDirectory_unregister (
732        PortableServer_Servant  _servant,
733        const CORBA_char       *iid,
734        const CORBA_Object      obj,
735        CORBA_Environment      *ev)
736{
737        if (!remove_active_server (_servant, iid, obj))
738                CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
739                                     ex_Bonobo_ObjectDirectory_NotRegistered,
740                                     NULL);
741}
742
743static CORBA_char *
744impl_Bonobo_ObjectDirectory__get_hostID (
745        PortableServer_Servant           _servant,
746        CORBA_Environment               *ev)
747{
748        return CORBA_string_dup (bonobo_activation_hostname_get ());
749}
750
751static CORBA_char *
752impl_Bonobo_ObjectDirectory__get_username (
753        PortableServer_Servant           _servant,
754        CORBA_Environment               *ev)
755{
756        return CORBA_string_dup (g_get_user_name ());
757}
758
759/*** epv structures ***/
760
761static PortableServer_ServantBase__epv impl_Bonobo_ObjectDirectory_base_epv = {
762        NULL,                   /* _private data */
763        NULL,                   /* finalize routine */
764        NULL                    /* default_POA routine */
765};
766
767/* FIXME: fill me in / deal with me globaly */
768static POA_Bonobo_Unknown__epv impl_Bonobo_Unknown_epv = {
769        NULL,                   /* _private data */
770        NULL,
771        NULL,
772        NULL
773};
774
775static POA_Bonobo_ObjectDirectory__epv impl_Bonobo_ObjectDirectory_epv = {
776        NULL,                   /* _private */
777        impl_Bonobo_ObjectDirectory__get_servers,
778        impl_Bonobo_ObjectDirectory_get_active_servers,
779        impl_Bonobo_ObjectDirectory__get_username,
780        impl_Bonobo_ObjectDirectory__get_hostID,
781        impl_Bonobo_ObjectDirectory_activate,
782        impl_Bonobo_ObjectDirectory_register_new,
783        impl_Bonobo_ObjectDirectory_unregister
784};
785
786/*** vepv structures ***/
787
788static POA_Bonobo_ObjectDirectory__vepv impl_Bonobo_ObjectDirectory_vepv = {
789        &impl_Bonobo_ObjectDirectory_base_epv,
790        &impl_Bonobo_Unknown_epv,
791        &impl_Bonobo_ObjectDirectory_epv
792};
793
794Bonobo_ObjectDirectory
795bonobo_object_directory_get (void)
796{
797        if (!main_dir)
798                return CORBA_OBJECT_NIL;
799        else
800                return main_dir->self;
801}
802
803void
804bonobo_object_directory_init (PortableServer_POA poa,
805                              const char        *registry_path,
806                              CORBA_Environment *ev)
807{
808        PortableServer_ObjectId         *objid;
809        impl_POA_Bonobo_ObjectDirectory *servant;
810
811        g_assert (main_dir == NULL);
812
813        servant = g_new0 (impl_POA_Bonobo_ObjectDirectory, 1);
814
815        main_dir = servant; /* DON'T FIXME: this is good. */
816
817        servant->servant.vepv = &impl_Bonobo_ObjectDirectory_vepv;
818        POA_Bonobo_ObjectDirectory__init ((PortableServer_Servant) servant,
819                                       ev);
820        objid = PortableServer_POA_activate_object (poa, servant, ev);
821        CORBA_free (objid);
822        servant->self =
823                PortableServer_POA_servant_to_reference (poa, servant, ev);
824
825        servant->by_iid = NULL;
826
827        servant->registry_source_directories = split_path_unique (registry_path);
828        servant->registry_directory_mtimes = g_hash_table_new (g_str_hash, g_str_equal);
829
830        update_registry (servant, FALSE);
831
832        servant->active_server_lists =
833                g_hash_table_new_full (g_str_hash, g_str_equal,
834                                       g_free, active_server_list_free);
835        servant->no_servers_timeout = 0;
836}
837
838void
839bonobo_object_directory_shutdown (PortableServer_POA poa,
840                                  CORBA_Environment *ev)
841{
842        PortableServer_ObjectId *oid;
843        impl_POA_Bonobo_ObjectDirectory *servant = main_dir;
844
845        oid = PortableServer_POA_servant_to_id (poa, servant, ev);
846        PortableServer_POA_deactivate_object (poa, oid, ev);
847        CORBA_free (oid);
848
849        main_dir = NULL;
850
851        CORBA_Object_release (servant->self, ev);
852        g_hash_table_destroy (servant->active_server_lists);
853        servant->active_server_lists = NULL;
854        g_hash_table_destroy (servant->registry_directory_mtimes);
855        servant->registry_directory_mtimes = NULL;
856        g_strfreev (servant->registry_source_directories);
857
858        g_free (servant);
859}
860
861CORBA_Object
862bonobo_object_directory_re_check_fn (const Bonobo_ActivationEnvironment *environment,
863                                     const char                         *act_iid,
864                                     gpointer                            user_data,
865                                     CORBA_Environment                  *ev)
866{
867        CORBA_Object retval;
868
869        retval = od_get_active_server (
870                main_dir, (Bonobo_ImplementationID) act_iid, environment);
871
872        if (ev->_major != CORBA_NO_EXCEPTION ||
873            retval == CORBA_OBJECT_NIL) {
874                char *msg;
875                Bonobo_GeneralError *errval = Bonobo_GeneralError__alloc ();
876
877                CORBA_exception_free (ev);
878
879                /*
880                 * If this exception blows ( which it will only do with a multi-object )
881                 * factory, you need to ensure you register the object you were activated
882                 * for [use const char *bonobo_activation_iid_get (void); ] is registered
883                 * with bonobo_activation_active_server_register - _after_ any other
884                 * servers are registered.
885                 */
886                msg = g_strdup_printf (_("Race condition activating server '%s'"), act_iid);
887                errval->description = CORBA_string_dup (msg);
888                g_free (msg);
889
890                CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
891                                     ex_Bonobo_GeneralError, errval);
892                retval = CORBA_OBJECT_NIL;
893        }
894
895        return retval;
896}
897
898void
899bonobo_object_directory_reload (void)
900{
901#ifdef BONOBO_ACTIVATION_DEBUG
902        g_print ("reloading our object directory!\n");
903#endif
904        update_registry (main_dir, TRUE);
905}
Note: See TracBrowser for help on using the repository browser.