1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
3
* oafd: OAF CORBA dameon.
5
* Copyright (C) 1999, 2000 Red Hat, Inc.
6
* Copyright (C) 1999, 2000 Eazel, Inc.
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.
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.
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.
22
* Authors: Elliot Lee <sopwith@redhat.com>,
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"
42
#define RESIDUAL_SERVERS 0
44
static GObjectClass *parent_class = NULL;
45
static gboolean finished_internal_registration = FALSE;
51
Bonobo_ActivationEnvironment environment;
53
} servers [1]; /* flexible array */
56
static ObjectDirectory *main_dir = NULL;
58
#ifdef BONOBO_ACTIVATION_DEBUG
60
od_dump_list (ObjectDirectory * od)
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;
72
Bonobo_ActivationProperty *prop =
73
&(od->attr_servers->_buffer[i].
75
if (strchr (prop->name, '-') != NULL) /* Translated, likely to
76
be annoying garbage value */
79
g_print (" %s = ", prop->name);
81
case Bonobo_ACTIVATION_P_STRING:
82
g_print ("\"%s\"\n", prop->v._u.value_string);
84
case Bonobo_ACTIVATION_P_NUMBER:
85
g_print ("%f\n", prop->v._u.value_number);
87
case Bonobo_ACTIVATION_P_BOOLEAN:
90
_u.value_boolean ? "TRUE" : "FALSE");
92
case Bonobo_ACTIVATION_P_STRINGV:
95
k < prop->v._u.value_stringv._length;
99
value_stringv._buffer[k]);
102
value_stringv._length - 1))
115
registry_directory_needs_update (ObjectDirectory *od,
116
const char *directory)
118
gboolean needs_update;
122
if (stat (directory, &statbuf) != 0) {
126
old_mtime = (time_t) g_hash_table_lookup (
127
od->registry_directory_mtimes, directory);
129
g_hash_table_insert (od->registry_directory_mtimes,
130
(gpointer) directory,
131
(gpointer) statbuf.st_mtime);
133
needs_update = (old_mtime != statbuf.st_mtime);
135
#ifdef BONOBO_ACTIVATION_DEBUG
137
g_warning ("Compare old_mtime on '%s' with %ld ==? %ld",
139
(long) old_mtime, (long) statbuf.st_mtime);
146
update_registry (ObjectDirectory *od, gboolean force_reload)
151
static gboolean doing_reload = FALSE;
157
#ifdef BONOBO_ACTIVATION_DEBUG
158
g_warning ("Update registry %p", od->by_iid);
161
/* get first time init right */
162
must_load = (od->by_iid == NULL);
164
cur_time = time (NULL);
166
if (cur_time - 5 > od->time_did_stat) {
167
od->time_did_stat = cur_time;
169
for (i = 0; od->registry_source_directories[i] != NULL; i++) {
170
if (registry_directory_needs_update
171
(od, od->registry_source_directories[i]))
176
if (must_load || force_reload) {
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.
182
#ifdef BONOBO_ACTIVATION_DEBUG
183
g_warning ("Re-load %d %d", must_load, force_reload);
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,
190
od->attr_runtime_servers,
192
bonobo_activation_hostname_get ());
193
od->time_did_stat = od->time_list_changed = time (NULL);
195
#ifdef BONOBO_ACTIVATION_DEBUG
199
activation_clients_cache_notify ();
202
doing_reload = FALSE;
206
split_path_unique (const char *colon_delimited_path)
211
GSList *l, *tmp = NULL;
213
g_return_val_if_fail (colon_delimited_path != NULL, NULL);
215
wrk = g_strsplit (colon_delimited_path, ":", -1);
217
g_return_val_if_fail (wrk != NULL, NULL);
219
for (max = i = 0; wrk [i]; i++) {
221
for (l = tmp; l; l = l->next) {
222
if (!strcmp (l->data, wrk [i])) {
224
} else if (wrk [i] == '\0') {
229
tmp = g_slist_prepend (tmp, g_strdup (wrk [i]));
234
tmp = g_slist_reverse (tmp);
236
ret = g_new (char *, max + 1);
238
for (l = tmp, i = 0; l; l = l->next)
249
static Bonobo_ServerInfoListCache *
250
impl_Bonobo_ObjectDirectory__get_servers (
251
PortableServer_Servant servant,
252
Bonobo_CacheTime only_if_newer,
253
CORBA_Environment *ev)
255
ObjectDirectory *od = OBJECT_DIRECTORY (servant);
256
Bonobo_ServerInfoListCache *retval;
258
update_registry (od, FALSE);
260
retval = Bonobo_ServerInfoListCache__alloc ();
262
retval->_d = (only_if_newer < od->time_list_changed);
264
retval->_u.server_list = *od->attr_servers;
265
CORBA_sequence_set_release (&retval->_u.server_list,
273
Bonobo_ImplementationID *seq;
275
} StateCollectionInfo;
278
collate_active_server (char *key, gpointer value, StateCollectionInfo *sci)
280
sci->seq [(sci->last_used)++] = CORBA_string_dup (key);
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)
289
ObjectDirectory *od = OBJECT_DIRECTORY (servant);
290
Bonobo_ServerStateCache *retval;
292
retval = Bonobo_ServerStateCache__alloc ();
294
retval->_d = (only_if_newer < od->time_active_changed);
296
StateCollectionInfo sci;
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);
305
g_hash_table_foreach (od->active_server_lists,
306
(GHFunc) collate_active_server, &sci);
307
CORBA_sequence_set_release (&(retval->_u.active_servers),
315
od_get_active_server (ObjectDirectory *od,
317
const Bonobo_ActivationEnvironment *environment)
319
ActiveServerList *servers;
323
servers = g_hash_table_lookup (od->active_server_lists, iid);
325
return CORBA_OBJECT_NIL;
327
retval = CORBA_OBJECT_NIL;
329
for (i = 0; i < servers->n_servers; i++) {
330
if (Bonobo_ActivationEnvironment_match (
331
&servers->servers [i].environment,
333
retval = servers->servers [i].server;
337
if (retval != CORBA_OBJECT_NIL &&
338
!CORBA_Object_non_existent (retval, NULL))
339
return CORBA_Object_duplicate (retval, NULL);
341
return CORBA_OBJECT_NIL;
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
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)
359
int i, serverinfo_env_idx;
360
const Bonobo_ActivationEnvironment *client_env;
361
const Bonobo_StringList *serverinfo_env = NULL;
363
array = g_array_new (FALSE, FALSE, sizeof (Bonobo_ActivationEnvValue));
365
/* copy all values from @environment */
366
for (i = 0; i < environment->_length; ++i)
367
g_array_append_val (array, environment->_buffer[i]);
369
if (client == CORBA_OBJECT_NIL)
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)
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;
382
g_warning ("bonobo:environment should have type stringv");
389
/* do the actual merging */
390
client_env = (const Bonobo_ActivationEnvironment *)
391
g_hash_table_lookup (od->client_envs, client);
396
for (serverinfo_env_idx = 0;
397
serverinfo_env_idx < serverinfo_env->_length; ++serverinfo_env_idx)
399
CORBA_char *env = serverinfo_env->_buffer[serverinfo_env_idx];
400
gboolean duplicated_env = FALSE;
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;
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]);
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);
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,
437
CORBA_Environment *ev)
439
ObjectDirectory *od = OBJECT_DIRECTORY (servant);
441
Bonobo_ServerInfo *si;
443
#ifdef BONOBO_ACTIVATION_DEBUG
444
static int depth = 0;
446
Bonobo_ActivationEnvironment merged_environment;
448
od_merge_client_environment (od, (Bonobo_ServerInfo *)
449
g_hash_table_lookup (od->by_iid, iid),
450
environment, &merged_environment, client);
452
retval = CORBA_OBJECT_NIL;
454
update_registry (od, FALSE);
456
if (!(flags & Bonobo_ACTIVATION_FLAG_PRIVATE)) {
457
retval = od_get_active_server (od, iid, &merged_environment);
459
if (retval != CORBA_OBJECT_NIL) {
460
g_free (merged_environment._buffer);
465
if (flags & Bonobo_ACTIVATION_FLAG_EXISTING_ONLY) {
466
return CORBA_OBJECT_NIL;
469
#ifdef BONOBO_ACTIVATION_DEBUG
473
for (i = 0; i < depth; i++)
475
fprintf (stderr, "Activate '%s'\n", iid);
483
si = g_hash_table_lookup (od->by_iid, iid);
486
retval = od_server_activate (
487
si, &ai, BONOBO_OBJREF (od), &merged_environment, client, ev);
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
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
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);
507
if (retval != CORBA_OBJECT_NIL)
508
CORBA_exception_free (ev);
512
#ifdef BONOBO_ACTIVATION_DEBUG
515
for (i = 0; i < depth; i++)
517
fprintf (stderr, "Activated '%s' = %p\n", iid, retval);
521
g_free (merged_environment._buffer);
526
extern GMainLoop *main_loop;
529
quit_server_timeout (gpointer user_data)
531
#ifdef BONOBO_ACTIVATION_DEBUG
532
g_warning ("Quit server !");
536
main_dir->n_active_servers > RESIDUAL_SERVERS ||
537
!activation_clients_is_empty_scan ())
538
g_warning ("Serious error handling server count, not quitting");
540
g_main_loop_quit (main_loop);
542
main_dir->no_servers_timeout = 0;
547
void od_finished_internal_registration (void)
549
finished_internal_registration = TRUE;
555
ObjectDirectory *od = main_dir;
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;
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);
567
od->time_active_changed = time (NULL);
571
remove_active_server_entry (ActiveServerList *servers,
574
CORBA_Object_release (servers->servers [index].server, NULL);
575
CORBA_free (servers->servers [index].environment._buffer);
577
if (index != servers->n_servers - 1)
578
memcpy (&servers->servers [index],
579
&servers->servers [servers->n_servers - 1],
580
sizeof (servers->servers [index]));
582
servers->n_servers--;
585
static ActiveServerList *
586
add_active_server_entry (ActiveServerList *servers,
587
const Bonobo_ActivationEnvironment *environment,
592
index = servers->n_servers - 1;
595
servers = g_realloc (servers,
596
sizeof (*servers) + sizeof (servers->servers [0]) * index);
598
servers->servers [index].server = CORBA_Object_duplicate (object, NULL);
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;
606
for (i = 0; i < environment->_length; i++)
607
Bonobo_ActivationEnvValue_copy (
608
&servers->servers [index].environment._buffer [i],
609
&environment->_buffer [i]);
615
prune_dead_servers (gpointer key,
619
ObjectDirectory *od = user_data;
620
ActiveServerList *servers = value;
623
for (i = 0; i < servers->n_servers; i++) {
624
ORBitConnectionStatus status;
627
status = ORBit_small_get_connection_status (
628
servers->servers [i].server);
630
dead = (status == ORBIT_CONNECTION_DISCONNECTED);
632
#ifdef BONOBO_ACTIVATION_DEBUG
633
fprintf (stderr, "IID '%20s' (%p), %s \n",
634
(char *) key, servers->servers [i].server,
635
dead ? "dead" : "alive");
638
remove_active_server_entry (servers, i);
640
od->n_active_servers--;
645
return !servers->n_servers;
649
active_server_cnx_broken (ORBitConnection *cnx,
653
ObjectDirectory *od = main_dir;
655
if (!od) /* shutting down */
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);
669
add_active_server (ObjectDirectory *od,
671
const Bonobo_ActivationEnvironment *environment,
674
ActiveServerList *servers;
675
ORBitConnection *cnx;
677
cnx = ORBit_small_get_connection (object);
679
if (!g_object_get_data (G_OBJECT (cnx), "object_count")) {
681
G_OBJECT (cnx), "object_count", GUINT_TO_POINTER (1));
685
G_CALLBACK (active_server_cnx_broken),
689
g_assert (!strcmp (iid, NAMING_CONTEXT_IID) ||
690
!strcmp(iid, EVENT_SOURCE_IID));
692
servers = g_hash_table_lookup (od->active_server_lists, iid);
694
servers = g_new0 (ActiveServerList, 1);
696
servers->iid = g_strdup (iid);
697
servers->n_servers = 1;
699
servers = add_active_server_entry (
700
servers, environment, object);
702
g_hash_table_insert (
703
od->active_server_lists, servers->iid, servers);
705
ActiveServerList *new_servers;
707
g_assert (servers->n_servers > 0);
709
servers->n_servers++;
711
new_servers = add_active_server_entry (
712
servers, environment, object);
714
if (new_servers != servers) { /* Need to reset the pointer */
715
g_hash_table_steal (od->active_server_lists, new_servers->iid);
717
g_hash_table_insert (
718
od->active_server_lists, new_servers->iid, new_servers);
722
if (finished_internal_registration)
723
od->n_active_servers++;
730
active_server_list_free (gpointer data)
732
ActiveServerList *servers = data;
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);
744
remove_active_server (ObjectDirectory *od,
748
ActiveServerList *servers;
749
gboolean removed = FALSE;
752
servers = g_hash_table_lookup (od->active_server_lists, iid);
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);
765
od->n_active_servers--;
767
if (servers->n_servers == 0)
768
g_hash_table_remove (od->active_server_lists, iid);
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,
780
const CORBA_char *description)
782
Bonobo_ServerInfo *old_serverinfo, *new_serverinfo;
783
GSList *parsed_serverinfo = NULL, *l;
786
update_registry (od, FALSE);
788
old_serverinfo = (Bonobo_ServerInfo *) g_hash_table_lookup (od->by_iid, iid);
790
return old_serverinfo;
791
if (!(*description)) /* empty description? */
794
/* parse description */
795
bonobo_parse_server_info_memory (description, &parsed_serverinfo,
796
bonobo_activation_hostname_get ());
798
/* check for zero entries */
799
if (!parsed_serverinfo)
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);
808
g_slist_free (parsed_serverinfo);
811
new_serverinfo = (Bonobo_ServerInfo *) parsed_serverinfo->data;
812
g_slist_free (parsed_serverinfo);
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;
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)
843
ObjectDirectory *od = OBJECT_DIRECTORY (servant);
845
Bonobo_ActivationEnvironment merged_environment;
846
Bonobo_ServerInfo const *serverinfo;
848
oldobj = od_get_active_server (od, iid, environment);
851
serverinfo = od_register_runtime_server_info (od, iid, description);
852
od_merge_client_environment (od, serverinfo, environment,
853
&merged_environment, client);
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;
864
if (!(flags&Bonobo_REGISTRATION_FLAG_NO_SERVERINFO)) {
865
g_free (merged_environment._buffer);
866
return Bonobo_ACTIVATION_REG_NOT_LISTED;
870
#ifdef BONOBO_ACTIVATION_DEBUG
871
g_warning ("Server register. '%s' : %p", iid, obj);
874
add_active_server (od, iid, &merged_environment, obj);
875
g_free (merged_environment._buffer);
877
bonobo_event_source_notify_listeners
879
"Bonobo/ObjectDirectory:activation:register",
882
return Bonobo_ACTIVATION_REG_SUCCESS;
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)
896
return impl_Bonobo_ObjectDirectory_register_new_full
897
(servant, iid, environment, obj, flags,
898
description, existing, CORBA_OBJECT_NIL, ev);
902
impl_Bonobo_ObjectDirectory_unregister (
903
PortableServer_Servant servant,
904
const CORBA_char *iid,
905
const CORBA_Object obj,
906
CORBA_Environment *ev)
908
ObjectDirectory *od = OBJECT_DIRECTORY (servant);
910
if (!remove_active_server (od, iid, obj))
911
CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
912
ex_Bonobo_ObjectDirectory_NotRegistered,
915
bonobo_event_source_notify_listeners
917
"Bonobo/ObjectDirectory:activation:unregister",
921
static Bonobo_DynamicPathLoadResult
922
impl_Bonobo_ObjectDirectory_add_path(
923
PortableServer_Servant servant,
924
const CORBA_char * add_path,
925
CORBA_Environment *ev)
927
ObjectDirectory *od = OBJECT_DIRECTORY (servant);
928
int i, j, dir_num, max;
929
char **add_directoies, **ret;
930
GSList *l, *tmp = NULL;
933
if (!od->registry_source_directories) {
934
od->registry_source_directories = split_path_unique (add_path);
935
return Bonobo_DYNAMIC_LOAD_SUCCESS;
937
add_directoies = split_path_unique (add_path);
940
return Bonobo_DYNAMIC_LOAD_ERROR;
942
for (max = i = 0; od->registry_source_directories[i]; i++) {
943
tmp = g_slist_append(tmp,g_strdup(od->registry_source_directories[i]));
949
for (i = 0; add_directoies[i]; i++) {
951
for (j = 0; od->registry_source_directories[j]; j++) {
952
if (!strcmp(add_directoies[i], od->registry_source_directories[j])) {
958
tmp = g_slist_append(tmp, g_strdup(add_directoies[i]));
963
if (max == dir_num) {
964
g_strfreev(add_directoies);
966
return Bonobo_DYNAMIC_LOAD_ALREADY_LISTED;
969
ret = g_new(char *, max + 1);
970
for (l = tmp, i = 0; l; l = l->next)
976
g_strfreev(add_directoies);
977
g_strfreev(od->registry_source_directories);
979
od->registry_source_directories = ret;
980
update_registry(od, TRUE);
981
return Bonobo_DYNAMIC_LOAD_SUCCESS;
984
static Bonobo_DynamicPathLoadResult
985
impl_Bonobo_ObjectDirectory_remove_path(
986
PortableServer_Servant servant,
987
const CORBA_char * remove_path,
988
CORBA_Environment *ev)
990
ObjectDirectory *od = OBJECT_DIRECTORY (servant);
991
char **remove_directoies, **ret;
993
GSList *l, *tmp = NULL;
996
remove_directoies = split_path_unique (remove_path);
997
if (!remove_directoies)
998
return Bonobo_DYNAMIC_LOAD_ERROR;
1000
for (max = i = 0; od->registry_source_directories[i]; i++) {
1002
for (j = 0; remove_directoies[j]; j++) {
1003
if (!strcmp(od->registry_source_directories[i], remove_directoies[j])) {
1010
tmp = g_slist_append(tmp, g_strdup(od->registry_source_directories[i]));
1017
g_strfreev(remove_directoies);
1018
return Bonobo_DYNAMIC_LOAD_NOT_LISTED;
1020
ret = g_new(char *, max + 1);
1021
for (l = tmp, i = 0; l; l = l->next)
1026
g_strfreev(remove_directoies);
1027
g_strfreev(od->registry_source_directories);
1029
od->registry_source_directories = ret;
1030
update_registry(od, TRUE);
1031
return Bonobo_DYNAMIC_LOAD_SUCCESS;
1036
client_cnx_broken (ORBitConnection *cnx,
1037
const Bonobo_ActivationClient client)
1039
ObjectDirectory *od = main_dir;
1040
if (!od) /* shutting down */
1042
g_hash_table_remove (od->client_envs, client);
1046
impl_Bonobo_ObjectDirectory_addClientEnv (
1047
PortableServer_Servant servant,
1048
const Bonobo_ActivationClient client,
1049
const Bonobo_StringList *client_env,
1050
CORBA_Environment *ev)
1052
Bonobo_ActivationEnvironment *env;
1053
ObjectDirectory *od = OBJECT_DIRECTORY (servant);
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;
1061
for (i = 0; i < client_env->_length; ++i)
1063
const char *keyval = client_env->_buffer[i];
1064
const char *equals = strchr (keyval, '=');
1068
g_warning ("Duff env. var '%s'", keyval);
1072
keylen = (guint) (equals - keyval);
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;
1081
g_hash_table_insert (od->client_envs, client, env);
1083
ORBit_small_listen_for_broken (client, G_CALLBACK (client_cnx_broken),
1088
Bonobo_ObjectDirectory
1089
bonobo_object_directory_get (void)
1092
return CORBA_OBJECT_NIL;
1094
return BONOBO_OBJREF (main_dir);
1098
bonobo_object_directory_event_source_get (void)
1101
return CORBA_OBJECT_NIL;
1103
return BONOBO_OBJREF (main_dir->event_source);
1107
bonobo_object_directory_init (PortableServer_POA poa,
1108
const char *registry_path,
1109
CORBA_Environment *ev)
1111
g_assert (main_dir == NULL);
1113
main_dir = g_object_new (OBJECT_TYPE_DIRECTORY, NULL);
1115
main_dir->registry_source_directories = split_path_unique (registry_path);
1116
update_registry (main_dir, FALSE);
1120
bonobo_object_directory_shutdown (PortableServer_POA poa,
1121
CORBA_Environment *ev)
1123
bonobo_object_set_immortal (BONOBO_OBJECT (main_dir), FALSE);
1124
bonobo_object_unref (BONOBO_OBJECT (main_dir));
1128
bonobo_object_directory_re_check_fn (const Bonobo_ActivationEnvironment *environment,
1129
const char *act_iid,
1131
CORBA_Environment *ev)
1133
CORBA_Object retval;
1135
retval = od_get_active_server (
1136
main_dir, (Bonobo_ImplementationID) act_iid, environment);
1138
if (ev->_major != CORBA_NO_EXCEPTION ||
1139
retval == CORBA_OBJECT_NIL) {
1141
Bonobo_GeneralError *errval = Bonobo_GeneralError__alloc ();
1143
CORBA_exception_free (ev);
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.
1152
msg = g_strdup_printf (_("Race condition activating server '%s'"), act_iid);
1153
errval->description = CORBA_string_dup (msg);
1156
CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
1157
ex_Bonobo_GeneralError, errval);
1158
retval = CORBA_OBJECT_NIL;
1165
bonobo_object_directory_reload (void)
1167
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "reloading our object directory!");
1169
update_registry (main_dir, TRUE);
1173
object_directory_finalize (GObject *object)
1175
ObjectDirectory *od = (ObjectDirectory *) object;
1179
g_hash_table_destroy (od->active_server_lists);
1180
g_hash_table_destroy (od->registry_directory_mtimes);
1182
g_strfreev (od->registry_source_directories);
1184
if (od->client_envs) {
1185
g_hash_table_destroy (od->client_envs);
1186
od->client_envs = NULL;
1189
parent_class->finalize (object);
1193
object_directory_class_init (ObjectDirectoryClass *klass)
1195
GObjectClass *object_class = (GObjectClass *) klass;
1196
POA_Bonobo_ObjectDirectory__epv *epv = &klass->epv;
1198
parent_class = g_type_class_peek_parent (klass);
1199
object_class->finalize = object_directory_finalize;
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;
1213
object_directory_init (ObjectDirectory *od)
1215
bonobo_object_set_immortal (BONOBO_OBJECT (od), TRUE);
1219
od->registry_directory_mtimes = g_hash_table_new (g_str_hash, g_str_equal);
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;
1226
od->attr_runtime_servers = g_ptr_array_new ();
1228
od->event_source = bonobo_event_source_new ();
1229
od->client_envs = g_hash_table_new_full
1231
(GDestroyNotify) CORBA_free);
1234
BONOBO_TYPE_FUNC_FULL (ObjectDirectory,
1235
Bonobo_ObjectDirectory,