bool revive_if_needed(std::unique_lock<std::mutex>& lock, SyncSession& session) const override
 {
     // Revive.
     session.create_sync_session();
     session.advance_state(lock, waiting_for_access_token);
     return true;
 }
 bool access_token_expired(std::unique_lock<std::mutex>& lock, SyncSession& session) const override
 {
     session.advance_state(lock, waiting_for_access_token);
     std::shared_ptr<SyncSession> session_ptr = session.shared_from_this();
     lock.unlock();
     session.m_config.bind_session_handler(session_ptr->m_realm_path, session_ptr->m_config, session_ptr);
     return false;
 }
 void bind_with_admin_token(std::unique_lock<std::mutex>& lock, SyncSession& session,
                            const std::string& admin_token,
                            const std::string& server_url) const override
 {
     session.create_sync_session();
     session.advance_state(lock, waiting_for_access_token);
     session.m_state->refresh_access_token(lock, session, admin_token, server_url);
 }
 void close(std::unique_lock<std::mutex>& lock, SyncSession& session) const override
 {
     switch (session.m_config.stop_policy) {
         case SyncSessionStopPolicy::Immediately:
             session.advance_state(lock, inactive);
             break;
         case SyncSessionStopPolicy::LiveIndefinitely:
             // Don't do anything; session lives forever.
             break;
         case SyncSessionStopPolicy::AfterChangesUploaded:
             // Wait for all pending changes to upload.
             session.advance_state(lock, dying);
             break;
     }
 }
 void handle_reconnect(std::unique_lock<std::mutex>& lock, SyncSession& session) const override
 {
     // Ask the binding to retry getting the token for this session.
     std::shared_ptr<SyncSession> session_ptr = session.shared_from_this();
     lock.unlock();
     session.m_config.bind_session_handler(session_ptr->m_realm_path, session_ptr->m_config, session_ptr);
 }
 void refresh_access_token(std::unique_lock<std::mutex>& lock, SyncSession& session,
                           std::string access_token,
                           const util::Optional<std::string>& server_url) const override
 {
     // Since the sync session was previously unbound, it's safe to do this from the
     // calling thread.
     if (!session.m_server_url) {
         session.m_server_url = server_url;
     }
     if (session.m_session_has_been_bound) {
         session.m_session->refresh(std::move(access_token));
     } else {
         session.m_session->bind(*session.m_server_url, std::move(access_token));
         session.m_session_has_been_bound = true;
     }
     if (session.m_deferred_commit_notification) {
         session.m_session->nonsync_transact_notify(*session.m_deferred_commit_notification);
         session.m_deferred_commit_notification = util::none;
     }
     session.advance_state(lock, active);
     if (session.m_deferred_close) {
         session.m_deferred_close = false;
         session.m_state->close(lock, session);
     }
 }
 void enter_state(std::unique_lock<std::mutex>&, SyncSession& session) const override
 {
     size_t current_death_count = ++session.m_death_count;
     session.m_session->async_wait_for_upload_completion([session=&session, current_death_count](std::error_code) {
         std::unique_lock<std::mutex> lock(session->m_state_mutex);
         if (session->m_state == &State::dying && session->m_death_count == current_death_count) {
             session->advance_state(lock, inactive);
         }
     });
 }
 void enter_state(std::unique_lock<std::mutex>& lock, SyncSession& session) const override
 {
     // Inform any queued-up completion handlers that they were cancelled.
     for (auto& package : session.m_completion_wait_packages) {
         package.callback(util::error::operation_aborted);
     }
     session.m_completion_wait_packages.clear();
     session.m_session = nullptr;
     session.unregister(lock);
 }
    void enter_state(std::unique_lock<std::mutex>& lock, SyncSession& session) const override
    {
        // If we have no session, we cannot possibly upload anything.
        if (!session.m_session) {
            session.advance_state(lock, inactive);
            return;
        }

        size_t current_death_count = ++session.m_death_count;
        std::weak_ptr<SyncSession> weak_session = session.shared_from_this();
        session.m_session->async_wait_for_upload_completion([weak_session, current_death_count](std::error_code) {
            if (auto session = weak_session.lock()) {
                std::unique_lock<std::mutex> lock(session->m_state_mutex);
                if (session->m_state == &State::dying && session->m_death_count == current_death_count) {
                    session->advance_state(lock, inactive);
                }
            }
        });
    }
Exemple #10
0
bool_t SyncAcceptor::OnRead(EventResult *evr)
{
	bool_t ret = FALSE;

	SyncSession *sess = 0;

	ret = MakeEventHandler(sess);
	if(!ret) { ECILA_TRACE(); return FALSE; }

	ret = AcceptEventHandler(sess);
	if(!ret) { ECILA_TRACE(); goto _ERROR; }

	ret = ActivateEventHandler(sess);
	if(!ret) { ECILA_TRACE(); goto _ERROR; }

	return TRUE;

_ERROR:
	sess->OnClose(0);
	return FALSE;
}
Exemple #11
0
 bool handle_error(std::unique_lock<std::mutex>& lock, SyncSession& session, const SyncError& error) const override
 {
     if (error.is_fatal) {
         session.advance_state(lock, inactive);
     }
     // If the error isn't fatal, don't change state, but don't
     // allow it to be reported either.
     // FIXME: What if the token expires while a session is dying?
     // Should we allow the token to be refreshed so that changes
     // can finish being uploaded?
     return true;
 }
Exemple #12
0
    void refresh_access_token(std::unique_lock<std::mutex>& lock, SyncSession& session,
                              std::string access_token,
                              const util::Optional<std::string>& server_url) const override
    {
        session.create_sync_session();

        // Since the sync session was previously unbound, it's safe to do this from the
        // calling thread.
        if (!session.m_server_url) {
            session.m_server_url = server_url;
        }
        if (session.m_session_has_been_bound) {
            session.m_session->refresh(std::move(access_token));
            session.m_session->cancel_reconnect_delay();
        } else {
            session.m_session->bind(*session.m_server_url, std::move(access_token));
            session.m_session_has_been_bound = true;
        }

        if (session.m_server_override)
            session.m_session->override_server(session.m_server_override->address, session.m_server_override->port);

        // Register all the pending wait-for-completion blocks.
        for (auto& package : session.m_completion_wait_packages) {
            (*session.m_session.*package.waiter)(std::move(package.callback));
        }
        session.m_completion_wait_packages.clear();

        // Handle any deferred commit notification.
        if (session.m_deferred_commit_notification) {
            session.m_session->nonsync_transact_notify(*session.m_deferred_commit_notification);
            session.m_deferred_commit_notification = util::none;
        }

        session.advance_state(lock, active);
        if (session.m_deferred_close) {
            session.m_state->close(lock, session);
        }
    }
Exemple #13
0
 void close(std::unique_lock<std::mutex>& lock, SyncSession& session) const override
 {
     switch (session.m_config.stop_policy) {
         case SyncSessionStopPolicy::Immediately:
             // Immediately kill the session.
             session.advance_state(lock, inactive);
             break;
         case SyncSessionStopPolicy::LiveIndefinitely:
         case SyncSessionStopPolicy::AfterChangesUploaded:
             // Defer handling closing the session until after the login response succeeds.
             session.m_deferred_close = true;
             break;
     }
 }
    void enter_state(std::unique_lock<std::mutex>&, SyncSession& session) const override
    {
        ++session.m_pending_upload_threads;
        std::thread([session=&session] {
            std::unique_lock<std::mutex> lock(session->m_state_mutex);
            if (session->m_pending_upload_threads != 1) {
                --session->m_pending_upload_threads;
                return;
            }

            if (session->m_state != &State::dying) {
                // The session was revived. Don't kill it.
                --session->m_pending_upload_threads;
                return;
            }

            session->m_session->wait_for_upload_complete_or_client_stopped();
            --session->m_pending_upload_threads;
            session->advance_state(lock, inactive);
        }).detach();
    }
Exemple #15
0
 static void handle_progress_update(SyncSession& session, uint64_t downloaded, uint64_t downloadable,
                                    uint64_t uploaded, uint64_t uploadable, bool is_fresh=true) {
     session.handle_progress_update(downloaded, downloadable, uploaded, uploadable, is_fresh);
 }
 void close_if_connecting(std::unique_lock<std::mutex>& lock, SyncSession& session) const override
 {
     // Ignore the sync configuration's stop policy as we're not yet connected.
     session.advance_state(lock, inactive);
 }
 static void handle_error(SyncSession& session, SyncError error)
 {
     session.handle_error(std::move(error));
 }
 static void nonsync_transact_notify(SyncSession& session, VersionID::version_type version)
 {
     session.nonsync_transact_notify(version);
 }
 static void set_error_handler(SyncSession& session, std::function<SyncSessionErrorHandler> callback)
 {
     session.set_error_handler(std::move(callback));
 }
 void log_out(std::unique_lock<std::mutex>& lock, SyncSession& session) const override
 {
     session.advance_state(lock, inactive);
 }
 bool revive_if_needed(std::unique_lock<std::mutex>& lock, SyncSession& session) const override
 {
     // Revive.
     session.advance_state(lock, active);
     return false;
 }
inline bool sessions_are_inactive(const SyncSession& session)
{
    return session.state() == SyncSession::PublicState::Inactive;
}
 void enter_state(std::unique_lock<std::mutex>& lock, SyncSession& session) const override
 {
     session.m_session = nullptr;
     session.m_server_url = util::none;
     session.unregister(lock);
 }
inline bool sessions_are_connected(const SyncSession& session) {
    return session.connection_state() == SyncSession::ConnectionState::Connected;
}
 static void set_sync_transact_callback(SyncSession& session,
                                        std::function<SyncSessionTransactCallback> callback)
 {
     session.set_sync_transact_callback(std::move(callback));
 }
 void access_token_expired(std::unique_lock<std::mutex>& lock, SyncSession& session) const override
 {
     session.advance_state(lock, waiting_for_access_token);
 }