summaryrefslogtreecommitdiffstats
path: root/client/red_channel.cpp
diff options
context:
space:
mode:
authorYonit Halperin <yhalperi@redhat.com>2011-09-18 21:33:02 +0300
committerYonit Halperin <yhalperi@redhat.com>2011-11-02 11:30:24 +0200
commitc73d5c10e677b8ab67101545bb17eb46afd1e251 (patch)
tree0a5efceec9aa64f98a982b50b6b142796ec9f73c /client/red_channel.cpp
parent6cd3ffba6fbb53102bbaf69bcdba29e5a1db458d (diff)
downloadspice-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.cpp60
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);