#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) */
/*
{
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));
{
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 */;
{
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));
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 */
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,
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)
{
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() */
}
{
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);
}
/* 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))
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;
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;
}