static void spicevmc_connect(RedChannel *channel, RedClient *client, RedsStream *stream, int migration, int num_common_caps, uint32_t *common_caps, int num_caps, uint32_t *caps) { RedChannelClient *rcc; SpiceVmcState *state; SpiceCharDeviceInstance *sin; SpiceCharDeviceInterface *sif; state = SPICE_CONTAINEROF(channel, SpiceVmcState, channel); sin = state->chardev_sin; sif = SPICE_CONTAINEROF(sin->base.sif, SpiceCharDeviceInterface, base); if (state->rcc) { spice_printerr("channel client %d:%d (%p) already connected, refusing second connection", channel->type, channel->id, state->rcc); // TODO: notify client in advance about the in use channel using // SPICE_MSG_MAIN_CHANNEL_IN_USE (for example) reds_stream_free(stream); return; } rcc = red_channel_client_create(sizeof(RedChannelClient), channel, client, stream, FALSE, num_common_caps, common_caps, num_caps, caps); if (!rcc) { return; } state->rcc = rcc; red_channel_client_ack_zero_messages_window(rcc); if (strcmp(sin->subtype, "port") == 0) { spicevmc_port_send_init(rcc); } if (!spice_char_device_client_add(state->chardev_st, client, FALSE, 0, ~0, ~0, red_channel_client_waits_for_migrate_data(rcc))) { spice_warning("failed to add client to spicevmc"); red_channel_client_disconnect(rcc); return; } if (sif->state) { sif->state(sin, 1); } }
static void snd_disconnect_channel(SndChannel *channel) { SndWorker *worker; if (!channel) { spice_debug("not connected"); return; } spice_debug("%p", channel); worker = channel->worker; if (channel->stream) { channel->cleanup(channel); red_channel_client_disconnect(worker->connection->channel_client); core->watch_remove(channel->stream->watch); channel->stream->watch = NULL; reds_stream_free(channel->stream); channel->stream = NULL; spice_marshaller_destroy(channel->send_data.marshaller); } snd_channel_put(channel); worker->connection = NULL; }
static void smartcard_char_device_attach_client(SpiceCharDeviceInstance *char_device, SmartCardChannelClient *scc) { SmartCardDeviceState *st = spice_char_device_state_opaque_get(char_device->st); int client_added; spice_assert(!scc->smartcard_state && !st->scc); st->scc = scc; scc->smartcard_state = st; client_added = spice_char_device_client_add(st->chardev_st, scc->base.client, FALSE, /* no flow control yet */ 0, /* send queue size */ ~0, ~0, red_channel_client_waits_for_migrate_data( &scc->base)); if (!client_added) { spice_warning("failed"); st->scc = NULL; scc->smartcard_state = NULL; red_channel_client_disconnect(&scc->base); } }