Registering server info of Bonobo::Application



	The following patch makes BonoboApplication send a XML fragment in the
description parameter of Bonobo::ObjectDirectory::register_new.  Also
there are changes to bonobo-activation-server to parse the XML string
and register a new serverinfo from that description.  In the code, I
have called these servers described by XML fragments at runtime "runtime
servers".

	The end result is that now one can list running Bonobo::Application's. 
Example:

$ activation-client -q -s "repo_ids.has('IDL:Bonobo/Application:1.0') AND _active"
Query spec is "repo_ids.has('IDL:Bonobo/Application:1.0') AND _active"
IID OAFIID:Libbonobo-Test-Uniqapp, type runtime, location unknown
    repo_ids = ["IDL:Bonobo/Unknown:1.0", "IDL:Bonobo/Application:1.0"]
    name = "Libbonobo-Test-Uniqapp"
    description = "Libbonobo-Test-Uniqapp application instance"

	I won't try to hide that there are some shortcomings:
		1. Inefficiency: rescans server file directories whenever an
application registers with XML description parameter;
		2. Stability: it's not difficult to make it crash.  b-a-s has some
confusing memory management semantics that I have not been able to
completely grasp.

	However, I am worried about the upcoming freeze in December.  Perhaps
it's better to postpone fixing these issues for later, and tackle the
remaining problems (application browser, per-server configurable list of
environment variables that determine uniqueness) before it's too late.

	Now I'm going to make the bonobo application browser, in libbonoboui. 
Meanwhile, I'm awaiting comments about this patch.

-- 
Gustavo J. A. M. Carneiro
<gjc inescporto pt> <gustavo users sourceforge net>
? stamp-h1
? activation-server/test-performance
? tests/test-uniqapp
Index: activation-server/object-directory-corba.c
===================================================================
RCS file: /cvs/gnome/libbonobo/activation-server/object-directory-corba.c,v
retrieving revision 1.61
diff -u -p -r1.61 object-directory-corba.c
--- activation-server/object-directory-corba.c	26 Aug 2003 13:19:56 -0000	1.61
+++ activation-server/object-directory-corba.c	23 Nov 2003 13:20:24 -0000
@@ -186,6 +186,7 @@ update_registry (ObjectDirectory *od, gb
 #endif
                 bonobo_server_info_load (od->registry_source_directories,
                                          &od->attr_servers,
+                                         od->attr_runtime_servers,
                                          &od->by_iid,
                                          bonobo_activation_hostname_get ());
                 od->time_did_stat = od->time_list_changed = time (NULL);
@@ -668,6 +669,61 @@ remove_active_server (ObjectDirectory *o
 	return removed;
 }
 
+  /* Parse server description and register it, replacing older
+   * definition if necessary.  Returns the regsitered ServerInfo */
+static Bonobo_ServerInfo const *
+od_register_runtime_server_info (ObjectDirectory  *od,
+                                 const char       *iid,
+                                 const CORBA_char *description)
+{
+        Bonobo_ServerInfo *old_serverinfo, *new_serverinfo;
+        GSList *parsed_serverinfo = NULL, *l;
+
+        old_serverinfo = (Bonobo_ServerInfo *) g_hash_table_lookup (od->by_iid, iid);
+        if (!(*description)) /* empty description? */
+                return old_serverinfo;
+
+          /* parse description */
+         bonobo_parse_server_info_memory (description, &parsed_serverinfo,
+                                          bonobo_activation_hostname_get ());
+
+           /* check for zero entries */
+         if (!parsed_serverinfo)
+                 return NULL;
+           /* check for more than one entry */
+         if (parsed_serverinfo->next) {
+                 g_warning ("More than one <oaf_server> specified, ignoring all");
+                 for (l = parsed_serverinfo; l; l = l->next) {
+                         Bonobo_ServerInfo__freekids (l->data, NULL);
+                         g_free (l->data);
+                 }
+                 g_slist_free (parsed_serverinfo);
+                 return NULL;
+         }
+         new_serverinfo = (Bonobo_ServerInfo *) parsed_serverinfo->data;
+         g_slist_free (parsed_serverinfo);
+
+         if (old_serverinfo) {
+                 Bonobo_ServerInfo *old_runtime_serverinfo;
+                 int i;
+
+                 for (i = 0; i < od->attr_runtime_servers->len; i++) {
+                         old_runtime_serverinfo = g_ptr_array_index (od->attr_runtime_servers, i);
+                         if (strcmp (old_runtime_serverinfo->iid, iid) == 0) {
+                                 Bonobo_ServerInfo__freekids (old_runtime_serverinfo, NULL);
+                                 g_free (old_runtime_serverinfo);
+                                 g_ptr_array_index (od->attr_runtime_servers, i) = new_serverinfo;
+                                 return new_serverinfo;
+                         }
+                 }
+                 g_warning ("Inconsistency between od->attr_servers "
+                            "and od->attr_runtime_servers");
+         } else
+                 g_ptr_array_add (od->attr_runtime_servers, new_serverinfo);
+           /* FIXME: this kill performance, need an alternative */
+         update_registry (od, TRUE);
+}
+
 static Bonobo_RegistrationResult
 impl_Bonobo_ObjectDirectory_register_new (
 	PortableServer_Servant              servant,
@@ -690,7 +746,7 @@ impl_Bonobo_ObjectDirectory_register_new
 			return Bonobo_ACTIVATION_REG_ALREADY_ACTIVE;
 	}
 
-        if (!g_hash_table_lookup (od->by_iid, iid)) {
+        if (!od_register_runtime_server_info (od, iid,description)) {
                 if (!(flags&Bonobo_REGISTRATION_FLAG_NO_SERVERINFO))
                         return Bonobo_ACTIVATION_REG_NOT_LISTED;
         }
@@ -954,6 +1010,8 @@ object_directory_init (ObjectDirectory *
                 g_hash_table_new_full (g_str_hash, g_str_equal,
                                        g_free, active_server_list_free);
         od->no_servers_timeout = 0;
+
+        od->attr_runtime_servers = g_ptr_array_new ();
 }
 
 BONOBO_TYPE_FUNC_FULL (ObjectDirectory,
Index: activation-server/object-directory-load.c
===================================================================
RCS file: /cvs/gnome/libbonobo/activation-server/object-directory-load.c,v
retrieving revision 1.40
diff -u -p -r1.40 object-directory-load.c
--- activation-server/object-directory-load.c	9 May 2003 07:26:32 -0000	1.40
+++ activation-server/object-directory-load.c	23 Nov 2003 13:20:24 -0000
@@ -551,19 +551,14 @@ static xmlSAXHandler od_SAXParser = {
 };
 
 static void
-od_load_file (const char *file,
-              GSList    **entries,
-              const char *host)
+od_load_context (xmlParserCtxt *ctxt,
+                 GSList    **entries,
+                 const char *host)
 {
         ParseInfo *info;
 	xmlSAXHandlerPtr oldsax;
-        xmlParserCtxt *ctxt;
         int ret = 0;
 
-        ctxt = xmlCreateFileParserCtxt (file);
-        if (!ctxt)
-                return;
-        
         info = parse_info_new ();
         info->host = host;
         info->entries = entries;
@@ -585,7 +580,6 @@ od_load_file (const char *file,
                         ret = -1;
         }
         ctxt->sax = oldsax;
-        xmlFreeParserCtxt (ctxt);
 
         parse_info_free (info);
 
@@ -595,6 +589,34 @@ od_load_file (const char *file,
         }
 }
 
+static void
+od_load_file (const char *file,
+              GSList    **entries,
+              const char *host)
+{
+        xmlParserCtxt *ctxt;
+
+        ctxt = xmlCreateFileParserCtxt (file);
+        if (!ctxt)
+                return;
+        od_load_context (ctxt, entries, host);
+        xmlFreeParserCtxt (ctxt);
+}
+
+void
+bonobo_parse_server_info_memory (const char *server_info,
+                                 GSList    **entries,
+                                 const char *host)
+{
+        xmlParserCtxt *ctxt;
+
+        ctxt = xmlCreateMemoryParserCtxt (server_info, strlen (server_info));
+        if (!ctxt)
+                return;
+        od_load_context (ctxt, entries, host);
+        xmlFreeParserCtxt (ctxt);
+}
+
 static gboolean
 od_filename_has_extension (const char *filename,
                            const char *extension)
@@ -643,10 +665,11 @@ od_load_directory (const char *directory
 
 
 void
-bonobo_server_info_load (char **directories,
-                         Bonobo_ServerInfoList   *servers,
-                         GHashTable **iid_to_server_info_map,
-                         const char *host)
+bonobo_server_info_load (char                  **directories,
+                         Bonobo_ServerInfoList  *servers,
+                         GPtrArray const        *runtime_servers,
+                         GHashTable            **iid_to_server_info_map,
+                         const char             *host)
 {
 	GSList *entries;
         int length;
@@ -671,17 +694,26 @@ bonobo_server_info_load (char **director
 	/* Now convert 'entries' into something that the server can store and pass back */
 	length = g_slist_length (entries);
 
-	servers->_buffer = CORBA_sequence_Bonobo_ServerInfo_allocbuf (length);
+	servers->_buffer = CORBA_sequence_Bonobo_ServerInfo_allocbuf
+                (length + runtime_servers->len);
 	/*
 	 * FIXME: servers->_buffer should be freed
 	 */
-	servers->_length = length;
+	servers->_length = length + runtime_servers->len;
 
 	for (j = 0, p = entries; j < length; j++, p = p->next) {
 		memcpy (&servers->_buffer[j], p->data, sizeof (Bonobo_ServerInfo));
 		g_hash_table_insert (*iid_to_server_info_map,
                                      servers->_buffer[j].iid,
                                      &servers->_buffer[j]);
+	}
+          /* append information of runtime-defined servers  */
+	for (j = 0; j < runtime_servers->len; j++) {
+                servers->_buffer[length + j] = *(Bonobo_ServerInfo *)
+                        g_ptr_array_index (runtime_servers, j);
+		g_hash_table_insert (*iid_to_server_info_map,
+                                     servers->_buffer[length + j].iid,
+                                     &servers->_buffer[length + j]);
 	}
 
         g_slist_foreach (entries, (GFunc) g_free, NULL);
Index: activation-server/object-directory.h
===================================================================
RCS file: /cvs/gnome/libbonobo/activation-server/object-directory.h,v
retrieving revision 1.2
diff -u -p -r1.2 object-directory.h
--- activation-server/object-directory.h	30 May 2003 15:56:01 -0000	1.2
+++ activation-server/object-directory.h	23 Nov 2003 13:20:25 -0000
@@ -32,7 +32,10 @@ struct _ObjectDirectory {
 
         /* Information on all servers */
 	GHashTable           *by_iid;
+	  /* Includes contents of attr_runtime_servers at the end */
 	Bonobo_ServerInfoList attr_servers;
+	  /* Servers without .server file, completely defined at run-time */
+	GPtrArray            *attr_runtime_servers;
 	Bonobo_CacheTime      time_list_changed;
 
         /* CORBA Object tracking */
Index: activation-server/server.h
===================================================================
RCS file: /cvs/gnome/libbonobo/activation-server/server.h,v
retrieving revision 1.21
diff -u -p -r1.21 server.h
--- activation-server/server.h	4 Jun 2003 15:32:34 -0000	1.21
+++ activation-server/server.h	23 Nov 2003 13:20:25 -0000
@@ -21,10 +21,15 @@
 #define NAMING_CONTEXT_IID "OAFIID:Bonobo_CosNaming_NamingContext"
 
 /* object-directory-load.c */
-void                   bonobo_server_info_load             (char                 **dirs,
-                                                            Bonobo_ServerInfoList *servers,
-                                                            GHashTable           **by_iid,
-                                                            const char            *host);
+void bonobo_server_info_load         (char                  **dirs,
+                                      Bonobo_ServerInfoList  *servers,
+                                      GPtrArray const        *runtime_servers,
+                                      GHashTable            **by_iid,
+                                      const char             *host);
+void bonobo_parse_server_info_memory (const char             *server_info,
+                                      GSList                **entries,
+                                      const char             *host);
+
 
 /* od-activate.c */
 typedef struct {
Index: activation-server/test-performance.c
===================================================================
RCS file: /cvs/gnome/libbonobo/activation-server/test-performance.c,v
retrieving revision 1.5
diff -u -p -r1.5 test-performance.c
--- activation-server/test-performance.c	17 Oct 2002 23:11:02 -0000	1.5
+++ activation-server/test-performance.c	23 Nov 2003 13:20:25 -0000
@@ -13,13 +13,14 @@ test_server_info_load (void)
 	int i;
 	char *dirs [] = { SERVERINFODIR, NULL };
 	Bonobo_ServerInfoList servers;
+	GPtrArray *runtime_servers = g_ptr_array_new ();
 	GHashTable *hash = NULL;
 
 	fprintf (stderr, "Testing server info load ...");
 
 	g_timer_start (timer);
 	for (i = 0; i < 10; i++)
-		bonobo_server_info_load (dirs, &servers, &hash,
+		bonobo_server_info_load (dirs, &servers, runtime_servers, &hash,
 					 bonobo_activation_hostname_get ());
 
 	fprintf (stderr, " %g(ms)\n",
Index: bonobo/bonobo-application.c
===================================================================
RCS file: /cvs/gnome/libbonobo/bonobo/bonobo-application.c,v
retrieving revision 1.2
diff -u -p -r1.2 bonobo-application.c
--- bonobo/bonobo-application.c	22 Nov 2003 11:59:28 -0000	1.2
+++ bonobo/bonobo-application.c	23 Nov 2003 13:20:25 -0000
@@ -484,8 +484,19 @@ bonobo_application_register_unique (Bono
 	CORBA_Object               remote_obj = CORBA_OBJECT_NIL;
 
 	iid     = g_strdup_printf ("OAFIID:%s", app->name);
-	description = g_strdup_printf ("Unique Application instance: '%s'",
-				       app->name);
+	description = g_strdup_printf (
+		"<oaf_info>\n"
+		"  <oaf_server iid=\"%s\" location=\"unknown\" type=\"runtime\">\n"
+		"    <oaf_attribute name=\"repo_ids\" type=\"stringv\">\n"
+		"       <item value=\"IDL:Bonobo/Unknown:1.0\"/>\n"
+		"       <item value=\"IDL:Bonobo/Application:1.0\"/>\n"
+		"    </oaf_attribute>\n"
+		"    <oaf_attribute name=\"name\" type=\"string\" value=\"%s\"/>\n"
+		"    <oaf_attribute name=\"description\" type=\"string\" "
+		" value=\"%s application instance\"/>\n"
+		"  </oaf_server>\n"
+		"</oaf_info>",
+		iid, app->name, app->name);
 	reg_res = bonobo_activation_register_active_server_ext
 		(iid, bonobo_object_corba_objref (BONOBO_OBJECT (app)), NULL,
 		 Bonobo_REGISTRATION_FLAG_NO_SERVERINFO, &remote_obj,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]