From 6636408137e0eb9f15348e8a4c5bc1fed5bcbaaa Mon Sep 17 00:00:00 2001 From: short <> Date: Fri, 12 Sep 2003 07:15:14 +0000 Subject: [PATCH] Implemented CaptiveParentConnector sandbox restarts handling GInterface. --- autogen.pl | 1 + src/libcaptive/client/Makefile.am | 26 +- src/libcaptive/client/directory-parent.c | 146 ++++++- src/libcaptive/client/directory-parent.h | 1 + src/libcaptive/client/marshallers.list | 19 + src/libcaptive/client/parent-connector.c | 481 +++++++++++++++++++++++ src/libcaptive/client/parent-connector.h | 113 ++++++ src/libcaptive/client/vfs-parent.c | 150 ++++++- src/libcaptive/client/vfs-parent.h | 9 + src/libcaptive/sandbox/client-CaptiveIOChannel.c | 8 +- src/libcaptive/sandbox/parent-Directory.c | 74 ++-- src/libcaptive/sandbox/parent-Directory.h | 4 +- src/libcaptive/sandbox/parent-File.c | 26 +- src/libcaptive/sandbox/parent-Vfs.c | 33 +- src/libcaptive/sandbox/split.c | 41 +- src/libcaptive/sandbox/split.h | 4 +- 16 files changed, 1024 insertions(+), 112 deletions(-) create mode 100644 src/libcaptive/client/marshallers.list create mode 100644 src/libcaptive/client/parent-connector.c create mode 100644 src/libcaptive/client/parent-connector.h diff --git a/autogen.pl b/autogen.pl index 0b71494..e7d06c1 100755 --- a/autogen.pl +++ b/autogen.pl @@ -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 diff --git a/src/libcaptive/client/Makefile.am b/src/libcaptive/client/Makefile.am index f56cfac..adcc308 100644 --- a/src/libcaptive/client/Makefile.am +++ b/src/libcaptive/client/Makefile.am @@ -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 diff --git a/src/libcaptive/client/directory-parent.c b/src/libcaptive/client/directory-parent.c index 6a473cf..be8970e 100644 --- a/src/libcaptive/client/directory-parent.c +++ b/src/libcaptive/client/directory-parent.c @@ -23,6 +23,7 @@ #include #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; } diff --git a/src/libcaptive/client/directory-parent.h b/src/libcaptive/client/directory-parent.h index a2ab98e..1f3d7be 100644 --- a/src/libcaptive/client/directory-parent.h +++ b/src/libcaptive/client/directory-parent.h @@ -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 index 0000000..0d00eeb --- /dev/null +++ b/src/libcaptive/client/marshallers.list @@ -0,0 +1,19 @@ +# $Id$ +# Mashallers for GObject based CaptiveParentConnector of libcaptive +# Copyright (C) 2003 Jan Kratochvil +# +# 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 index 0000000..e1931ca --- /dev/null +++ b/src/libcaptive/client/parent-connector.c @@ -0,0 +1,481 @@ +/* $Id$ + * fs object sandbox parents reconnections to their sandbox slave peers + * Copyright (C) 2003 Jan Kratochvil + * + * 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 + + +/* 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 + * vfs signal + * vfs signal + * + * 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 + * + * [VFS shutdown] + * [failure] + * [failure] + * + * + * 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 index 0000000..7640105 --- /dev/null +++ b/src/libcaptive/client/parent-connector.h @@ -0,0 +1,113 @@ +/* $Id$ + * Include file for fs object sandbox parents reconnections to their sandbox slave peers + * Copyright (C) 2003 Jan Kratochvil + * + * 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 +#include +#include +#include +#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 */ diff --git a/src/libcaptive/client/vfs-parent.c b/src/libcaptive/client/vfs-parent.c index c2f1ef8..734295d 100644 --- a/src/libcaptive/client/vfs-parent.c +++ b/src/libcaptive/client/vfs-parent.c @@ -25,12 +25,16 @@ #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; } diff --git a/src/libcaptive/client/vfs-parent.h b/src/libcaptive/client/vfs-parent.h index c340133..2adf94a 100644 --- a/src/libcaptive/client/vfs-parent.h +++ b/src/libcaptive/client/vfs-parent.h @@ -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 diff --git a/src/libcaptive/sandbox/client-CaptiveIOChannel.c b/src/libcaptive/sandbox/client-CaptiveIOChannel.c index ad5abdd..a18c0eb 100644 --- a/src/libcaptive/sandbox/client-CaptiveIOChannel.c +++ b/src/libcaptive/sandbox/client-CaptiveIOChannel.c @@ -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; diff --git a/src/libcaptive/sandbox/parent-Directory.c b/src/libcaptive/sandbox/parent-Directory.c index 9a06079..37743f0 100644 --- a/src/libcaptive/sandbox/parent-Directory.c +++ b/src/libcaptive/sandbox/parent-Directory.c @@ -31,71 +31,71 @@ 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) diff --git a/src/libcaptive/sandbox/parent-Directory.h b/src/libcaptive/sandbox/parent-Directory.h index 38e6e25..483c844 100644 --- a/src/libcaptive/sandbox/parent-Directory.h +++ b/src/libcaptive/sandbox/parent-Directory.h @@ -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); diff --git a/src/libcaptive/sandbox/parent-File.c b/src/libcaptive/sandbox/parent-File.c index ccc6e6a..ddfefed 100644 --- a/src/libcaptive/sandbox/parent-File.c +++ b/src/libcaptive/sandbox/parent-File.c @@ -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) diff --git a/src/libcaptive/sandbox/parent-Vfs.c b/src/libcaptive/sandbox/parent-Vfs.c index 648b907..7f90d87 100644 --- a/src/libcaptive/sandbox/parent-Vfs.c +++ b/src/libcaptive/sandbox/parent-Vfs.c @@ -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) diff --git a/src/libcaptive/sandbox/split.c b/src/libcaptive/sandbox/split.c index 772f7d6..1556462 100644 --- a/src/libcaptive/sandbox/split.c +++ b/src/libcaptive/sandbox/split.c @@ -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; diff --git a/src/libcaptive/sandbox/split.h b/src/libcaptive/sandbox/split.h index dd46858..b27db01 100644 --- a/src/libcaptive/sandbox/split.h +++ b/src/libcaptive/sandbox/split.h @@ -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 -- 1.8.3.1