Implemented CaptiveParentConnector sandbox restarts handling GInterface.
authorshort <>
Fri, 12 Sep 2003 07:15:14 +0000 (07:15 +0000)
committershort <>
Fri, 12 Sep 2003 07:15:14 +0000 (07:15 +0000)
16 files changed:
autogen.pl
src/libcaptive/client/Makefile.am
src/libcaptive/client/directory-parent.c
src/libcaptive/client/directory-parent.h
src/libcaptive/client/marshallers.list [new file with mode: 0644]
src/libcaptive/client/parent-connector.c [new file with mode: 0644]
src/libcaptive/client/parent-connector.h [new file with mode: 0644]
src/libcaptive/client/vfs-parent.c
src/libcaptive/client/vfs-parent.h
src/libcaptive/sandbox/client-CaptiveIOChannel.c
src/libcaptive/sandbox/parent-Directory.c
src/libcaptive/sandbox/parent-Directory.h
src/libcaptive/sandbox/parent-File.c
src/libcaptive/sandbox/parent-Vfs.c
src/libcaptive/sandbox/split.c
src/libcaptive/sandbox/split.h

index 0b71494..e7d06c1 100755 (executable)
@@ -55,6 +55,7 @@ AutoGen->run(
                                ./src/install/acquire/ui-gnome.glade.bak
                                ./src/install/acquire/ui-gnome.gladep.bak
                                ./src/libcaptive/cc/marshallers.[ch]
+                               ./src/libcaptive/client/marshallers.[ch]
                                ./src/libcaptive/ke/exports.c
                                ./src/libcaptive/reactos/*/*.[cS]
                                ./src/libcaptive/sandbox/sandbox-common.c
index f56cfac..adcc308 100644 (file)
@@ -21,10 +21,10 @@ include $(top_srcdir)/src/libcaptive/Makefile-libcaptive.am
 
 noinst_LTLIBRARIES=libclient.la
 libclient_la_SOURCES= \
-               directory-slave.c \
-               directory-slave.h \
                directory-parent.c \
                directory-parent.h \
+               directory-slave.c \
+               directory-slave.h \
                directory.c \
                directory.h \
                file-parent.c \
@@ -41,8 +41,12 @@ libclient_la_SOURCES= \
                lib.c \
                lib.h \
                libxml.c \
-               options.c \
+               marshallers.c \
+               marshallers.h \
                options-module.c \
+               options.c \
+               parent-connector.c \
+               parent-connector.h \
                result.c \
                result.h \
                usecount.c \
@@ -56,3 +60,19 @@ libclient_la_CFLAGS= \
                $(GNOME_VFS_MODULE_CFLAGS) $(OPENSSL_CFLAGS) $(LIBXML_CFLAGS)
 libclient_la_LIBADD= \
                $(GNOME_VFS_MODULE_LIBS)   $(OPENSSL_LIBS)   $(LIBXML_LIBS)
+
+marshallers.h: marshallers.list
+          glib-genmarshal --prefix=captive_client $< --header >$@
+
+marshallers.c: marshallers.list
+          glib-genmarshal --prefix=captive_client $< --body >$@
+
+EXTRA_DIST+= \
+               marshallers.list
+
+CLEANFILES+= \
+               marshallers.c \
+               marshallers.h
+
+# FIXME: Prevent: libtool: link: `libclient_la-parent-connector.lo' is not a valid libtool object
+# dependency: libclient_la-parent-connector.lo: marshallers.h
index 6a473cf..be8970e 100644 (file)
@@ -23,6 +23,7 @@
 #include <glib/gmessages.h>
 #include "../sandbox/parent-Directory.h"
 #include "vfs-parent.h"
+#include "parent-connector.h"
 
 
 static gpointer captive_directory_parent_object_parent_class=NULL;
@@ -57,8 +58,31 @@ CaptiveDirectoryObjectClass *captive_directory_object_class=CAPTIVE_DIRECTORY_OB
 }
 
 
+static GnomeVFSResult (*captive_directory_parent_object_captive_parent_connector_open_orig)
+               (CaptiveParentConnector *captive_parent_connector);
+static GnomeVFSResult captive_directory_parent_object_captive_parent_connector_open
+               (CaptiveParentConnector *captive_parent_connector);
+
+static GnomeVFSResult captive_directory_parent_object_captive_parent_connector_close
+               (CaptiveParentConnector *captive_parent_connector);
+static GnomeVFSResult (*captive_directory_parent_object_captive_parent_connector_close_orig)
+               (CaptiveParentConnector *captive_parent_connector);
+
+static void captive_directory_parent_object_captive_parent_connector_init(CaptiveParentConnectorIface *captive_parent_connector_iface)
+{
+       g_return_if_fail(CAPTIVE_IS_PARENT_CONNECTOR_CLASS(captive_parent_connector_iface));
+
+       captive_directory_parent_object_captive_parent_connector_open_orig=captive_parent_connector_iface->open;
+       captive_parent_connector_iface->open=captive_directory_parent_object_captive_parent_connector_open;
+
+       captive_directory_parent_object_captive_parent_connector_close_orig=captive_parent_connector_iface->close;
+       captive_parent_connector_iface->close=captive_directory_parent_object_captive_parent_connector_close;
+}
+
+
 static void captive_directory_parent_object_init(CaptiveDirectoryParentObject *captive_directory_parent_object)
 {
+       g_return_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_parent_object));
 }
 
 
@@ -78,19 +102,44 @@ static const GTypeInfo captive_directory_parent_object_info={
                                5,      /* n_preallocs */
                                (GInstanceInitFunc)captive_directory_parent_object_init,
                                };
+static const GInterfaceInfo captive_parent_connector_info={
+                               (GInterfaceInitFunc)captive_directory_parent_object_captive_parent_connector_init,      /* interface_init */
+                               NULL,   /* interface_finalize */
+                               NULL,   /* interface_data */
+                               };
 
                captive_directory_parent_object_type=g_type_register_static(CAPTIVE_DIRECTORY_TYPE_OBJECT,
                                "CaptiveDirectoryParentObject",&captive_directory_parent_object_info,0);
+               g_type_add_interface_static(captive_directory_parent_object_type,
+                               CAPTIVE_TYPE_PARENT_CONNECTOR,&captive_parent_connector_info);
                }
 
        return captive_directory_parent_object_type;
 }
 
 
+static void captive_directory_parent_init
+               (CaptiveDirectoryParentObject *captive_directory_parent_object,CaptiveVfsObject *captive_vfs_object)
+{
+       g_return_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_parent_object));
+       g_return_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_object));
+
+       /* Order of captive_directory_init() and captive_parent_connector_init()
+        * should not matter as 'vfs' is passed by value to captive_parent_connector_init().
+        */
+       captive_directory_init(CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object),captive_vfs_object);
+
+       captive_parent_connector_init(
+                       CAPTIVE_PARENT_CONNECTOR(captive_directory_parent_object),      /* captive_parent_connector */
+                       &captive_directory_parent_object->corba_Directory_object,       /* corba_objectp */
+                       CAPTIVE_VFS_PARENT_OBJECT(CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object)->vfs));     /* captive_vfs_parent_object */
+}
+
 GnomeVFSResult captive_directory_parent_new_open(CaptiveDirectoryObject **captive_directory_object_return,
                CaptiveVfsObject *captive_vfs_object,const gchar *pathname)
 {
 CaptiveDirectoryParentObject *captive_directory_parent_object;
+GnomeVFSResult r;
 
        g_return_val_if_fail(captive_directory_object_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
@@ -99,12 +148,22 @@ CaptiveDirectoryParentObject *captive_directory_parent_object;
        captive_directory_parent_object=g_object_new(
                        CAPTIVE_DIRECTORY_PARENT_TYPE_OBJECT,   /* object_type */
                        NULL);  /* first_property_name; FIXME: support properties */
+       captive_directory_parent_object->pathname=g_strdup(pathname);
 
-       captive_directory_init(CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object),captive_vfs_object);
+       captive_directory_parent_init(captive_directory_parent_object,captive_vfs_object);
 
-       *captive_directory_object_return=CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object);
+       if (GNOME_VFS_OK!=(r=captive_parent_connector_connect(CAPTIVE_PARENT_CONNECTOR(captive_directory_parent_object))))
+               return r;
+
+       if (GNOME_VFS_OK!=(r=captive_sandbox_parent_directory_new_open(captive_directory_parent_object))) {
+               g_object_unref(captive_directory_parent_object);
+               *captive_directory_object_return=NULL;
+               return r;
+               }
 
-       return captive_sandbox_parent_directory_new_open(captive_directory_parent_object,pathname);
+       *captive_directory_object_return=CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object);
+       return (*captive_directory_parent_object_captive_parent_connector_open_orig)
+                       (CAPTIVE_PARENT_CONNECTOR(captive_directory_parent_object));
 }
 
 
@@ -112,6 +171,7 @@ GnomeVFSResult captive_directory_parent_new_make(CaptiveDirectoryObject **captiv
                CaptiveVfsObject *captive_vfs_object,const gchar *pathname,guint perm)
 {
 CaptiveDirectoryParentObject *captive_directory_parent_object;
+GnomeVFSResult r;
 
        g_return_val_if_fail(captive_directory_object_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
@@ -120,24 +180,72 @@ CaptiveDirectoryParentObject *captive_directory_parent_object;
        captive_directory_parent_object=g_object_new(
                        CAPTIVE_DIRECTORY_PARENT_TYPE_OBJECT,   /* object_type */
                        NULL);  /* first_property_name; FIXME: support properties */
+       captive_directory_parent_object->pathname=g_strdup(pathname);
 
-       captive_directory_init(CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object),captive_vfs_object);
+       captive_directory_parent_init(captive_directory_parent_object,captive_vfs_object);
 
-       *captive_directory_object_return=CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object);
+       if (GNOME_VFS_OK!=(r=captive_parent_connector_connect(CAPTIVE_PARENT_CONNECTOR(captive_directory_parent_object))))
+               return r;
+
+       if (GNOME_VFS_OK!=(r=captive_sandbox_parent_directory_new_make(captive_directory_parent_object,perm))) {
+               g_object_unref(captive_directory_parent_object);
+               *captive_directory_object_return=NULL;
+               return r;
+               }
 
-       return captive_sandbox_parent_directory_new_make(captive_directory_parent_object,pathname,perm);
+       *captive_directory_object_return=CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object);
+       return (*captive_directory_parent_object_captive_parent_connector_open_orig)
+                       (CAPTIVE_PARENT_CONNECTOR(captive_directory_parent_object));
 }
 
 
 static GnomeVFSResult captive_directory_parent_close(CaptiveDirectoryObject *captive_directory_object)
 {
 CaptiveDirectoryParentObject *captive_directory_parent_object;
+GnomeVFSResult r;
 
        g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
 
        captive_directory_parent_object=CAPTIVE_DIRECTORY_PARENT_OBJECT(captive_directory_object);
 
-       return captive_sandbox_parent_directory_close(captive_directory_parent_object);
+       r=captive_parent_connector_close(CAPTIVE_PARENT_CONNECTOR(captive_directory_parent_object));
+
+       captive_parent_connector_finalize(CAPTIVE_PARENT_CONNECTOR(captive_directory_parent_object));
+
+       g_free(captive_directory_parent_object->pathname);
+       captive_directory_parent_object->pathname=NULL;
+
+       return r;
+}
+
+
+static GnomeVFSResult captive_directory_parent_object_captive_parent_connector_open
+               (CaptiveParentConnector *captive_parent_connector)
+{
+GnomeVFSResult r;
+
+       g_return_val_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector),GNOME_VFS_ERROR_BAD_PARAMETERS);
+       g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_parent_connector),GNOME_VFS_ERROR_BAD_PARAMETERS);
+
+       if (GNOME_VFS_OK!=(r=captive_sandbox_parent_directory_new_open(CAPTIVE_DIRECTORY_PARENT_OBJECT(captive_parent_connector))))
+               return r;
+
+       return (*captive_directory_parent_object_captive_parent_connector_open_orig)(captive_parent_connector);
+}
+
+
+static GnomeVFSResult captive_directory_parent_object_captive_parent_connector_close
+               (CaptiveParentConnector *captive_parent_connector)
+{
+GnomeVFSResult r;
+
+       g_return_val_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector),GNOME_VFS_ERROR_BAD_PARAMETERS);
+       g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_parent_connector),GNOME_VFS_ERROR_BAD_PARAMETERS);
+
+       if (GNOME_VFS_OK!=(r=captive_sandbox_parent_directory_close(CAPTIVE_DIRECTORY_PARENT_OBJECT(captive_parent_connector))))
+               return r;
+
+       return (*captive_directory_parent_object_captive_parent_connector_close_orig)(captive_parent_connector);
 }
 
 
@@ -145,23 +253,43 @@ static GnomeVFSResult captive_directory_parent_read
                (CaptiveDirectoryObject *captive_directory_object,GnomeVFSFileInfo *file_info)
 {
 CaptiveDirectoryParentObject *captive_directory_parent_object;
+GnomeVFSResult r;
+gint retried=0;
 
        g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(file_info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
        captive_directory_parent_object=CAPTIVE_DIRECTORY_PARENT_OBJECT(captive_directory_object);
 
-       return captive_sandbox_parent_directory_read(captive_directory_parent_object,file_info);
+       do {
+               if (GNOME_VFS_OK!=(r=captive_parent_connector_open(CAPTIVE_PARENT_CONNECTOR(captive_directory_parent_object))))
+                       return r;
+               if (GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE
+                               !=(r=captive_sandbox_parent_directory_read(captive_directory_parent_object,file_info)))
+                       return r;
+               } while (!retried++);
+       return r;
 }
 
 
 static GnomeVFSResult captive_directory_parent_remove(CaptiveDirectoryObject *captive_directory_object)
 {
 CaptiveDirectoryParentObject *captive_directory_parent_object;
+GnomeVFSResult r;
+gint retried=0;
 
        g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
 
        captive_directory_parent_object=CAPTIVE_DIRECTORY_PARENT_OBJECT(captive_directory_object);
 
-       return captive_sandbox_parent_directory_remove(captive_directory_parent_object);
+       do {
+               if (GNOME_VFS_OK!=(r=captive_parent_connector_open(CAPTIVE_PARENT_CONNECTOR(captive_directory_parent_object))))
+                       return r;
+               if (GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE!=(r=captive_sandbox_parent_directory_remove(captive_directory_parent_object))) {
+                       if (GNOME_VFS_OK==r)
+                               captive_parent_connector_set_dirty(CAPTIVE_PARENT_CONNECTOR(captive_directory_parent_object));
+                       return r;
+                       }
+               } while (!retried++);
+       return r;
 }
index a2ab98e..1f3d7be 100644 (file)
@@ -49,6 +49,7 @@ struct _CaptiveDirectoryParentObject {
        /*< private >*/
        Captive_Directory corba_Directory_object;
        GList *corba_Directory_file_info_list;  /* contents */
+       gchar *pathname;
        };
 struct _CaptiveDirectoryParentObjectClass {
        CaptiveDirectoryObjectClass parent_class;
diff --git a/src/libcaptive/client/marshallers.list b/src/libcaptive/client/marshallers.list
new file mode 100644 (file)
index 0000000..0d00eeb
--- /dev/null
@@ -0,0 +1,19 @@
+# $Id$
+# Mashallers for GObject based CaptiveParentConnector of libcaptive
+# Copyright (C) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
+# 
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; exactly version 2 of June 1991 is required
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+VOID:VOID
diff --git a/src/libcaptive/client/parent-connector.c b/src/libcaptive/client/parent-connector.c
new file mode 100644 (file)
index 0000000..e1931ca
--- /dev/null
@@ -0,0 +1,481 @@
+/* $Id$
+ * fs object sandbox parents reconnections to their sandbox slave peers
+ * Copyright (C) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; exactly version 2 of June 1991 is required
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "config.h"
+
+#include "parent-connector.h"  /* self */
+#include <glib/gmessages.h>
+
+
+/* g_object_get_data() 'key': */
+#define CAPTIVE_PARENT_CONNECTOR_CORBA_OBJECTP             "captive_parent_connector-corba_objectp"    /* &CORBA_Object */
+#define CAPTIVE_PARENT_CONNECTOR_CAPTIVE_VFS_PARENT_OBJECT "captive_parent_connector-captive_vfs_parent_object"        /* &CaptiveVfsParentObject */
+#define CAPTIVE_PARENT_CONNECTOR_DIRTY                     "captive_parent_connector-dirty"    /* GINT_TO_POINTER(0/1) */
+#define CAPTIVE_PARENT_CONNECTOR_VFS_SIGNALS_CONNECTED     "captive_parent_connector-vfs_signals_connected"    /* GINT_TO_POINTER(0/1) */
+
+
+/*
+ * vfs signal <detach>
+ * vfs signal <cease>
+ * vfs signal <abort>
+ * 
+ * connector state vfs          yes/no
+ * connector state corba_object yes/no
+ * connector state dirty        yes/no
+ * 
+ *                 vfs     handle  dirty   oper.   detach  cease   abort
+ * disconnected    N       N       N       opn_*   discon. discon. discon.
+ * broken          N       N       Y       broken  broken  broken  broken
+ * N/A             N       Y       N
+ * N/A             N       Y       Y
+ * closed_clean    Y       N       N       X       X       discon. discon.
+ * closed_dirty    Y       N       Y       X       X       discon. broken
+ * opened_clean    Y       Y       N       opn_*   cls_cln X       discon.
+ * opened_dirty    Y       Y       Y       opn_drt cls_drt X       broken
+ * 
+ * init->disconnected
+ * 
+ * <detach>[VFS shutdown]<cease>
+ * <detach>[failure]<abort>
+ * [failure]<abort>
+ * 
+ * 
+ * sandbox master GObject hierarchy (horizontal=dervived):
+ *         DirectoryParent----------------------------------->Directory->GObject
+ *                        \->ParentConnector->GTypeInterface   |
+ *                                  | [ref.]                   | [reference]
+ *                                 VfsParent----------------->Vfs->GObject
+ * 
+ * sandbox master GObject reconnections signalling:
+ *               VfsParent -> ParentConnector
+ *         ParentConnector -> DirectoryParent
+ * sandbox master reconnection requests:
+ *         DirectoryParent -> ParentConnector
+ *         ParentConnector -> VfsParent
+ * 
+ * CORBA/ORBit connections:
+ *         sandbox master                   |  sandbox slave (restartable)
+ *         ---------------------------------|-----------------------------------
+ *         DirectoryParent--Directory_stub <-> Directory_servant--DirectorySlave
+ *               VfsParent--------Vfs_stub <->       Vfs_servant--VfsSlave
+ * 
+ * sandbox slave GObject hierarchy (horizontal=dervived):
+ *         DirectorySlave->Directory->GObject
+ *                          | [reference]
+ *               VfsSlave->Vfs->GObject
+ */
+
+
+static GnomeVFSResult captive_parent_connector_handler_open(CaptiveParentConnector *captive_parent_connector);
+static GnomeVFSResult captive_parent_connector_handler_close(CaptiveParentConnector *captive_parent_connector);
+
+
+static void captive_parent_connector_iface_init(CaptiveParentConnectorIface *captive_parent_connector_iface)
+{
+       captive_parent_connector_iface->open=captive_parent_connector_handler_open;
+       captive_parent_connector_iface->close=captive_parent_connector_handler_close;
+}
+
+
+GType captive_parent_connector_get_type(void)
+{
+static GType captive_parent_connector_type=0;
+
+       if (!captive_parent_connector_type) {
+static const GTypeInfo captive_parent_connector_info={
+                               sizeof(CaptiveParentConnectorIface),
+                               (GBaseInitFunc)captive_parent_connector_iface_init,     /* base_init */
+                               NULL,   /* base_finalize */
+                               NULL,   /* iface_init */
+                               NULL,   /* iface_finalize */
+                               NULL,   /* iface_data */
+                               0,      /* instance_size */
+                               0,      /* n_preallocs */
+                               NULL,   /* instance_init */
+                               };
+
+               captive_parent_connector_type=g_type_register_static(G_TYPE_INTERFACE,
+                               "CaptiveParentConnector",&captive_parent_connector_info,0);
+               }
+
+       return captive_parent_connector_type;
+}
+
+static void captive_parent_connector_vfs_signals_disconnect(CaptiveParentConnector *captive_parent_connector);
+
+static void captive_parent_connector_vfs_detach(CaptiveVfsParentObject *captive_vfs_parent_object,
+               CaptiveParentConnector *captive_parent_connector)
+{
+       g_return_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object));
+       g_return_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector));
+       g_return_if_fail(captive_vfs_parent_object==captive_parent_connector_get_captive_vfs_parent_object(captive_parent_connector));
+
+       /**/ if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_DISCONNECTED))
+               /* NOP */;
+       else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_BROKEN))
+               /* NOP */;
+       else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED))
+               g_assert_not_reached();
+       else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_OPENED)) {
+               (*CAPTIVE_PARENT_CONNECTOR_GET_IFACE(captive_parent_connector)->close)(captive_parent_connector);       /* errors ignored */
+               g_assert(captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED));
+               }
+       else g_assert_not_reached();
+}
+
+static void captive_parent_connector_vfs_cease(CaptiveVfsParentObject *captive_vfs_parent_object,
+               CaptiveParentConnector *captive_parent_connector)
+{
+       g_return_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object));
+       g_return_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector));
+       g_return_if_fail(captive_vfs_parent_object==captive_parent_connector_get_captive_vfs_parent_object(captive_parent_connector));
+
+       /**/ if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_DISCONNECTED))
+               /* NOP */;
+       else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_BROKEN))
+               /* NOP */;
+       else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED)) {
+               g_object_set_data(G_OBJECT(captive_parent_connector),CAPTIVE_PARENT_CONNECTOR_DIRTY,
+                               GINT_TO_POINTER(FALSE));
+               }
+       else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_OPENED))
+               g_assert_not_reached();
+       else g_assert_not_reached();
+
+       captive_parent_connector_vfs_signals_disconnect(captive_parent_connector);
+}
+
+static void captive_parent_connector_vfs_abort(CaptiveVfsParentObject *captive_vfs_parent_object,
+               CaptiveParentConnector *captive_parent_connector)
+{
+       g_return_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object));
+       g_return_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector));
+       g_return_if_fail(captive_vfs_parent_object==captive_parent_connector_get_captive_vfs_parent_object(captive_parent_connector));
+
+       /**/ if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_DISCONNECTED))
+               /* NOP */;
+       else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_BROKEN))
+               /* NOP */;
+       else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED))
+               /* NOP */;      /* -> DISCONNECTED or BROKEN */
+       else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_OPENED)) {
+               (*CAPTIVE_PARENT_CONNECTOR_GET_IFACE(captive_parent_connector)->close)(captive_parent_connector);       /* errors ignored */
+               g_assert(captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED));
+               }
+       else g_assert_not_reached();
+
+       captive_parent_connector_vfs_signals_disconnect(captive_parent_connector);
+}
+
+static void captive_parent_connector_vfs_signals_connect(CaptiveParentConnector *captive_parent_connector)
+{
+CaptiveVfsParentObject *captive_vfs_parent_object;
+
+       g_return_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector));
+
+       captive_vfs_parent_object=captive_parent_connector_get_captive_vfs_parent_object(captive_parent_connector);
+
+       if (g_object_get_data(G_OBJECT(captive_vfs_parent_object),CAPTIVE_PARENT_CONNECTOR_VFS_SIGNALS_CONNECTED))
+               return;
+
+       g_object_ref(captive_vfs_parent_object);
+
+       g_signal_connect(captive_vfs_parent_object,"detach",
+                       G_CALLBACK(captive_parent_connector_vfs_detach),captive_parent_connector);      /* c_handler,data */
+       g_signal_connect(captive_vfs_parent_object,"cease",
+                       G_CALLBACK(captive_parent_connector_vfs_cease),captive_parent_connector);       /* c_handler,data */
+       g_signal_connect(captive_vfs_parent_object,"abort",
+                       G_CALLBACK(captive_parent_connector_vfs_abort),captive_parent_connector);       /* c_handler,data */
+
+       g_object_set_data(G_OBJECT(captive_vfs_parent_object),CAPTIVE_PARENT_CONNECTOR_VFS_SIGNALS_CONNECTED,
+                       GINT_TO_POINTER(TRUE));
+}
+
+static void captive_parent_connector_vfs_signals_disconnect(CaptiveParentConnector *captive_parent_connector)
+{
+CaptiveVfsParentObject *captive_vfs_parent_object;
+
+       g_return_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector));
+
+       captive_vfs_parent_object=captive_parent_connector_get_captive_vfs_parent_object(captive_parent_connector);
+
+       if (!g_object_get_data(G_OBJECT(captive_vfs_parent_object),CAPTIVE_PARENT_CONNECTOR_VFS_SIGNALS_CONNECTED))
+               return;
+
+       g_signal_handlers_disconnect_by_func(captive_vfs_parent_object,
+                       G_CALLBACK(captive_parent_connector_vfs_detach),captive_parent_connector);      /* func,data */
+       g_signal_handlers_disconnect_by_func(captive_vfs_parent_object,
+                       G_CALLBACK(captive_parent_connector_vfs_cease),captive_parent_connector);       /* func,data */
+       g_signal_handlers_disconnect_by_func(captive_vfs_parent_object,
+                       G_CALLBACK(captive_parent_connector_vfs_abort),captive_parent_connector);       /* func,data */
+
+       g_object_unref(captive_vfs_parent_object);
+
+       g_object_set_data(G_OBJECT(captive_vfs_parent_object),CAPTIVE_PARENT_CONNECTOR_VFS_SIGNALS_CONNECTED,
+                       GINT_TO_POINTER(FALSE));
+}
+
+void captive_parent_connector_init(CaptiveParentConnector *captive_parent_connector,
+               CORBA_Object *corba_objectp,CaptiveVfsParentObject *captive_vfs_parent_object)
+{
+       g_return_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector));
+       g_return_if_fail(corba_objectp!=NULL);
+       g_return_if_fail(/* CORBA_Object_is_nil() */ *corba_objectp==CORBA_OBJECT_NIL);
+       g_return_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object));
+
+       g_object_set_data(G_OBJECT(captive_parent_connector),CAPTIVE_PARENT_CONNECTOR_CORBA_OBJECTP,
+                       corba_objectp);
+       g_object_set_data(G_OBJECT(captive_parent_connector),CAPTIVE_PARENT_CONNECTOR_CAPTIVE_VFS_PARENT_OBJECT,
+                       captive_vfs_parent_object);
+       g_object_set_data(G_OBJECT(captive_parent_connector),CAPTIVE_PARENT_CONNECTOR_DIRTY,
+                       GINT_TO_POINTER(FALSE));
+
+       g_assert(captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_DISCONNECTED_OR_CLOSED));
+}
+
+
+void captive_parent_connector_finalize(CaptiveParentConnector *captive_parent_connector)
+{
+       g_return_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector));
+
+       g_assert(captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_DISCONNECTED_OR_CLOSED));
+
+       captive_parent_connector_vfs_signals_disconnect(captive_parent_connector);
+}
+
+
+GnomeVFSResult captive_parent_connector_connect(CaptiveParentConnector *captive_parent_connector)
+{
+GnomeVFSResult r;
+
+       g_return_val_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector),GNOME_VFS_ERROR_BAD_PARAMETERS);
+
+       if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_DISCONNECTED)) {
+               if (GNOME_VFS_OK!=(r=captive_vfs_parent_object_connect(
+                               captive_parent_connector_get_captive_vfs_parent_object(captive_parent_connector))))
+                       return r;
+               g_assert(captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED_CLEAN));
+               }
+
+       /**/ if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_DISCONNECTED))
+               g_assert_not_reached();
+       else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_BROKEN))
+               return GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE;
+       else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED))
+               return GNOME_VFS_OK;
+       else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_OPENED))
+               return GNOME_VFS_OK;
+       else g_assert_not_reached();
+
+       /* NOTREACHED */
+       return GNOME_VFS_ERROR_INTERNAL;
+}
+
+
+GnomeVFSResult captive_parent_connector_open(CaptiveParentConnector *captive_parent_connector)
+{
+GnomeVFSResult r;
+
+       g_return_val_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector),GNOME_VFS_ERROR_BAD_PARAMETERS);
+
+       if (GNOME_VFS_OK!=(r=captive_parent_connector_connect(captive_parent_connector)))
+               return r;
+
+       if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED)) {
+               if (GNOME_VFS_OK!=(r=(*CAPTIVE_PARENT_CONNECTOR_GET_IFACE(captive_parent_connector)->open)(captive_parent_connector)))
+                       return r;
+               g_assert(captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_OPENED));
+               }
+
+       /**/ if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_DISCONNECTED))
+               g_assert_not_reached();
+       else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_BROKEN))
+               g_assert_not_reached();
+       else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED))
+               g_assert_not_reached();
+       else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_OPENED))
+               return GNOME_VFS_OK;
+       else g_assert_not_reached();
+
+       /* NOTREACHED */
+       return GNOME_VFS_ERROR_INTERNAL;
+}
+
+
+GnomeVFSResult captive_parent_connector_close(CaptiveParentConnector *captive_parent_connector)
+{
+GnomeVFSResult r;
+
+       g_return_val_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector),GNOME_VFS_ERROR_BAD_PARAMETERS);
+
+       if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_OPENED)) {
+               if (GNOME_VFS_OK!=(r=(*CAPTIVE_PARENT_CONNECTOR_GET_IFACE(captive_parent_connector)->close)(captive_parent_connector)))
+                       return r;
+               g_assert(captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED));
+               }
+
+       /**/ if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_DISCONNECTED))
+               return GNOME_VFS_OK;
+       else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_BROKEN))
+               return GNOME_VFS_OK;
+       else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED))
+               return GNOME_VFS_OK;
+       else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_OPENED))
+               g_assert_not_reached();
+       else g_assert_not_reached();
+
+       /* NOTREACHED */
+       return GNOME_VFS_ERROR_INTERNAL;
+}
+
+
+void captive_parent_connector_set_dirty(CaptiveParentConnector *captive_parent_connector)
+{
+       g_return_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector));
+
+       g_return_if_fail(captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_OPENED));
+
+       g_object_set_data(G_OBJECT(captive_parent_connector),CAPTIVE_PARENT_CONNECTOR_DIRTY,
+                       GINT_TO_POINTER(TRUE));
+}
+
+
+static GnomeVFSResult captive_parent_connector_handler_open(CaptiveParentConnector *captive_parent_connector)
+{
+       g_return_val_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector),GNOME_VFS_ERROR_BAD_PARAMETERS);
+
+       /* Handler should have 'opened' us. */
+
+       /**/ if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_DISCONNECTED))
+               g_assert_not_reached();
+       else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_BROKEN))
+               g_assert_not_reached();
+       else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED))
+               g_assert_not_reached(); /* Parent handler failed. */
+       else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_OPENED)) {
+               captive_parent_connector_vfs_signals_connect(captive_parent_connector);
+               return GNOME_VFS_OK;
+               }
+       else g_assert_not_reached();
+
+       /* NOTREACHED */
+       return GNOME_VFS_ERROR_INTERNAL;
+}
+
+
+static GnomeVFSResult captive_parent_connector_handler_close(CaptiveParentConnector *captive_parent_connector)
+{
+       g_return_val_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector),GNOME_VFS_ERROR_BAD_PARAMETERS);
+
+       /* Handler should have 'closed' us. */
+
+       /**/ if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_DISCONNECTED)) {
+               captive_parent_connector_vfs_signals_disconnect(captive_parent_connector);
+               return GNOME_VFS_OK;
+               }
+       else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_BROKEN)) {
+               captive_parent_connector_vfs_signals_disconnect(captive_parent_connector);
+               return GNOME_VFS_OK;
+               }
+       else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED))
+               return GNOME_VFS_OK;
+       else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_OPENED))
+               g_assert_not_reached();
+       else g_assert_not_reached();
+
+       /* NOTREACHED */
+       return GNOME_VFS_ERROR_INTERNAL;
+}
+
+
+CaptiveVfsParentObject *captive_parent_connector_get_captive_vfs_parent_object
+               (CaptiveParentConnector *captive_parent_connector)
+{
+CaptiveVfsParentObject *r;
+
+       g_return_val_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector),NULL);
+
+       r=g_object_get_data(G_OBJECT(captive_parent_connector),CAPTIVE_PARENT_CONNECTOR_CAPTIVE_VFS_PARENT_OBJECT);
+       g_assert(CAPTIVE_VFS_PARENT_IS_OBJECT(r));
+
+       return r;
+}
+
+
+CORBA_Object captive_parent_connector_get_corba_object(CaptiveParentConnector *captive_parent_connector)
+{
+CORBA_Object *rp;
+
+       g_return_val_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector),NULL);
+
+       rp=g_object_get_data(G_OBJECT(captive_parent_connector),CAPTIVE_PARENT_CONNECTOR_CORBA_OBJECTP);
+       g_assert(rp!=NULL);
+       /* '*rp' may be NULL */
+
+       return *rp;
+}
+
+
+gboolean captive_parent_connector_get_dirty(CaptiveParentConnector *captive_parent_connector)
+{
+gpointer r_gpointer;
+gint r_gint;
+
+       g_return_val_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector),FALSE);
+
+       r_gpointer=g_object_get_data(G_OBJECT(captive_parent_connector),CAPTIVE_PARENT_CONNECTOR_DIRTY);
+       r_gint=GPOINTER_TO_INT(r_gpointer);
+       g_assert(r_gint==TRUE || r_gint==FALSE);
+
+       return r_gint;
+}
+
+
+gboolean captive_parent_connector_is_state(CaptiveParentConnector *captive_parent_connector,
+               CaptiveParentConnectorFlagWant vfs_want,
+               CaptiveParentConnectorFlagWant corba_object_want,CaptiveParentConnectorFlagWant dirty_want)
+{
+       g_return_val_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector),FALSE);
+
+       if (vfs_want!=CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ANY) {
+CaptiveVfsParentObject *captive_vfs_parent_object;
+
+               captive_vfs_parent_object=captive_parent_connector_get_captive_vfs_parent_object(captive_parent_connector);
+               if ((vfs_want==CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ON)!=
+                               (/* !CORBA_Object_is_nil() */ captive_vfs_parent_object->corba_Vfs_object!=CORBA_OBJECT_NIL))
+                       return FALSE;
+               }
+       if (corba_object_want!=CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ANY) {
+CORBA_Object corba_object;
+
+               corba_object=captive_parent_connector_get_corba_object(captive_parent_connector);
+               if ((corba_object_want==CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ON)!=
+                               (/* !CORBA_Object_is_nil() */ corba_object!=CORBA_OBJECT_NIL))
+                       return FALSE;
+               }
+       if (dirty_want!=CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ANY) {
+gboolean dirty;
+
+               dirty=captive_parent_connector_get_dirty(captive_parent_connector);
+               if ((dirty_want==CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ON)!=dirty)
+                       return FALSE;
+               }
+
+       return TRUE;
+}
diff --git a/src/libcaptive/client/parent-connector.h b/src/libcaptive/client/parent-connector.h
new file mode 100644 (file)
index 0000000..7640105
--- /dev/null
@@ -0,0 +1,113 @@
+/* $Id$
+ * Include file for fs object sandbox parents reconnections to their sandbox slave peers
+ * Copyright (C) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; exactly version 2 of June 1991 is required
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _CAPTIVE_CLIENT_PRIV_PARENT_CONNECTOR_H
+#define _CAPTIVE_CLIENT_PRIV_PARENT_CONNECTOR_H 1
+
+
+#include <glib/gmacros.h>
+#include <glib/gtypes.h>
+#include <glib-object.h>
+#include <orbit/orb-core/corba-defs.h>
+#include "vfs-parent.h"
+
+
+G_BEGIN_DECLS
+
+#define CAPTIVE_TYPE_PARENT_CONNECTOR           (captive_parent_connector_get_type ())
+#define CAPTIVE_PARENT_CONNECTOR(obj)           (G_TYPE_CHECK_INSTANCE_CAST ((obj), CAPTIVE_TYPE_PARENT_CONNECTOR, CaptiveParentConnector))
+#define CAPTIVE_PARENT_CONNECTOR_CLASS(obj)     (G_TYPE_CHECK_CLASS_CAST ((obj), CAPTIVE_TYPE_PARENT_CONNECTOR, CaptiveParentConnectorIface))
+#define CAPTIVE_IS_PARENT_CONNECTOR(obj)        (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CAPTIVE_TYPE_PARENT_CONNECTOR))
+#define CAPTIVE_IS_PARENT_CONNECTOR_CLASS(obj)  (G_TYPE_CHECK_CLASS_TYPE ((obj), CAPTIVE_TYPE_PARENT_CONNECTOR))
+#define CAPTIVE_PARENT_CONNECTOR_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), CAPTIVE_TYPE_PARENT_CONNECTOR, CaptiveParentConnectorIface))
+typedef struct _CaptiveParentConnector      CaptiveParentConnector;
+typedef struct _CaptiveParentConnectorIface CaptiveParentConnectorIface;
+
+
+GType captive_parent_connector_get_type(void);
+
+struct _CaptiveParentConnectorIface {
+       GTypeInterface g_iface;
+
+       GnomeVFSResult (*open)(CaptiveParentConnector *captive_parent_connector);
+       GnomeVFSResult (*close)(CaptiveParentConnector *captive_parent_connector);
+       };
+
+typedef enum captive_parent_connector_flag_want {
+       CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ON,
+       CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_OFF,
+       CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ANY,
+       } CaptiveParentConnectorFlagWant;
+
+#define CAPTIVE_PARENT_CONNECTOR_FLAGS_DISCONNECTED \
+               CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_OFF, /* vfs */ \
+               CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_OFF, /* corba_object */ \
+               CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_OFF  /* dirty */
+#define CAPTIVE_PARENT_CONNECTOR_FLAGS_BROKEN \
+               CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_OFF, /* vfs */ \
+               CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_OFF, /* corba_object */ \
+               CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ON   /* dirty */
+#define CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED \
+               CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ON,  /* vfs */ \
+               CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_OFF, /* corba_object */ \
+               CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ANY  /* dirty */
+#define CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED_CLEAN \
+               CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ON,  /* vfs */ \
+               CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_OFF, /* corba_object */ \
+               CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_OFF  /* dirty */
+#define CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED_DIRTY \
+               CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ON,  /* vfs */ \
+               CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_OFF, /* corba_object */ \
+               CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ON   /* dirty */
+#define CAPTIVE_PARENT_CONNECTOR_FLAGS_DISCONNECTED_OR_CLOSED \
+               CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ANY, /* vfs */ \
+               CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_OFF, /* corba_object */ \
+               CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_OFF  /* dirty */
+#define CAPTIVE_PARENT_CONNECTOR_FLAGS_OPENED \
+               CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ON,  /* vfs */ \
+               CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ON,  /* corba_object */ \
+               CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ANY  /* dirty */
+#define CAPTIVE_PARENT_CONNECTOR_FLAGS_OPENED_CLEAN \
+               CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ON,  /* vfs */ \
+               CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ON,  /* corba_object */ \
+               CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_OFF  /* dirty */
+#define CAPTIVE_PARENT_CONNECTOR_FLAGS_OPENED_DIRTY \
+               CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ON,  /* vfs */ \
+               CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ON,  /* corba_object */ \
+               CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ON   /* dirty */
+
+void captive_parent_connector_init(CaptiveParentConnector *captive_parent_connector,
+                       CORBA_Object *corba_objectp,CaptiveVfsParentObject *captive_vfs_parent_object);
+void captive_parent_connector_finalize(CaptiveParentConnector *captive_parent_connector);
+GnomeVFSResult captive_parent_connector_connect(CaptiveParentConnector *captive_parent_connector);
+GnomeVFSResult captive_parent_connector_open(CaptiveParentConnector *captive_parent_connector);
+GnomeVFSResult captive_parent_connector_close(CaptiveParentConnector *captive_parent_connector);
+void captive_parent_connector_set_dirty(CaptiveParentConnector *captive_parent_connector);
+CaptiveVfsParentObject *captive_parent_connector_get_captive_vfs_parent_object
+               (CaptiveParentConnector *captive_parent_connector);
+CORBA_Object captive_parent_connector_get_corba_object(CaptiveParentConnector *captive_parent_connector);
+gboolean captive_parent_connector_get_dirty(CaptiveParentConnector *captive_parent_connector);
+gboolean captive_parent_connector_is_state(CaptiveParentConnector *captive_parent_connector,
+               CaptiveParentConnectorFlagWant vfs_want,
+               CaptiveParentConnectorFlagWant corba_object_want,CaptiveParentConnectorFlagWant dirty_want);
+
+G_END_DECLS
+
+
+#endif /* _CAPTIVE_CLIENT_PRIV_PARENT_CONNECTOR_H */
index c2f1ef8..734295d 100644 (file)
 #include "../sandbox/parent-Vfs.h"
 #include "directory-parent.h"
 #include "file-parent.h"
+#include "marshallers.h"
 
 
 static gpointer captive_vfs_parent_object_parent_class=NULL;
 
 
 static GnomeVFSResult captive_vfs_parent_init(CaptiveVfsObject *captive_vfs_object);
+static void captive_vfs_parent_object_handler_detach(CaptiveVfsParentObject *captive_vfs_parent_object);
+static void captive_vfs_parent_object_handler_cease(CaptiveVfsParentObject *captive_vfs_parent_object);
+static void captive_vfs_parent_object_handler_abort(CaptiveVfsParentObject *captive_vfs_parent_object);
 static GnomeVFSResult captive_vfs_parent_close(CaptiveVfsObject *captive_vfs_object);
 static GnomeVFSResult captive_vfs_parent_commit(CaptiveVfsObject *captive_vfs_object);
 static GnomeVFSResult captive_vfs_parent_volume_info_get
@@ -64,6 +68,34 @@ CaptiveVfsObjectClass *captive_vfs_object_class=CAPTIVE_VFS_OBJECT_CLASS(class);
 
        captive_vfs_object_class->file_new_open=captive_file_parent_new_open;
        captive_vfs_object_class->file_new_create=captive_file_parent_new_create;
+
+       class->detach=captive_vfs_parent_object_handler_detach;
+       g_signal_new(
+                       "detach",       /* signal_name */
+                       G_TYPE_FROM_CLASS(class),       /* itype */
+                       G_SIGNAL_RUN_LAST,      /* signal_flags */
+                       G_STRUCT_OFFSET(CaptiveVfsParentObjectClass,detach),    /* class_offset */
+                       NULL,NULL,      /* accumulator,accu_data */
+                       captive_client_VOID__VOID,      /* c_marshaller */
+                       G_TYPE_NONE,0); /* return_type,n_params */
+       class->cease=captive_vfs_parent_object_handler_cease;
+       g_signal_new(
+                       "cease",        /* signal_name */
+                       G_TYPE_FROM_CLASS(class),       /* itype */
+                       G_SIGNAL_RUN_LAST,      /* signal_flags */
+                       G_STRUCT_OFFSET(CaptiveVfsParentObjectClass,cease),     /* class_offset */
+                       NULL,NULL,      /* accumulator,accu_data */
+                       captive_client_VOID__VOID,      /* c_marshaller */
+                       G_TYPE_NONE,0); /* return_type,n_params */
+       class->abort=captive_vfs_parent_object_handler_abort;
+       g_signal_new(
+                       "abort",        /* signal_name */
+                       G_TYPE_FROM_CLASS(class),       /* itype */
+                       G_SIGNAL_RUN_LAST,      /* signal_flags */
+                       G_STRUCT_OFFSET(CaptiveVfsParentObjectClass,abort),     /* class_offset */
+                       NULL,NULL,      /* accumulator,accu_data */
+                       captive_client_VOID__VOID,      /* c_marshaller */
+                       G_TYPE_NONE,0); /* return_type,n_params */
 }
 
 
@@ -72,6 +104,22 @@ static void captive_vfs_parent_object_init(CaptiveVfsParentObject *captive_vfs_p
        captive_vfs_parent_object->corba_parent_giochanel_blind=NULL;
 }
 
+       
+static void captive_vfs_parent_object_handler_detach(CaptiveVfsParentObject *captive_vfs_parent_object)
+{
+       g_return_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object));
+}
+
+static void captive_vfs_parent_object_handler_cease(CaptiveVfsParentObject *captive_vfs_parent_object)
+{
+       g_return_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object));
+}
+
+static void captive_vfs_parent_object_handler_abort(CaptiveVfsParentObject *captive_vfs_parent_object)
+{
+       g_return_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object));
+}
+
 
 GType captive_vfs_parent_object_get_type(void)
 {
@@ -113,24 +161,42 @@ CaptiveVfsParentObject *captive_vfs_parent_object;
 static GnomeVFSResult captive_vfs_parent_close(CaptiveVfsObject *captive_vfs_object)
 {
 CaptiveVfsParentObject *captive_vfs_parent_object;
+GnomeVFSResult r;
 
        g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
 
        captive_vfs_parent_object=CAPTIVE_VFS_PARENT_OBJECT(captive_vfs_object);
 
-       return captive_sandbox_parent_vfs_close(captive_vfs_parent_object);
+       if (captive_vfs_parent_object->corba_Vfs_object!=CORBA_OBJECT_NIL) {
+               r=captive_sandbox_parent_vfs_close(captive_vfs_parent_object);
+               g_assert(captive_vfs_parent_object->corba_Vfs_object==CORBA_OBJECT_NIL);
+               }
+       else
+               r=GNOME_VFS_OK;
+
+       return r;
 }
 
 
 static GnomeVFSResult captive_vfs_parent_commit(CaptiveVfsObject *captive_vfs_object)
 {
 CaptiveVfsParentObject *captive_vfs_parent_object;
+GnomeVFSResult r;
+gint retried=0;
 
        g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
 
        captive_vfs_parent_object=CAPTIVE_VFS_PARENT_OBJECT(captive_vfs_object);
 
-       return captive_sandbox_parent_vfs_commit(captive_vfs_parent_object);
+       do {
+               if (captive_vfs_parent_object->corba_Vfs_object==CORBA_OBJECT_NIL
+                               && GNOME_VFS_OK!=(r=captive_vfs_parent_object_connect(captive_vfs_parent_object)))
+                       return r;
+               if (GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE
+                               !=(r=captive_sandbox_parent_vfs_commit(captive_vfs_parent_object)))
+                       return r;
+               } while (!retried++);
+       return r;
 }
 
 
@@ -138,11 +204,89 @@ static GnomeVFSResult captive_vfs_parent_volume_info_get
                (CaptiveVfsObject *captive_vfs_object,CaptiveVfsVolumeInfo *volume_info)
 {
 CaptiveVfsParentObject *captive_vfs_parent_object;
+GnomeVFSResult r;
+gint retried=0;
 
        g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(volume_info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
        captive_vfs_parent_object=CAPTIVE_VFS_PARENT_OBJECT(captive_vfs_object);
 
-       return captive_sandbox_parent_vfs_volume_info_get(captive_vfs_parent_object,volume_info);
+       do {
+               if (captive_vfs_parent_object->corba_Vfs_object==CORBA_OBJECT_NIL
+                               && GNOME_VFS_OK!=(r=captive_vfs_parent_object_connect(captive_vfs_parent_object)))
+                       return r;
+               if (GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE
+                               !=(r=captive_sandbox_parent_vfs_volume_info_get(captive_vfs_parent_object,volume_info)))
+                       return r;
+               } while (!retried++);
+       return r;
+}
+
+
+GnomeVFSResult captive_vfs_parent_object_connect(CaptiveVfsParentObject *captive_vfs_parent_object)
+{
+       g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
+
+       g_return_val_if_fail(captive_vfs_parent_object->corba_Vfs_object==CORBA_OBJECT_NIL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+
+       return captive_sandbox_parent_vfs_new(captive_vfs_parent_object);
+}
+
+
+GnomeVFSResult captive_vfs_parent_object_disconnect(CaptiveVfsParentObject *captive_vfs_parent_object)
+{
+GnomeVFSResult r;
+
+       g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
+
+       g_return_val_if_fail(captive_vfs_parent_object->corba_Vfs_object!=CORBA_OBJECT_NIL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+
+       /* Detach all connectors: */
+       g_signal_emit_by_name(captive_vfs_parent_object,"detach");
+
+       /* Some connector detaching broke the connection? */
+       if (captive_vfs_parent_object->corba_Vfs_object==CORBA_OBJECT_NIL) {
+               /* "abort" should have been emitted by captive_vfs_parent_object_aborted() */
+               return GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE;
+               }
+
+       if (GNOME_VFS_OK!=(r=captive_sandbox_parent_vfs_close(captive_vfs_parent_object))) {
+               /* Some non-ORBit shutdown error may have occured: */
+               g_signal_emit_by_name(captive_vfs_parent_object,"abort");
+               return r;
+               }
+
+       /* success: */
+       g_signal_emit_by_name(captive_vfs_parent_object,"cease");
+
+       return GNOME_VFS_OK;
+}
+
+
+GnomeVFSResult captive_vfs_parent_object_aborted(CaptiveVfsParentObject *captive_vfs_parent_object)
+{
+static gint inside=0;
+GnomeVFSResult r;
+
+       g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
+
+       g_return_val_if_fail(captive_vfs_parent_object->corba_Vfs_object!=CORBA_OBJECT_NIL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+
+       /* Prevent looping by COMM_FAILURE of 'unmount' operation
+        * by captive_sandbox_parent_vfs_close().
+        */
+       g_assert(inside>=0);
+       if (inside)
+               return GNOME_VFS_OK;
+       inside++;
+
+       g_signal_emit_by_name(captive_vfs_parent_object,"abort");
+
+       r=captive_sandbox_parent_vfs_close(captive_vfs_parent_object);
+
+       g_assert(inside==1);
+       inside--;
+
+       return r;
 }
index c340133..2adf94a 100644 (file)
@@ -66,8 +66,17 @@ struct _CaptiveVfsParentObject {
        };
 struct _CaptiveVfsParentObjectClass {
        CaptiveVfsObjectClass parent_class;
+
+       /* signals */
+       void (*detach)(CaptiveVfsParentObject *captive_vfs_parent_object);
+       void (*cease)(CaptiveVfsParentObject *captive_vfs_parent_object);
+       void (*abort)(CaptiveVfsParentObject *captive_vfs_parent_object);
        };
 
+GnomeVFSResult captive_vfs_parent_object_connect(CaptiveVfsParentObject *captive_vfs_parent_object);
+GnomeVFSResult captive_vfs_parent_object_disconnect(CaptiveVfsParentObject *captive_vfs_parent_object);
+GnomeVFSResult captive_vfs_parent_object_aborted(CaptiveVfsParentObject *captive_vfs_parent_object);
+
 G_END_DECLS
 
 
index ad5abdd..a18c0eb 100644 (file)
@@ -59,7 +59,7 @@ Captive_Bytes *buffer_corba;
        *bytes_read_return=0;
 
        Captive_CaptiveIOChannel_read(captive_io_channel->corba_captive_io_channel,&buffer_corba,count,&captive_corba_ev);
-       if (GNOME_VFS_OK!=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev))
+       if (GNOME_VFS_OK!=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,NULL))
                return G_IO_STATUS_ERROR;
 
        g_return_val_if_fail(buffer_corba->_length<=count,G_IO_STATUS_ERROR);
@@ -93,7 +93,7 @@ Captive_GSize bytes_written_corba;
 
        Captive_CaptiveIOChannel_write(captive_io_channel->corba_captive_io_channel,
                        &buffer_corba_local,&bytes_written_corba,&captive_corba_ev);
-       if (GNOME_VFS_OK!=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev))
+       if (GNOME_VFS_OK!=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,NULL))
                return G_IO_STATUS_ERROR;
 
        *bytes_written_return=bytes_written_corba;
@@ -109,7 +109,7 @@ struct captive_io_channel *captive_io_channel=(struct captive_io_channel *)chann
        g_return_val_if_fail(validate_captive_io_channel(captive_io_channel),G_IO_STATUS_ERROR);
 
        Captive_CaptiveIOChannel_seek(captive_io_channel->corba_captive_io_channel,offset,type,&captive_corba_ev);
-       if (GNOME_VFS_OK!=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev))
+       if (GNOME_VFS_OK!=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,NULL))
                return G_IO_STATUS_ERROR;
 
        return G_IO_STATUS_NORMAL;
@@ -223,7 +223,7 @@ struct captive_io_channel *captive_io_channel;
        captive_io_channel=(struct captive_io_channel *)giochannel;
 
        *size_return=Captive_CaptiveIOChannel_size(captive_io_channel->corba_captive_io_channel,&captive_corba_ev);
-       if (GNOME_VFS_OK!=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev))
+       if (GNOME_VFS_OK!=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,NULL))
                return FALSE;
 
        return TRUE;
index 9a06079..37743f0 100644 (file)
 
 
 GnomeVFSResult captive_sandbox_parent_directory_new_open
-               (CaptiveDirectoryParentObject *captive_directory_parent_object,const gchar *pathname)
+               (CaptiveDirectoryParentObject *captive_directory_parent_object)
 {
-gboolean retried=FALSE;
-xmlNode *xml_action;
+xmlNode *xml_action=NULL;
 CaptiveVfsParentObject *captive_vfs_parent_object;
+GnomeVFSResult r;
+Captive_Directory corba_Directory_object;
 
        g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
-       g_return_val_if_fail(pathname!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+       g_return_val_if_fail(captive_directory_parent_object->pathname!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
        captive_vfs_parent_object=CAPTIVE_VFS_PARENT_OBJECT(CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object)->vfs);
 
-retry:
-       xml_action=NULL;
        if (captive_vfs_parent_object->corba_bug_action) {
                xml_action=xmlNewTextChild(captive_vfs_parent_object->corba_bug_action,NULL,"directory_new_open",NULL);
                xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_directory_parent_object));
-               xmlNewProp(xml_action,"pathname",pathname);
+               xmlNewProp(xml_action,"pathname",captive_directory_parent_object->pathname);
                }
 
-       captive_directory_parent_object->corba_Directory_object=Captive_Vfs_directory_new_open(
-                       captive_vfs_parent_object->corba_Vfs_object,pathname,&captive_corba_ev);
+       corba_Directory_object=Captive_Vfs_directory_new_open(
+                       captive_vfs_parent_object->corba_Vfs_object,captive_directory_parent_object->pathname,&captive_corba_ev);
        if (xml_action)
                xmlNewProp(xml_action,"result",(captive_corba_ev._major==CORBA_NO_EXCEPTION ? "1" : "0"));
+       /* If 'r' means failure 'corba_Directory_object' may not be 'CORBA_OBJECT_NIL'
+        * although it is not valid 'CORBA_Object' to be passed to CORBA_Object_release().
+        */
+       if (GNOME_VFS_OK!=(r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object)))
+               return r;
 
-       if (!retried && captive_sandbox_parent_query_vfs_retry(&captive_corba_ev,captive_vfs_parent_object)) {
-               retried=TRUE;
-               goto retry;
-               }
-
-       return captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       captive_directory_parent_object->corba_Directory_object=corba_Directory_object;
+       return GNOME_VFS_OK;
 }
 
 
 GnomeVFSResult captive_sandbox_parent_directory_new_make
-               (CaptiveDirectoryParentObject *captive_directory_parent_object,const gchar *pathname,guint perm)
+               (CaptiveDirectoryParentObject *captive_directory_parent_object,guint perm)
 {
-gboolean retried=FALSE;
-xmlNode *xml_action;
+xmlNode *xml_action=NULL;
 CaptiveVfsParentObject *captive_vfs_parent_object;
+GnomeVFSResult r;
+Captive_Directory corba_Directory_object;
 
        g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
-       g_return_val_if_fail(pathname!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+       g_return_val_if_fail(captive_directory_parent_object->pathname!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
        captive_vfs_parent_object=CAPTIVE_VFS_PARENT_OBJECT(CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object)->vfs);
 
-retry:
-       xml_action=NULL;
        if (captive_vfs_parent_object->corba_bug_action) {
                xml_action=xmlNewTextChild(captive_vfs_parent_object->corba_bug_action,NULL,"directory_new_make",NULL);
                xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_directory_parent_object));
-               xmlNewProp(xml_action,"pathname",pathname);
+               xmlNewProp(xml_action,"pathname",captive_directory_parent_object->pathname);
                xmlNewProp(xml_action,"perm",captive_printf_alloca("%u",(unsigned)perm));
                }
 
-       captive_directory_parent_object->corba_Directory_object=Captive_Vfs_directory_new_make(
-                       captive_vfs_parent_object->corba_Vfs_object,pathname,perm,&captive_corba_ev);
+       corba_Directory_object=Captive_Vfs_directory_new_make(
+                       captive_vfs_parent_object->corba_Vfs_object,captive_directory_parent_object->pathname,perm,&captive_corba_ev);
        if (xml_action)
                xmlNewProp(xml_action,"result",(captive_corba_ev._major==CORBA_NO_EXCEPTION ? "1" : "0"));
+       /* If 'r' means failure 'corba_Directory_object' may not be 'CORBA_OBJECT_NIL'
+        * although it is not valid 'CORBA_Object' to be passed to CORBA_Object_release().
+        */
+       if (GNOME_VFS_OK!=(r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object)))
+               return r;
 
-       if (!retried && captive_sandbox_parent_query_vfs_retry(&captive_corba_ev,captive_vfs_parent_object)) {
-               retried=TRUE;
-               goto retry;
-               }
-
-       return captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       captive_directory_parent_object->corba_Directory_object=corba_Directory_object;
+       return GNOME_VFS_OK;
 }
 
 
@@ -115,15 +115,17 @@ CaptiveVfsParentObject *captive_vfs_parent_object;
                }
 
        Captive_Directory_shutdown(captive_directory_parent_object->corba_Directory_object,&captive_corba_ev);
-       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object);
        if (xml_action)
                xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
-       if (r!=GNOME_VFS_OK)
-               return r;
 
+       /* Always clear 'corba_Directory_object' even if 'r' means failure. */
        CORBA_Object_release((CORBA_Object)captive_directory_parent_object->corba_Directory_object,&captive_corba_ev);
        captive_directory_parent_object->corba_Directory_object=CORBA_OBJECT_NIL;
 
+       if (r!=GNOME_VFS_OK)
+               return r;
+
        if (captive_directory_parent_object->corba_Directory_file_info_list) {
 GList *file_info_last_l=g_list_last(captive_directory_parent_object->corba_Directory_file_info_list);
 
@@ -137,7 +139,7 @@ GList *file_info_last_l=g_list_last(captive_directory_parent_object->corba_Direc
                captive_directory_parent_object->corba_Directory_file_info_list=NULL;
                }
 
-       return captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       return captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object);
 }
 
 static GnomeVFSResult captive_sandbox_parent_directory_read_fill1
@@ -159,7 +161,7 @@ CaptiveVfsParentObject *captive_vfs_parent_object;
                }
 
        Captive_Directory_read(captive_directory_parent_object->corba_Directory_object,&file_info_corba,&captive_corba_ev);
-       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object);
        if (xml_action)
                xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
        if (r!=GNOME_VFS_OK)
@@ -262,7 +264,7 @@ CaptiveVfsParentObject *captive_vfs_parent_object;
                }
 
        Captive_Directory_remove(captive_directory_parent_object->corba_Directory_object,&captive_corba_ev);
-       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object);
        if (xml_action)
                xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
        if (r!=GNOME_VFS_OK)
index 38e6e25..483c844 100644 (file)
@@ -30,9 +30,9 @@
 G_BEGIN_DECLS
 
 GnomeVFSResult captive_sandbox_parent_directory_new_open
-               (CaptiveDirectoryParentObject *captive_directory_parent_object,const gchar *pathname);
+               (CaptiveDirectoryParentObject *captive_directory_parent_object);
 GnomeVFSResult captive_sandbox_parent_directory_new_make
-               (CaptiveDirectoryParentObject *captive_directory_parent_object,const gchar *pathname,guint perm);
+               (CaptiveDirectoryParentObject *captive_directory_parent_object,guint perm);
 GnomeVFSResult captive_sandbox_parent_directory_close(CaptiveDirectoryParentObject *captive_directory_parent_object);
 GnomeVFSResult captive_sandbox_parent_directory_read
                (CaptiveDirectoryParentObject *captive_directory_parent_object,GnomeVFSFileInfo *file_info_captive);
index ccc6e6a..ddfefed 100644 (file)
@@ -53,7 +53,7 @@ CaptiveVfsParentObject *captive_vfs_parent_object;
        if (xml_action)
                xmlNewProp(xml_action,"result",(captive_corba_ev._major==CORBA_NO_EXCEPTION ? "1" : "0"));
 
-       return captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       return captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object);
 }
 
 
@@ -82,7 +82,7 @@ CaptiveVfsParentObject *captive_vfs_parent_object;
        if (xml_action)
                xmlNewProp(xml_action,"result",(captive_corba_ev._major==CORBA_NO_EXCEPTION ? "1" : "0"));
 
-       return captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       return captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object);
 }
 
 
@@ -102,7 +102,7 @@ CaptiveVfsParentObject *captive_vfs_parent_object;
                }
 
        Captive_File_shutdown(captive_file_parent_object->corba_File_object,&captive_corba_ev);
-       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object);
        if (xml_action)
                xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
        if (r!=GNOME_VFS_OK)
@@ -111,7 +111,7 @@ CaptiveVfsParentObject *captive_vfs_parent_object;
        CORBA_Object_release((CORBA_Object)captive_file_parent_object->corba_File_object,&captive_corba_ev);
        captive_file_parent_object->corba_File_object=CORBA_OBJECT_NIL;
 
-       return captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       return captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object);
 }
 
 
@@ -145,7 +145,7 @@ CaptiveVfsParentObject *captive_vfs_parent_object;
                        GNOME_VFS_SEEK_START,captive_file_parent_object->offset);
        if (r==GNOME_VFS_OK) {
                Captive_File_read(captive_file_parent_object->corba_File_object,&buffer_corba,num_bytes,&captive_corba_ev);
-               r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+               r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object);
                }
        if (xml_action)
                xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
@@ -201,7 +201,7 @@ CaptiveVfsParentObject *captive_vfs_parent_object;
 
                Captive_File_write(captive_file_parent_object->corba_File_object,
                                &buffer_corba_local,&bytes_written_corba,&captive_corba_ev);
-               r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+               r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object);
                }
        if (xml_action)
                xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
@@ -240,7 +240,7 @@ CaptiveVfsParentObject *captive_vfs_parent_object;
                }
 
        Captive_File_seek(captive_file_parent_object->corba_File_object,whence,offset,&captive_corba_ev);
-       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object);
        if (xml_action)
                xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
        if (r!=GNOME_VFS_OK)
@@ -320,7 +320,7 @@ CaptiveVfsParentObject *captive_vfs_parent_object;
                }
 
        Captive_File_tell(captive_file_parent_object->corba_File_object,&offset_corba,&captive_corba_ev);
-       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object);
        if (xml_action)
                xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
        if (r!=GNOME_VFS_OK)
@@ -382,7 +382,7 @@ CaptiveVfsParentObject *captive_vfs_parent_object;
                }
 
        Captive_File_remove(captive_file_parent_object->corba_File_object,&captive_corba_ev);
-       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object);
        if (xml_action)
                xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
        if (r!=GNOME_VFS_OK)
@@ -411,7 +411,7 @@ CaptiveVfsParentObject *captive_vfs_parent_object;
                }
 
        Captive_File_file_info_get(captive_file_parent_object->corba_File_object,&file_info_corba,&captive_corba_ev);
-       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object);
        if (xml_action)
                xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
        if (r!=GNOME_VFS_OK)
@@ -452,7 +452,7 @@ CaptiveVfsParentObject *captive_vfs_parent_object;
                return r;
 
        Captive_File_file_info_set(captive_file_parent_object->corba_File_object,&file_info_corba,mask,&captive_corba_ev);
-       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object);
        if (xml_action)
                xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
        if (r!=GNOME_VFS_OK)
@@ -481,7 +481,7 @@ CaptiveVfsParentObject *captive_vfs_parent_object;
                }
 
        Captive_File_truncate(captive_file_parent_object->corba_File_object,file_size,&captive_corba_ev);
-       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object);
        if (xml_action)
                xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
        if (r!=GNOME_VFS_OK)
@@ -511,7 +511,7 @@ CaptiveVfsParentObject *captive_vfs_parent_object;
                }
 
        Captive_File_move(captive_file_parent_object_old->corba_File_object,pathname_new,force_replace,&captive_corba_ev);
-       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object);
        if (xml_action)
                xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
        if (r!=GNOME_VFS_OK)
index 648b907..7f90d87 100644 (file)
@@ -42,6 +42,8 @@ gboolean errbool;
 
        g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
 
+       g_return_val_if_fail(captive_vfs_parent_object->corba_Vfs_object==CORBA_OBJECT_NIL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+
        errbool=captive_sandbox_spawn(captive_vfs_parent_object);
        g_return_val_if_fail(errbool==TRUE,GNOME_VFS_ERROR_GENERIC);
 
@@ -55,6 +57,8 @@ GnomeVFSResult r;
 
        g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
 
+       g_return_val_if_fail(captive_vfs_parent_object->corba_Vfs_object==CORBA_OBJECT_NIL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+
        r=captive_sandbox_parent_vfs_new_silent(captive_vfs_parent_object);
 
        if (captive_vfs_parent_object->corba_bug_action) {
@@ -115,11 +119,15 @@ GIOStatus erriostatus;
 
        g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
 
+       g_return_val_if_fail(captive_vfs_parent_object->corba_Vfs_object!=CORBA_OBJECT_NIL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+
        Captive_Vfs_shutdown(captive_vfs_parent_object->corba_Vfs_object,&captive_corba_ev);
-       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object);
 
+       /* Always clear 'corba_Vfs_object' even if 'r' means failure. */
        CORBA_Object_release(captive_vfs_parent_object->corba_Vfs_object,&captive_corba_ev);
        g_assert(validate_CORBA_Environment(&captive_corba_ev));
+       captive_vfs_parent_object->corba_Vfs_object=CORBA_OBJECT_NIL;
 
        /* Shutdown 'GLogFunc' servant. */
        GLogFunc_servant=PortableServer_POA_reference_to_servant(captive_corba_poa,
@@ -188,6 +196,8 @@ GnomeVFSResult captive_sandbox_parent_vfs_close(CaptiveVfsParentObject *captive_
 {
        g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
 
+       g_return_val_if_fail(captive_vfs_parent_object->corba_Vfs_object!=CORBA_OBJECT_NIL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+
        if (captive_vfs_parent_object->corba_bug_action) {
 xmlNode *xml_action;
 
@@ -206,13 +216,18 @@ xmlNode *xml_action=NULL;
 
        g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
 
+       g_return_val_if_fail(captive_vfs_parent_object->corba_Vfs_object!=CORBA_OBJECT_NIL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+
        if (captive_vfs_parent_object->corba_bug_action) {
                xmlNewTextChild(captive_vfs_parent_object->corba_bug_action,NULL,"vfs_commit",NULL);
                xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_vfs_parent_object));
                }
 
-       r_close=captive_sandbox_parent_vfs_close_silent(captive_vfs_parent_object);     /* errors ignored */
-       r_new=captive_sandbox_parent_vfs_new_silent(captive_vfs_parent_object);
+       r_close=captive_vfs_parent_object_disconnect(captive_vfs_parent_object);
+       if (captive_vfs_parent_object->corba_Vfs_object==CORBA_OBJECT_NIL)
+               r_new=captive_vfs_parent_object_connect(captive_vfs_parent_object);
+       else
+               r_new=GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE;
 
        if (captive_vfs_parent_object->corba_bug_action) {
                xml_action=xmlNewTextChild(captive_vfs_parent_object->corba_bug_action,NULL,"vfs_commit",NULL);
@@ -228,16 +243,13 @@ xmlNode *xml_action=NULL;
 GnomeVFSResult captive_sandbox_parent_vfs_volume_info_get
                (CaptiveVfsParentObject *captive_vfs_parent_object,CaptiveVfsVolumeInfo *volume_info_captive)
 {
-xmlNode *xml_action;
+xmlNode *xml_action=NULL;
 Captive_CaptiveVfsVolumeInfo volume_info_corba;
 GnomeVFSResult r;
-gboolean retried=FALSE;
 
        g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(volume_info_captive!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
-retry:
-       xml_action=NULL;
        if (captive_vfs_parent_object->corba_bug_action) {
                xml_action=xmlNewTextChild(captive_vfs_parent_object->corba_bug_action,NULL,"vfs_volume_info_get",NULL);
                xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_vfs_parent_object));
@@ -247,12 +259,7 @@ retry:
        if (xml_action)
                xmlNewProp(xml_action,"result",(captive_corba_ev._major==CORBA_NO_EXCEPTION ? "1" : "0"));
 
-       if (!retried && captive_sandbox_parent_query_vfs_retry(&captive_corba_ev,captive_vfs_parent_object)) {
-               retried=TRUE;
-               goto retry;
-               }
-
-       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object);
        if (xml_action)
                xmlSetProp(xml_action,"result",gnome_vfs_result_to_string(r));
        if (r!=GNOME_VFS_OK)
index 772f7d6..1556462 100644 (file)
@@ -850,15 +850,27 @@ gchar *child_chroot_pid_hashkey_dir;
 }
 
 
-GnomeVFSResult captive_sandbox_parent_return_from_CORBA_Environment(CORBA_Environment *evp)
+GnomeVFSResult captive_sandbox_parent_return_from_CORBA_Environment
+               (CORBA_Environment *evp,CaptiveVfsParentObject *captive_vfs_parent_object)
 {
 GnomeVFSResult r;
 
        if (evp->_major==CORBA_NO_EXCEPTION)
                return GNOME_VFS_OK;
 
-       if (evp->_major==CORBA_USER_EXCEPTION && !strcmp(ex_Captive_GnomeVFSResultException,CORBA_exception_id(evp)))
+       /* If !CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.sandbox_server_argv it is CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.sandbox_server_ior
+        * where we cannot do any restart anyway.
+        */
+       if (captive_vfs_parent_object && CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.sandbox_server_argv
+                       && (evp->_major==CORBA_SYSTEM_EXCEPTION && !strcmp(ex_CORBA_COMM_FAILURE,CORBA_exception_id(evp)))) {
+               r=GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE;
+               if (captive_vfs_parent_object->corba_Vfs_object!=CORBA_OBJECT_NIL)
+                       captive_vfs_parent_object_aborted(captive_vfs_parent_object);   /* errors ignored */
+               }
+       else if (evp->_major==CORBA_USER_EXCEPTION && !strcmp(ex_Captive_GnomeVFSResultException,CORBA_exception_id(evp))) {
                r=((Captive_GnomeVFSResultException *)CORBA_exception_value(evp))->gnome_vfs_result;
+               g_assert(r!=GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE);     /* code reserved for sandbox restarts */
+               }
        else {
                r=GNOME_VFS_ERROR_GENERIC;
                g_warning(_("CORBA Exception occured: id=\"%s\", value=%p"),
@@ -870,31 +882,6 @@ GnomeVFSResult r;
 }
 
 
-gboolean captive_sandbox_parent_query_vfs_retry(CORBA_Environment *evp,CaptiveVfsParentObject *captive_vfs_parent_object)
-{
-GnomeVFSResult errvfsresult;
-gboolean want_retry;
-
-       g_return_val_if_fail(evp!=NULL,FALSE);
-       g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),FALSE);
-
-       /* If !CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.sandbox_server_argv it is CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.sandbox_server_ior
-        * where we cannot do any restart anyway.
-        */
-       want_retry=(CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.sandbox_server_argv
-                       && (evp->_major==CORBA_SYSTEM_EXCEPTION && !strcmp(ex_CORBA_COMM_FAILURE,CORBA_exception_id(evp))));
-       /* Never free 'evp' if returning as no-retry - 'evp' will be reevaluated by the caller! */
-       if (!want_retry)
-               return FALSE;   /* no retry */
-       CORBA_exception_free(evp);
-
-       captive_sandbox_parent_vfs_close(captive_vfs_parent_object);    /* errors ignored */
-       errvfsresult=captive_sandbox_parent_vfs_new(captive_vfs_parent_object);
-
-       return errvfsresult==GNOME_VFS_OK;      /* retry if restart succeeded */
-}
-
-
 void captive_sandbox_child_GnomeVFSResultException_throw(CORBA_Environment *evp,GnomeVFSResult errvfsresult)
 {
 Captive_GnomeVFSResultException *gnome_vfs_result_exception;
index dd46858..b27db01 100644 (file)
@@ -44,9 +44,9 @@ void sandbox_child_shutdown(void);
 #ifdef ORBIT2  /* Prevent missing $(ORBIT_CFLAGS) outside of libcaptive/sandbox/ */
 gboolean captive_sandbox_spawn(CaptiveVfsParentObject *captive_vfs_parent_object);
 gboolean validate_CORBA_Environment(CORBA_Environment *evp);
-GnomeVFSResult captive_sandbox_parent_return_from_CORBA_Environment(CORBA_Environment *evp);
+GnomeVFSResult captive_sandbox_parent_return_from_CORBA_Environment
+               (CORBA_Environment *evp,CaptiveVfsParentObject *captive_vfs_parent_object);
 void captive_sandbox_child_GnomeVFSResultException_throw(CORBA_Environment *evp,GnomeVFSResult errvfsresult);
-gboolean captive_sandbox_parent_query_vfs_retry(CORBA_Environment *evp,CaptiveVfsParentObject *captive_vfs_parent_object);
 #endif
 
 G_END_DECLS