static void infc_session_proxy_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec) { InfcSessionProxy* session; InfcSessionProxyPrivate* priv; session = INFC_SESSION_PROXY(object); priv = INFC_SESSION_PROXY_PRIVATE(session); switch(prop_id) { case PROP_SESSION: g_value_set_object(value, G_OBJECT(priv->session)); break; case PROP_SUBSCRIPTION_GROUP: g_value_set_boxed(value, priv->subscription_group); break; case PROP_CONNECTION: g_value_set_object(value, G_OBJECT(priv->connection)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } }
static void inf_test_mass_join_subscribe_finished_cb(InfRequest* request, const InfRequestResult* result, const GError* error, gpointer user_data) { InfTestMassJoiner* joiner; const InfBrowserIter* iter; InfSession* session; joiner = (InfTestMassJoiner*)user_data; inf_request_result_get_subscribe_session(result, NULL, &iter, NULL); joiner->session = INFC_SESSION_PROXY( inf_browser_get_session( INF_BROWSER(joiner->browser), iter ) ); g_assert(joiner->session != NULL); g_object_get(G_OBJECT(joiner->session), "session", &session, NULL); switch(inf_session_get_status(session)) { case INF_SESSION_PRESYNC: case INF_SESSION_SYNCHRONIZING: g_signal_connect_after( G_OBJECT(session), "synchronization-failed", G_CALLBACK(inf_test_mass_join_session_synchronization_failed_cb), joiner ); g_signal_connect_after( G_OBJECT(session), "synchronization-complete", G_CALLBACK(inf_test_mass_join_session_synchronization_complete_cb), joiner ); break; case INF_SESSION_RUNNING: inf_test_mass_join_join_user(joiner); break; case INF_SESSION_CLOSED: fprintf( stderr, "Joiner %s: Session closed after subscription\n", joiner->username ); inf_xml_connection_close(infc_browser_get_connection(joiner->browser)); break; } g_object_unref(session); }
static void infc_session_proxy_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec) { InfcSessionProxy* proxy; InfcSessionProxyPrivate* priv; proxy = INFC_SESSION_PROXY(object); priv = INFC_SESSION_PROXY_PRIVATE(proxy); switch(prop_id) { case PROP_SESSION: g_assert(priv->session == NULL); /* construct only */ priv->session = INF_SESSION(g_value_dup_object(value)); g_signal_connect( G_OBJECT(priv->session), "close", G_CALLBACK(infc_session_proxy_session_close_cb), proxy ); g_signal_connect( G_OBJECT(priv->session), "synchronization-complete", G_CALLBACK(infc_session_proxy_session_synchronization_complete_cb), proxy ); g_signal_connect( G_OBJECT(priv->session), "synchronization-failed", G_CALLBACK(infc_session_proxy_session_synchronization_failed_cb), proxy ); break; case PROP_SUBSCRIPTION_GROUP: case PROP_CONNECTION: /* these are read-only because they can only be changed both at once, * refer to infc_session_proxy_set_connection(). */ default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } }
static void infc_session_proxy_init(GTypeInstance* instance, gpointer g_class) { InfcSessionProxy* proxy; InfcSessionProxyPrivate* priv; proxy = INFC_SESSION_PROXY(instance); priv = INFC_SESSION_PROXY_PRIVATE(proxy); priv->session = NULL; priv->subscription_group = NULL; priv->connection = NULL; priv->request_manager = infc_request_manager_new(); }
static void infc_session_proxy_net_object_enqueued(InfNetObject* net_object, InfXmlConnection* connection, xmlNodePtr node) { InfcSessionProxy* proxy; InfcSessionProxyPrivate* priv; proxy = INFC_SESSION_PROXY(net_object); priv = INFC_SESSION_PROXY_PRIVATE(proxy); /* TODO: Don't forward for messages the proxy issued */ g_assert(priv->session != NULL); inf_net_object_enqueued(INF_NET_OBJECT(priv->session), connection, node); }
static void infc_session_proxy_connection_notify_status_cb(InfXmlConnection* connection, GParamSpec* pspec, gpointer user_data) { InfcSessionProxy* proxy; InfXmlConnectionStatus status; proxy = INFC_SESSION_PROXY(user_data); g_object_get(G_OBJECT(connection), "status", &status, NULL); if(status == INF_XML_CONNECTION_CLOSED || status == INF_XML_CONNECTION_CLOSING) { /* Reset connection in case of closure */ infc_session_proxy_release_connection(proxy); } }
static void infc_session_proxy_session_synchronization_complete_cb(InfSession* session, InfXmlConnection* conn, gpointer user_data) { InfcSessionProxy* proxy; InfcSessionProxyPrivate* priv; InfSessionStatus status; proxy = INFC_SESSION_PROXY(user_data); priv = INFC_SESSION_PROXY_PRIVATE(proxy); g_object_get(G_OBJECT(session), "status", &status, NULL); /* There are actually 4 different situations here, depending on status * and priv->connection: * * 1) status == SYNCHRONIZING and priv->connection == NULL * This means that someone synchronized its session to us, but we are not * subscribed to that session. * * 2) status == SYNCHRONIZING and priv->connection != NULL * This means that someone synchronized us and we are subscribed to that * session. * * 3) status == RUNNING and priv->connection == NULL * This means that we synchronized our session to someone else but are * not subscribed to any session. * * 4) status == RUNNING and priv->connection != NULL * This means that we synchronized our session to someone else and are * subscribed to a session (possibly on another host as the one we * synchronized to!). */ if(status == INF_SESSION_SYNCHRONIZING) { if(priv->connection != NULL) { /* The connection that synchronized the session to us should be the * one we subscribed to. */ g_assert(priv->connection == conn); } } }
static void infc_session_proxy_dispose(GObject* object) { InfcSessionProxy* proxy; InfcSessionProxyPrivate* priv; proxy = INFC_SESSION_PROXY(object); priv = INFC_SESSION_PROXY_PRIVATE(proxy); if(priv->connection) infc_session_proxy_unsubscribe_connection(proxy); /* Release session */ if(priv->session != NULL) { g_signal_handlers_disconnect_by_func( G_OBJECT(priv->session), G_CALLBACK(infc_session_proxy_session_close_cb), proxy ); g_signal_handlers_disconnect_by_func( G_OBJECT(priv->session), G_CALLBACK(infc_session_proxy_session_synchronization_complete_cb), proxy ); g_signal_handlers_disconnect_by_func( G_OBJECT(priv->session), G_CALLBACK(infc_session_proxy_session_synchronization_failed_cb), proxy ); g_object_unref(G_OBJECT(priv->session)); priv->session = NULL; } g_object_unref(G_OBJECT(priv->request_manager)); priv->request_manager = NULL; G_OBJECT_CLASS(parent_class)->dispose(object); }
static void infc_session_proxy_session_synchronization_failed_cb(InfSession* session, InfXmlConnection* conn, const GError* error, gpointer user_data) { InfcSessionProxy* proxy; InfcSessionProxyPrivate* priv; InfSessionStatus status; proxy = INFC_SESSION_PROXY(user_data); priv = INFC_SESSION_PROXY_PRIVATE(proxy); g_object_get(G_OBJECT(session), "status", &status, NULL); switch(status) { case INF_SESSION_SYNCHRONIZING: /* When the synchronization failed in synchronizing state, the session * will close itself anyway which is where we do the cleanup in this * case. */ break; case INF_SESSION_RUNNING: /* We do not need to send an explicit session-unsubscribe, because the * failed synchronization should already let the host know that * subscription makes no sense anymore. */ /* If the synchronization failed because the connection was closed, then * the connection might not exist anymore at this point since the * notify::status handler ran before this handler. */ if(priv->connection != NULL) infc_session_proxy_release_connection(proxy); break; case INF_SESSION_CLOSED: default: g_assert_not_reached(); break; } }
static void infc_session_proxy_session_close_cb(InfSession* session, gpointer user_data) { InfcSessionProxy* proxy; InfcSessionProxyPrivate* priv; proxy = INFC_SESSION_PROXY(user_data); priv = INFC_SESSION_PROXY_PRIVATE(proxy); if(priv->connection != NULL) infc_session_proxy_unsubscribe_connection(proxy); /* Don't release session so others can still access */ #if 0 g_signal_handlers_disconnect_by_func( G_OBJECT(priv->session), G_CALLBACK(infc_session_proxy_session_close_cb), proxy ); g_signal_handlers_disconnect_by_func( G_OBJECT(priv->session), G_CALLBACK(infc_session_proxy_session_synchronization_complete_cb), proxy ); g_signal_handlers_disconnect_by_func( G_OBJECT(priv->session), G_CALLBACK(infc_session_proxy_session_synchronization_failed_cb), proxy ); g_object_unref(G_OBJECT(priv->session)); priv->session = NULL; #endif }
static gboolean infc_session_proxy_net_object_received(InfNetObject* net_object, InfXmlConnection* connection, xmlNodePtr node, GError** error) { InfcSessionProxy* proxy; InfcSessionProxyPrivate* priv; InfcSessionProxyClass* proxy_class; InfSessionSyncStatus status; GError* local_error; InfcRequest* request; GError* seq_error; proxy = INFC_SESSION_PROXY(net_object); priv = INFC_SESSION_PROXY_PRIVATE(proxy); proxy_class = INFC_SESSION_PROXY_GET_CLASS(proxy); status = inf_session_get_synchronization_status(priv->session, connection); local_error = NULL; g_assert(status != INF_SESSION_SYNC_NONE || priv->connection == connection); g_assert(inf_session_get_status(priv->session) != INF_SESSION_CLOSED); if(status != INF_SESSION_SYNC_NONE) { /* Direct delegate during synchronization */ return inf_net_object_received( INF_NET_OBJECT(priv->session), connection, node, error ); } else { if(strcmp((const char*)node->name, "user-join") == 0) { infc_session_proxy_handle_user_join( proxy, connection, node, &local_error ); } else if(strcmp((const char*)node->name, "user-rejoin") == 0) { infc_session_proxy_handle_user_rejoin( proxy, connection, node, &local_error ); } else if(strcmp((const char*)node->name, "request-failed") == 0) { infc_session_proxy_handle_request_failed( proxy, connection, node, &local_error ); } else if(strcmp((const char*)node->name, "session-close") == 0) { infc_session_proxy_handle_session_close( proxy, connection, node, &local_error ); } else { return inf_net_object_received( INF_NET_OBJECT(priv->session), connection, node, error ); } } if(local_error != NULL) { /* If the request had a (valid) seq set, we cancel the corresponding * request because the reply could not be processed. */ request = infc_request_manager_get_request_by_xml( priv->request_manager, NULL, node, NULL ); if(request != NULL) { /* If the request had a seq set, we cancel the corresponding request * because the reply could not be processed. */ seq_error = NULL; g_set_error( &seq_error, inf_request_error_quark(), INF_REQUEST_ERROR_REPLY_UNPROCESSED, _("Server reply could not be processed: %s"), local_error->message ); infc_request_manager_fail_request( priv->request_manager, request, seq_error ); g_error_free(seq_error); } g_propagate_error(error, local_error); } /* Don't forward any of the handled messages */ return FALSE; }
void Gobby::UserJoinCommands::on_document_removed(InfBrowser* browser, const InfBrowserIter* iter, InfSessionProxy* proxy, Folder& folder, SessionView& view) { g_assert(proxy != NULL); UserJoinMap::iterator user_iter = m_user_join_map.find(proxy); // If the user join was successful the session is no longer in the map if(user_iter != m_user_join_map.end()) { delete user_iter->second; m_user_join_map.erase(user_iter); } else { // The user has removed the document. What we do now depends // on whether we are hosting the document or whether we are a // client. If we are a client we reset the connection of the // session proxy, which basically leads to us being // unsubscribed from the document. If we are hosting the // document, we do not want to unsubscribe from it, since // other users might still be connected. We therefore only // remove the local user from the session. If there are indeed // no other clients, then InfdDirectory will take care of // unsubscribing the session 60s after it became idle. if(INFD_IS_SESSION_PROXY(proxy)) { InfUser* user = view.get_active_user(); if(user != NULL) { InfSession* session; g_object_get(G_OBJECT(proxy), "session", &session, NULL); inf_session_set_user_status( session, user, INF_USER_UNAVAILABLE); g_object_unref(session); // TODO: set_active_user should go to // SessionView base: // TODO: The libinftextgtk objects should // reset the active user automatically when it // becomes unavailable. TextSessionView* text_view = dynamic_cast<TextSessionView*>(&view); if(text_view) text_view->set_active_user(NULL); ChatSessionView* chat_view = dynamic_cast<ChatSessionView*>(&view); if(chat_view) chat_view->set_active_user(NULL); } } else if(INFC_IS_SESSION_PROXY(proxy)) { infc_session_proxy_set_connection( INFC_SESSION_PROXY(proxy), NULL, NULL, 0); } } }