From: short <> Date: Fri, 12 Sep 2003 19:42:35 +0000 (+0000) Subject: Report all dirty objects corrupted by each sandbox crash. X-Git-Tag: captive-0_9~83 X-Git-Url: http://git.jankratochvil.net/?a=commitdiff_plain;h=e5429203bbc0daee778c936e7bfb54a5afa1826f;p=captive.git Report all dirty objects corrupted by each sandbox crash. Fixed 'BROKEN' state to never reincarnate back to 'CLOSED'&'DIRTY' state. --- diff --git a/src/libcaptive/client/parent-connector.c b/src/libcaptive/client/parent-connector.c index e1931ca..3de15e1 100644 --- a/src/libcaptive/client/parent-connector.c +++ b/src/libcaptive/client/parent-connector.c @@ -27,7 +27,8 @@ #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) */ +#define CAPTIVE_PARENT_CONNECTOR_BROKEN "captive_parent_connector-broken" /* GINT_TO_POINTER(0/1) */ +#define CAPTIVE_PARENT_CONNECTOR_SELF_REFS "captive_parent_connector-self_refs" /* GINT_TO_POINTER(count) */ /* @@ -124,14 +125,15 @@ static void captive_parent_connector_vfs_detach(CaptiveVfsParentObject *captive_ { 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)); + g_return_if_fail(NULL==captive_parent_connector_get_captive_vfs_parent_object(captive_parent_connector) + || 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(); + /* NOP */; 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)); @@ -144,7 +146,8 @@ static void captive_parent_connector_vfs_cease(CaptiveVfsParentObject *captive_v { 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)); + g_return_if_fail(NULL==captive_parent_connector_get_captive_vfs_parent_object(captive_parent_connector) + || 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 */; @@ -166,14 +169,25 @@ static void captive_parent_connector_vfs_abort(CaptiveVfsParentObject *captive_v { 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)); + g_return_if_fail(NULL==captive_parent_connector_get_captive_vfs_parent_object(captive_parent_connector) + || 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_CLOSED_DIRTY_OR_OPENED_DIRTY)) + g_warning(_("Filesystem crash broke dirty object: %s"), + (*CAPTIVE_PARENT_CONNECTOR_GET_IFACE(captive_parent_connector)->get_pathname)(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_CLOSED_CLEAN)) + /* NOP */; /* -> DISCONNECTED */ + else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED_DIRTY)) { + /* -> BROKEN */ + /* Ensure to never become VFS-capable Connector from BROKEN state. */ + g_object_set_data(G_OBJECT(captive_parent_connector),CAPTIVE_PARENT_CONNECTOR_BROKEN, + GINT_TO_POINTER(TRUE)); + } 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)); @@ -191,10 +205,8 @@ CaptiveVfsParentObject *captive_vfs_parent_object; 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); + /* Prevent multiple equivalent signal handlers. */ + captive_parent_connector_vfs_signals_disconnect(captive_parent_connector); g_signal_connect(captive_vfs_parent_object,"detach", G_CALLBACK(captive_parent_connector_vfs_detach),captive_parent_connector); /* c_handler,data */ @@ -202,22 +214,17 @@ CaptiveVfsParentObject *captive_vfs_parent_object; 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; +gint self_refs; 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, @@ -225,12 +232,24 @@ CaptiveVfsParentObject *captive_vfs_parent_object; 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)); + /* Do not 'while'-cycle the loop by 1-decreasing as we cannot g_object_get_data() + * on fully unreffed GObject. + */ + if ((self_refs=GPOINTER_TO_INT( + g_object_get_data(G_OBJECT(captive_parent_connector),CAPTIVE_PARENT_CONNECTOR_SELF_REFS)))) { + g_assert(self_refs>0); + g_object_set_data(G_OBJECT(captive_parent_connector),CAPTIVE_PARENT_CONNECTOR_SELF_REFS, + GINT_TO_POINTER(0)); + while (self_refs--) { + /* Undo captive_directory_close() / captive_file_close(): */ + g_object_ref(captive_vfs_parent_object); + /* Cause g_object_last_unref(): */ + g_object_unref(captive_parent_connector); + } + } } + void captive_parent_connector_init(CaptiveParentConnector *captive_parent_connector, CORBA_Object *corba_objectp,CaptiveVfsParentObject *captive_vfs_parent_object) { @@ -246,7 +265,33 @@ void captive_parent_connector_init(CaptiveParentConnector *captive_parent_connec 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)); + g_assert( + captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_DISCONNECTED_OR_CLOSED_CLEAN)); +} + + +/* Abort dispose()? */ +gboolean captive_parent_connector_dispose(CaptiveParentConnector *captive_parent_connector) +{ + g_return_val_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector),FALSE); + + if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED_DIRTY)) { +CaptiveVfsParentObject *captive_vfs_parent_object; + + captive_vfs_parent_object=captive_parent_connector_get_captive_vfs_parent_object(captive_parent_connector); + + /* Cancel g_object_last_unref(): */ + g_object_ref(captive_parent_connector); + /* Simulate captive_directory_close() / captive_file_close(): */ + g_object_unref(captive_vfs_parent_object); + g_object_set_data(G_OBJECT(captive_parent_connector),CAPTIVE_PARENT_CONNECTOR_SELF_REFS, + GINT_TO_POINTER(1+GPOINTER_TO_INT( + g_object_get_data(G_OBJECT(captive_parent_connector),CAPTIVE_PARENT_CONNECTOR_SELF_REFS)))); + return TRUE; /* abort dispose() */ + } + + captive_parent_connector_vfs_signals_disconnect(captive_parent_connector); + return FALSE; /* continue dispose() */ } @@ -254,7 +299,10 @@ void captive_parent_connector_finalize(CaptiveParentConnector *captive_parent_co { 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)); + g_assert(captive_parent_connector_is_state( + captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_DISCONNECTED_OR_BROKEN_OR_CLOSED)); + /* Should have been catched by captive_parent_connector_dispose(): */ + g_assert(!captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED_DIRTY)); captive_parent_connector_vfs_signals_disconnect(captive_parent_connector); } @@ -385,14 +433,10 @@ static GnomeVFSResult captive_parent_connector_handler_close(CaptiveParentConnec /* 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); + /**/ 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)) { - captive_parent_connector_vfs_signals_disconnect(captive_parent_connector); + 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)) @@ -458,13 +502,16 @@ 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)) + (!GPOINTER_TO_INT(g_object_get_data(G_OBJECT(captive_parent_connector),CAPTIVE_PARENT_CONNECTOR_BROKEN)) + && /* !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); + g_assert(!GPOINTER_TO_INT(g_object_get_data(G_OBJECT(captive_parent_connector),CAPTIVE_PARENT_CONNECTOR_BROKEN)) + || corba_object==CORBA_OBJECT_NIL); if ((corba_object_want==CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ON)!= (/* !CORBA_Object_is_nil() */ corba_object!=CORBA_OBJECT_NIL)) return FALSE; @@ -473,6 +520,8 @@ CORBA_Object corba_object; gboolean dirty; dirty=captive_parent_connector_get_dirty(captive_parent_connector); + g_assert(!GPOINTER_TO_INT(g_object_get_data(G_OBJECT(captive_parent_connector),CAPTIVE_PARENT_CONNECTOR_BROKEN)) + || dirty==TRUE); if ((dirty_want==CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ON)!=dirty) return FALSE; }