diff options
author | Yonit Halperin <yhalperi@redhat.com> | 2011-09-18 21:33:02 +0300 |
---|---|---|
committer | Yonit Halperin <yhalperi@redhat.com> | 2011-11-02 11:30:24 +0200 |
commit | c73d5c10e677b8ab67101545bb17eb46afd1e251 (patch) | |
tree | 0a5efceec9aa64f98a982b50b6b142796ec9f73c /client/red_channel.cpp | |
parent | 6cd3ffba6fbb53102bbaf69bcdba29e5a1db458d (diff) | |
download | spice-c73d5c10e677b8ab67101545bb17eb46afd1e251.tar.gz spice-c73d5c10e677b8ab67101545bb17eb46afd1e251.tar.xz spice-c73d5c10e677b8ab67101545bb17eb46afd1e251.zip |
client: handle SPICE_MSG_MAIN_MIGRATE_END
(1) disconnect all channels from the migration src
(2) after all channels are disconnected, clean global resources
(3) send SPICE_MSGC_MAIN_MIGRATE_END to migration target
(4) wait for SPICE_MSG_MAIN_INIT
(4) switch all channels to migration target
(cherry picked from commit 510a4ff7c4f188fe6d0fb12198b8f9fdb74b9a2d branch 0.8)
Conflicts:
client/red_channel.h
Diffstat (limited to 'client/red_channel.cpp')
-rw-r--r-- | client/red_channel.cpp | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/client/red_channel.cpp b/client/red_channel.cpp index 8632600c..d85265b7 100644 --- a/client/red_channel.cpp +++ b/client/red_channel.cpp @@ -30,6 +30,15 @@ #include "openssl/evp.h" #include "openssl/x509.h" +void MigrationDisconnectSrcEvent::response(AbstractProcessLoop& events_loop) +{ + static_cast<RedChannel*>(events_loop.get_owner())->do_migration_disconnect_src(); +} + +void MigrationConnectTargetEvent::response(AbstractProcessLoop& events_loop) +{ + static_cast<RedChannel*>(events_loop.get_owner())->do_migration_connect_target(); +} RedChannelBase::RedChannelBase(uint8_t type, uint8_t id, const ChannelCaps& common_caps, const ChannelCaps& caps) @@ -440,6 +449,57 @@ void RedChannel::disconnect() _action_cond.notify_one(); } +void RedChannel::disconnect_migration_src() +{ + clear_outgoing_messages(); + + Lock lock(_action_lock); + if (_state == CONNECTING_STATE || _state == CONNECTED_STATE) { + AutoRef<MigrationDisconnectSrcEvent> migrate_event(new MigrationDisconnectSrcEvent()); + _loop.push_event(*migrate_event); + } +} + +void RedChannel::connect_migration_target() +{ + LOG_INFO(""); + AutoRef<MigrationConnectTargetEvent> migrate_event(new MigrationConnectTargetEvent()); + _loop.push_event(*migrate_event); +} + +void RedChannel::do_migration_disconnect_src() +{ + if (_socket_in_loop) { + _socket_in_loop = false; + _loop.remove_socket(*this); + } + + clear_outgoing_messages(); + if (_outgoing_message) { + _outgoing_message->release(); + _outgoing_message = NULL; + } + _incomming_header_pos = 0; + if (_incomming_message) { + _incomming_message->unref(); + _incomming_message = NULL; + } + + on_disconnect_mig_src(); + get_client().migrate_channel(*this); + get_client().on_channel_disconnect_mig_src_completed(*this); +} + +void RedChannel::do_migration_connect_target() +{ + LOG_INFO(""); + _loop.add_socket(*this); + _socket_in_loop = true; + on_connect_mig_target(); + set_state(CONNECTED_STATE); + on_event(); +} + void RedChannel::clear_outgoing_messages() { Lock lock(_outgoing_lock); |