"Device '%s' not found", s->chr_name);
return;
}
- if (qemu_chr_fe_claim(chr) != 0) {
- error_setg(errp, QERR_DEVICE_IN_USE, s->chr_name);
- return;
- }
if (!qemu_chr_fe_init(&s->chr, chr, errp)) {
return;
}
{
RngEgd *s = RNG_EGD(obj);
- if (s->chr.chr) {
- qemu_chr_fe_set_handlers(&s->chr, NULL, NULL, NULL, NULL, NULL);
- qemu_chr_fe_release(s->chr.chr);
- }
-
+ qemu_chr_fe_deinit(&s->chr);
g_free(s->chr_name);
}
put_packet(s, buf);
#ifndef CONFIG_USER_ONLY
+ qemu_chr_fe_deinit(&s->chr);
qemu_chr_delete(chr);
#endif
}
chr = qemu_chr_new_noreplay("gdb", device);
if (!chr)
return -1;
-
- qemu_chr_fe_claim_no_fail(chr);
}
s = gdbserver_state;
PXA2xxFIrState *s = PXA2XX_FIR(dev);
if (s->chr.chr) {
- qemu_chr_fe_claim_no_fail(s->chr.chr);
qemu_chr_fe_set_handlers(&s->chr, pxa2xx_fir_is_empty,
pxa2xx_fir_rx, pxa2xx_fir_event, s, NULL);
}
s->irq = irq;
if (chr) {
qemu_chr_fe_init(&s->chr, chr, &error_abort);
- qemu_chr_fe_claim_no_fail(chr);
qemu_chr_fe_set_handlers(&s->chr, mcf_uart_can_receive,
mcf_uart_receive, mcf_uart_event, s, NULL);
}
void serial_exit_core(SerialState *s)
{
- qemu_chr_fe_set_handlers(&s->chr, NULL, NULL, NULL, NULL, NULL);
+ qemu_chr_fe_deinit(&s->chr);
qemu_unregister_reset(serial_reset, s);
}
memory_region_add_subregion(sysmem, A7ADDR(base), &s->iomem_a7);
if (chr) {
- qemu_chr_fe_claim_no_fail(chr);
qemu_chr_fe_init(&s->chr, chr, &error_abort);
qemu_chr_fe_set_handlers(&s->chr, sh_serial_can_receive1,
sh_serial_receive1,
xen_be_bind_evtchn(&con->xendev);
if (con->chr.chr) {
- if (qemu_chr_fe_claim(con->chr.chr) == 0) {
- qemu_chr_fe_set_handlers(&con->chr, xencons_can_receive,
- xencons_receive, NULL, con, NULL);
- } else {
- xen_be_printf(xendev, 0,
- "xen_console_init error chardev %s already used\n",
- con->chr.chr->label);
- con->chr.chr = NULL;
- }
+ qemu_chr_fe_set_handlers(&con->chr, xencons_can_receive,
+ xencons_receive, NULL, con, NULL);
}
xen_be_printf(xendev, 1, "ring mfn %d, remote port %d, local port %d, limit %zd\n",
{
struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
- if (con->chr.chr) {
- qemu_chr_fe_set_handlers(&con->chr, NULL, NULL, NULL, NULL, NULL);
- qemu_chr_fe_release(con->chr.chr);
- }
+ qemu_chr_fe_deinit(&con->chr);
xen_be_unbind_evtchn(&con->xendev);
if (con->sring) {
object_get_typename(obj), prop->name, str);
return;
}
- if (qemu_chr_fe_claim(s) != 0) {
- error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use",
- object_get_typename(obj), prop->name, str);
+
+ if (!qemu_chr_fe_init(be, s, errp)) {
+ error_prepend(errp, "Property '%s.%s' can't take value '%s': ",
+ object_get_typename(obj), prop->name, str);
return;
}
-
- qemu_chr_fe_init(be, s, errp);
}
static void release_chr(Object *obj, const char *name, void *opaque)
Property *prop = opaque;
CharBackend *be = qdev_get_prop_ptr(dev, prop);
- if (be->chr) {
- qemu_chr_fe_set_handlers(be, NULL, NULL, NULL, NULL, NULL);
- qemu_chr_fe_release(be->chr);
- }
+ qemu_chr_fe_deinit(be);
}
PropertyInfo qdev_prop_chr = {
{
CharDriverState *chr = qemu_chr_fe_get_driver(&card->cs);
+ qemu_chr_fe_deinit(&card->cs);
qemu_chr_delete(chr);
card->vscard_in_pos = card->vscard_in_hdr = 0;
}
USBRedirDevice *dev = USB_REDIRECT(udev);
CharDriverState *chr = qemu_chr_fe_get_driver(&dev->cs);
+ qemu_chr_fe_deinit(&dev->cs);
qemu_chr_delete(chr);
- dev->cs.chr = NULL;
/* Note must be done after qemu_chr_close, as that causes a close event */
qemu_bh_delete(dev->chardev_close_bh);
qemu_bh_delete(dev->device_reject_bh);
*/
int qemu_chr_fe_set_msgfds(CharBackend *be, int *fds, int num);
-/**
- * @qemu_chr_fe_claim:
- *
- * Claim a backend before using it, should be called before calling
- * qemu_chr_fe_set_handlers().
- *
- * Returns: -1 if the backend is already in use by another frontend, 0 on
- * success.
- */
-int qemu_chr_fe_claim(CharDriverState *s);
-
-/**
- * @qemu_chr_fe_claim_no_fail:
- *
- * Like qemu_chr_fe_claim, but will exit qemu with an error when the
- * backend is already in use.
- */
-void qemu_chr_fe_claim_no_fail(CharDriverState *s);
-
-/**
- * @qemu_chr_fe_release:
- *
- * Release a backend for use by another frontend.
- *
- * Returns: -1 if the backend is already in use by another frontend, 0 on
- * success.
- */
-void qemu_chr_fe_release(CharDriverState *s);
-
/**
* @qemu_chr_be_can_write:
*
* @qemu_chr_fe_init:
*
* Initializes a front end for the given CharBackend and
- * CharDriver.
+ * CharDriver. Call qemu_chr_fe_deinit() to remove the association and
+ * release the driver.
*
* Returns: false on error.
*/
*/
CharDriverState *qemu_chr_fe_get_driver(CharBackend *be);
+/**
+ * @qemu_chr_fe_deinit:
+ *
+ * Dissociate the CharBackend from the CharDriver.
+ */
+void qemu_chr_fe_deinit(CharBackend *b);
+
/**
* @qemu_chr_fe_set_handlers:
* @b: a CharBackend
static void monitor_data_destroy(Monitor *mon)
{
- if (mon->chr.chr) {
- qemu_chr_fe_set_handlers(&mon->chr, NULL, NULL, NULL, NULL, NULL);
- }
+ qemu_chr_fe_deinit(&mon->chr);
if (monitor_is_qmp(mon)) {
json_message_parser_destroy(&mon->qmp.parser);
}
return 1;
}
- if (qemu_chr_fe_claim(*chr) < 0) {
- error_setg(errp, "chardev \"%s\" cannot be claimed",
- chr_name);
- return 1;
- }
-
return 0;
}
{
CompareState *s = COLO_COMPARE(obj);
- if (s->chr_pri_in.chr) {
- qemu_chr_fe_set_handlers(&s->chr_pri_in, NULL, NULL, NULL, NULL, NULL);
- qemu_chr_fe_release(s->chr_pri_in.chr);
- }
- if (s->chr_sec_in.chr) {
- qemu_chr_fe_set_handlers(&s->chr_sec_in, NULL, NULL, NULL, NULL, NULL);
- qemu_chr_fe_release(s->chr_sec_in.chr);
- }
- if (s->chr_out.chr) {
- qemu_chr_fe_release(s->chr_out.chr);
- }
+ qemu_chr_fe_deinit(&s->chr_pri_in);
+ qemu_chr_fe_deinit(&s->chr_sec_in);
+ qemu_chr_fe_deinit(&s->chr_out);
g_queue_free(&s->conn_list);
{
MirrorState *s = FILTER_MIRROR(nf);
- if (s->chr_out.chr) {
- qemu_chr_fe_release(s->chr_out.chr);
- }
+ qemu_chr_fe_deinit(&s->chr_out);
}
static void filter_redirector_cleanup(NetFilterState *nf)
{
MirrorState *s = FILTER_REDIRECTOR(nf);
- if (s->chr_in.chr) {
- qemu_chr_fe_set_handlers(&s->chr_in, NULL, NULL, NULL, NULL, NULL);
- qemu_chr_fe_release(s->chr_in.chr);
- }
- if (s->chr_out.chr) {
- qemu_chr_fe_release(s->chr_out.chr);
- }
+ qemu_chr_fe_deinit(&s->chr_in);
+ qemu_chr_fe_deinit(&s->chr_out);
}
static void filter_mirror_setup(NetFilterState *nf, Error **errp)
return;
}
- if (qemu_chr_fe_claim(chr) != 0) {
- error_setg(errp, QERR_DEVICE_IN_USE, s->outdev);
- return;
- }
-
qemu_chr_fe_init(&s->chr_out, chr, errp);
}
return;
}
- qemu_chr_fe_claim_no_fail(chr);
if (!qemu_chr_fe_init(&s->chr_in, chr, errp)) {
return;
}
"OUT Device '%s' not found", s->outdev);
return;
}
- qemu_chr_fe_claim_no_fail(chr);
if (!qemu_chr_fe_init(&s->chr_out, chr, errp)) {
return;
}
fwd->port = port;
fwd->slirp = s->slirp;
- qemu_chr_fe_claim_no_fail(fwd->hd.chr);
qemu_chr_fe_set_handlers(&fwd->hd, guestfwd_can_read, guestfwd_read,
NULL, fwd, NULL);
}
g_free(s->vhost_net);
s->vhost_net = NULL;
}
- if (nc->queue_index == 0 && s->chr.chr) {
- qemu_chr_fe_set_handlers(&s->chr, NULL, NULL, NULL, NULL, NULL);
- qemu_chr_fe_release(s->chr.chr);
- s->chr.chr = NULL;
+ if (nc->queue_index == 0) {
+ qemu_chr_fe_deinit(&s->chr);
}
qemu_purge_queued_packets(nc);
return NULL;
}
- qemu_chr_fe_claim_no_fail(chr);
-
return chr;
}
{
MuxDriver *d = chr->opaque;
+ qemu_chr_fe_deinit(&d->chr);
g_free(d);
}
return true;
}
+void qemu_chr_fe_deinit(CharBackend *b)
+{
+ assert(b);
+
+ if (b->chr) {
+ qemu_chr_fe_set_handlers(b, NULL, NULL, NULL, NULL, NULL);
+ b->chr->avail_connections++;
+ b->chr = NULL;
+ }
+}
+
void qemu_chr_fe_set_handlers(CharBackend *b,
IOCanReadHandler *fd_can_read,
IOReadHandler *fd_read,
error_report_err(err);
}
if (chr && qemu_opt_get_bool(opts, "mux", 0)) {
- qemu_chr_fe_claim_no_fail(chr);
monitor_init(chr, MONITOR_USE_READLINE);
}
qemu_opts_del(opts);
return tag;
}
-int qemu_chr_fe_claim(CharDriverState *s)
-{
- if (s->avail_connections < 1) {
- return -1;
- }
- s->avail_connections--;
- return 0;
-}
-
-void qemu_chr_fe_claim_no_fail(CharDriverState *s)
-{
- if (qemu_chr_fe_claim(s) != 0) {
- fprintf(stderr, "%s: error chardev \"%s\" already used\n",
- __func__, s->label);
- exit(1);
- }
-}
-
-void qemu_chr_fe_release(CharDriverState *s)
-{
- s->avail_connections++;
-}
-
void qemu_chr_fe_disconnect(CharBackend *be)
{
CharDriverState *chr = be->chr;
int i;
CharDriverState *chr = qemu_chr_fe_get_driver(&server->chr);
+ qemu_chr_fe_deinit(&server->chr);
qemu_chr_delete(chr);
for (i = 0; i < server->fds_num; i++) {
exit(1);
}
- qemu_chr_fe_claim_no_fail(chr);
monitor_init(chr, flags);
return 0;
}