Beispiel #1
0
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);
}
Beispiel #3
0
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;
  }
}
Beispiel #4
0
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();
}
Beispiel #5
0
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);
}
Beispiel #6
0
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);
  }
}
Beispiel #7
0
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);
    }
  }
}
Beispiel #8
0
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);
}
Beispiel #9
0
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;
  }
}
Beispiel #10
0
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
}
Beispiel #11
0
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);
		}
	}
}