mux: split mux_chr_update_read_handler()
Make qemu_chr_add_handlers_full() aware of mux handling. This allows introduction of a tag associated with the fe handlers and a qemu_chr_set_handlers() function to set the handler for a particular tag. That will allow to get rid of qemu_chr_add_handlers*() in later changes, in favor of qemu_chr_fe_set_handler(). To this end, chr_update_read_handler callback is enhanced with a tag argument, and mux_chr_update_read_handler() is splitted in new functions: mux_chr_new_handler_tag(), mux_chr_set_handlers(), mux_set_focus(). Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20161022095318.17775-9-marcandre.lureau@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
		
							parent
							
								
									c8cccba312
								
							
						
					
					
						commit
						6dfa8298fa
					
				| 
						 | 
				
			
			@ -80,7 +80,7 @@ struct CharDriverState {
 | 
			
		|||
                         const uint8_t *buf, int len);
 | 
			
		||||
    GSource *(*chr_add_watch)(struct CharDriverState *s, GIOCondition cond);
 | 
			
		||||
    void (*chr_update_read_handler)(struct CharDriverState *s,
 | 
			
		||||
                                    GMainContext *context);
 | 
			
		||||
                                    GMainContext *context, int tag);
 | 
			
		||||
    int (*chr_ioctl)(struct CharDriverState *s, int cmd, void *arg);
 | 
			
		||||
    int (*get_msgfds)(struct CharDriverState *s, int* fds, int num);
 | 
			
		||||
    int (*set_msgfds)(struct CharDriverState *s, int *fds, int num);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										139
									
								
								qemu-char.c
								
								
								
								
							
							
						
						
									
										139
									
								
								qemu-char.c
								
								
								
								
							| 
						 | 
				
			
			@ -89,6 +89,8 @@
 | 
			
		|||
#define READ_RETRIES 10
 | 
			
		||||
#define TCP_MAX_FDS 16
 | 
			
		||||
 | 
			
		||||
typedef struct MuxDriver MuxDriver;
 | 
			
		||||
 | 
			
		||||
/***********************************************************/
 | 
			
		||||
/* Socket address helpers */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -449,12 +451,14 @@ void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
 | 
			
		|||
 | 
			
		||||
static void remove_fd_in_watch(CharDriverState *chr);
 | 
			
		||||
 | 
			
		||||
void qemu_chr_add_handlers_full(CharDriverState *s,
 | 
			
		||||
                                IOCanReadHandler *fd_can_read,
 | 
			
		||||
                                IOReadHandler *fd_read,
 | 
			
		||||
                                IOEventHandler *fd_event,
 | 
			
		||||
                                void *opaque,
 | 
			
		||||
                                GMainContext *context)
 | 
			
		||||
static void
 | 
			
		||||
qemu_chr_set_handlers(CharDriverState *s,
 | 
			
		||||
                      IOCanReadHandler *fd_can_read,
 | 
			
		||||
                      IOReadHandler *fd_read,
 | 
			
		||||
                      IOEventHandler *fd_event,
 | 
			
		||||
                      void *opaque,
 | 
			
		||||
                      GMainContext *context,
 | 
			
		||||
                      int tag)
 | 
			
		||||
{
 | 
			
		||||
    int fe_open;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -469,7 +473,7 @@ void qemu_chr_add_handlers_full(CharDriverState *s,
 | 
			
		|||
    s->chr_event = fd_event;
 | 
			
		||||
    s->handler_opaque = opaque;
 | 
			
		||||
    if (s->chr_update_read_handler) {
 | 
			
		||||
        s->chr_update_read_handler(s, context);
 | 
			
		||||
        s->chr_update_read_handler(s, context, tag);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!s->explicit_fe_open) {
 | 
			
		||||
| 
						 | 
				
			
			@ -483,6 +487,34 @@ void qemu_chr_add_handlers_full(CharDriverState *s,
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int mux_chr_new_handler_tag(CharDriverState *chr, Error **errp);
 | 
			
		||||
static void mux_chr_set_handlers(CharDriverState *chr, GMainContext *context);
 | 
			
		||||
static void mux_set_focus(MuxDriver *d, int focus);
 | 
			
		||||
 | 
			
		||||
void qemu_chr_add_handlers_full(CharDriverState *s,
 | 
			
		||||
                                IOCanReadHandler *fd_can_read,
 | 
			
		||||
                                IOReadHandler *fd_read,
 | 
			
		||||
                                IOEventHandler *fd_event,
 | 
			
		||||
                                void *opaque,
 | 
			
		||||
                                GMainContext *context)
 | 
			
		||||
{
 | 
			
		||||
    int tag = 0;
 | 
			
		||||
 | 
			
		||||
    if (s->is_mux) {
 | 
			
		||||
        tag = mux_chr_new_handler_tag(s, &error_abort);
 | 
			
		||||
        if (tag == 0) {
 | 
			
		||||
            mux_chr_set_handlers(s, context);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    qemu_chr_set_handlers(s, fd_can_read, fd_read,
 | 
			
		||||
                          fd_event, opaque, context, tag);
 | 
			
		||||
 | 
			
		||||
    if (s->is_mux) {
 | 
			
		||||
        mux_set_focus(s->opaque, tag);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void qemu_chr_add_handlers(CharDriverState *s,
 | 
			
		||||
                           IOCanReadHandler *fd_can_read,
 | 
			
		||||
                           IOReadHandler *fd_read,
 | 
			
		||||
| 
						 | 
				
			
			@ -519,7 +551,7 @@ static CharDriverState *qemu_chr_open_null(const char *id,
 | 
			
		|||
#define MAX_MUX 4
 | 
			
		||||
#define MUX_BUFFER_SIZE 32	/* Must be a power of 2.  */
 | 
			
		||||
#define MUX_BUFFER_MASK (MUX_BUFFER_SIZE - 1)
 | 
			
		||||
typedef struct {
 | 
			
		||||
struct MuxDriver {
 | 
			
		||||
    IOCanReadHandler *chr_can_read[MAX_MUX];
 | 
			
		||||
    IOReadHandler *chr_read[MAX_MUX];
 | 
			
		||||
    IOEventHandler *chr_event[MAX_MUX];
 | 
			
		||||
| 
						 | 
				
			
			@ -540,8 +572,7 @@ typedef struct {
 | 
			
		|||
    /* Protected by the CharDriverState chr_write_lock.  */
 | 
			
		||||
    int linestart;
 | 
			
		||||
    int64_t timestamps_start;
 | 
			
		||||
} MuxDriver;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Called with chr_write_lock held.  */
 | 
			
		||||
static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
 | 
			
		||||
| 
						 | 
				
			
			@ -655,12 +686,9 @@ static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)
 | 
			
		|||
            qemu_chr_be_event(chr, CHR_EVENT_BREAK);
 | 
			
		||||
            break;
 | 
			
		||||
        case 'c':
 | 
			
		||||
            assert(d->mux_cnt > 0); /* handler registered with first fe */
 | 
			
		||||
            /* Switch to the next registered device */
 | 
			
		||||
            mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT);
 | 
			
		||||
            d->focus++;
 | 
			
		||||
            if (d->focus >= d->mux_cnt)
 | 
			
		||||
                d->focus = 0;
 | 
			
		||||
            mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);
 | 
			
		||||
            mux_set_focus(d, (d->focus + 1) % d->mux_cnt);
 | 
			
		||||
            break;
 | 
			
		||||
        case 't':
 | 
			
		||||
            d->timestamps = !d->timestamps;
 | 
			
		||||
| 
						 | 
				
			
			@ -735,31 +763,18 @@ static void mux_chr_event(void *opaque, int event)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static void mux_chr_update_read_handler(CharDriverState *chr,
 | 
			
		||||
                                        GMainContext *context)
 | 
			
		||||
                                        GMainContext *context,
 | 
			
		||||
                                        int tag)
 | 
			
		||||
{
 | 
			
		||||
    MuxDriver *d = chr->opaque;
 | 
			
		||||
 | 
			
		||||
    if (d->mux_cnt >= MAX_MUX) {
 | 
			
		||||
        fprintf(stderr, "Cannot add I/O handlers, MUX array is full\n");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    d->ext_opaque[d->mux_cnt] = chr->handler_opaque;
 | 
			
		||||
    d->chr_can_read[d->mux_cnt] = chr->chr_can_read;
 | 
			
		||||
    d->chr_read[d->mux_cnt] = chr->chr_read;
 | 
			
		||||
    d->chr_event[d->mux_cnt] = chr->chr_event;
 | 
			
		||||
    /* Fix up the real driver with mux routines */
 | 
			
		||||
    if (d->mux_cnt == 0) {
 | 
			
		||||
        qemu_chr_add_handlers_full(d->drv, mux_chr_can_read,
 | 
			
		||||
                                   mux_chr_read,
 | 
			
		||||
                                   mux_chr_event,
 | 
			
		||||
                                   chr, context);
 | 
			
		||||
    }
 | 
			
		||||
    if (d->focus != -1) {
 | 
			
		||||
        mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT);
 | 
			
		||||
    }
 | 
			
		||||
    d->focus = d->mux_cnt;
 | 
			
		||||
    d->mux_cnt++;
 | 
			
		||||
    mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);
 | 
			
		||||
    assert(tag >= 0);
 | 
			
		||||
    assert(tag < d->mux_cnt);
 | 
			
		||||
 | 
			
		||||
    d->ext_opaque[tag] = chr->handler_opaque;
 | 
			
		||||
    d->chr_can_read[tag] = chr->chr_can_read;
 | 
			
		||||
    d->chr_read[tag] = chr->chr_read;
 | 
			
		||||
    d->chr_event[tag] = chr->chr_event;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool muxes_realized;
 | 
			
		||||
| 
						 | 
				
			
			@ -815,6 +830,44 @@ static void mux_chr_close(struct CharDriverState *chr)
 | 
			
		|||
    g_free(d);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int mux_chr_new_handler_tag(CharDriverState *chr, Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    MuxDriver *d = chr->opaque;
 | 
			
		||||
 | 
			
		||||
    if (d->mux_cnt >= MAX_MUX) {
 | 
			
		||||
        fprintf(stderr, "Cannot add I/O handlers, MUX array is full\n");
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return d->mux_cnt++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void mux_chr_set_handlers(CharDriverState *chr, GMainContext *context)
 | 
			
		||||
{
 | 
			
		||||
    MuxDriver *d = chr->opaque;
 | 
			
		||||
 | 
			
		||||
    /* Fix up the real driver with mux routines */
 | 
			
		||||
    qemu_chr_add_handlers_full(d->drv,
 | 
			
		||||
                               mux_chr_can_read,
 | 
			
		||||
                               mux_chr_read,
 | 
			
		||||
                               mux_chr_event,
 | 
			
		||||
                               chr,
 | 
			
		||||
                               context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void mux_set_focus(MuxDriver *d, int focus)
 | 
			
		||||
{
 | 
			
		||||
    assert(focus >= 0);
 | 
			
		||||
    assert(focus < d->mux_cnt);
 | 
			
		||||
 | 
			
		||||
    if (d->focus != -1) {
 | 
			
		||||
        mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    d->focus = focus;
 | 
			
		||||
    mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static CharDriverState *qemu_chr_open_mux(const char *id,
 | 
			
		||||
                                          ChardevBackend *backend,
 | 
			
		||||
                                          ChardevReturn *ret, Error **errp)
 | 
			
		||||
| 
						 | 
				
			
			@ -1085,7 +1138,8 @@ static GSource *fd_chr_add_watch(CharDriverState *chr, GIOCondition cond)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static void fd_chr_update_read_handler(CharDriverState *chr,
 | 
			
		||||
                                       GMainContext *context)
 | 
			
		||||
                                       GMainContext *context,
 | 
			
		||||
                                       int tag)
 | 
			
		||||
{
 | 
			
		||||
    FDCharDriver *s = chr->opaque;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1342,7 +1396,8 @@ static void pty_chr_update_read_handler_locked(CharDriverState *chr)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static void pty_chr_update_read_handler(CharDriverState *chr,
 | 
			
		||||
                                        GMainContext *context)
 | 
			
		||||
                                        GMainContext *context,
 | 
			
		||||
                                        int tag)
 | 
			
		||||
{
 | 
			
		||||
    qemu_mutex_lock(&chr->chr_write_lock);
 | 
			
		||||
    pty_chr_update_read_handler_locked(chr);
 | 
			
		||||
| 
						 | 
				
			
			@ -2589,7 +2644,8 @@ static gboolean udp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static void udp_chr_update_read_handler(CharDriverState *chr,
 | 
			
		||||
                                        GMainContext *context)
 | 
			
		||||
                                        GMainContext *context,
 | 
			
		||||
                                        int tag)
 | 
			
		||||
{
 | 
			
		||||
    NetCharDriver *s = chr->opaque;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3008,7 +3064,8 @@ static void tcp_chr_connect(void *opaque)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static void tcp_chr_update_read_handler(CharDriverState *chr,
 | 
			
		||||
                                        GMainContext *context)
 | 
			
		||||
                                        GMainContext *context,
 | 
			
		||||
                                        int tag)
 | 
			
		||||
{
 | 
			
		||||
    TCPCharDriver *s = chr->opaque;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue