diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:35 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:35 -0800 |
commit | f721e3ac031f892af46f255a47d7f54a91317b30 (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /charpipe.c | |
parent | bae1bc39312d5019bd9a5b8d840a529213a69a17 (diff) | |
download | external_qemu-f721e3ac031f892af46f255a47d7f54a91317b30.zip external_qemu-f721e3ac031f892af46f255a47d7f54a91317b30.tar.gz external_qemu-f721e3ac031f892af46f255a47d7f54a91317b30.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'charpipe.c')
-rw-r--r-- | charpipe.c | 273 |
1 files changed, 0 insertions, 273 deletions
diff --git a/charpipe.c b/charpipe.c deleted file mode 100644 index d6b9829..0000000 --- a/charpipe.c +++ /dev/null @@ -1,273 +0,0 @@ -/* Copyright (C) 2007-2008 The Android Open Source Project -** -** This software is licensed under the terms of the GNU General Public -** License version 2, as published by the Free Software Foundation, and -** may be copied, distributed, and modified under those terms. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -*/ -#include "qemu-char.h" -#include "cbuffer.h" -#include "qemu_debug.h" - -#define xxDEBUG - -#ifdef DEBUG -# include <stdio.h> -# define D(...) ( fprintf( stderr, __VA_ARGS__ ), fprintf(stderr, "\n") ) -#else -# define D(...) ((void)0) -#endif - -/* we want to implement a bi-directionnal communication channel - * between two QEMU character drivers that merge well into the - * QEMU event loop. - * - * each half of the channel has its own object and buffer, and - * we implement communication through charpipe_poll() which - * must be called by the main event loop after its call to select() - * - */ - -#define BIP_BUFFER_SIZE 512 - -typedef struct BipBuffer { - struct BipBuffer* next; - CBuffer cb[1]; - char buff[ BIP_BUFFER_SIZE ]; -} BipBuffer; - -static BipBuffer* _free_bip_buffers; - -static BipBuffer* -bip_buffer_alloc( void ) -{ - BipBuffer* bip = _free_bip_buffers; - if (bip != NULL) { - _free_bip_buffers = bip->next; - } else { - bip = malloc( sizeof(*bip) ); - if (bip == NULL) { - derror( "%s: not enough memory", __FUNCTION__ ); - exit(1); - } - } - bip->next = NULL; - cbuffer_reset( bip->cb, bip->buff, sizeof(bip->buff) ); - return bip; -} - -static void -bip_buffer_free( BipBuffer* bip ) -{ - bip->next = _free_bip_buffers; - _free_bip_buffers = bip; -} - -/* this models each half of the charpipe */ -typedef struct CharPipeHalf { - CharDriverState cs[1]; - BipBuffer* bip_first; - BipBuffer* bip_last; - struct CharPipeHalf* peer; /* NULL if closed */ -} CharPipeHalf; - - - -static void -charpipehalf_close( CharDriverState* cs ) -{ - CharPipeHalf* ph = cs->opaque; - - while (ph->bip_first) { - BipBuffer* bip = ph->bip_first; - ph->bip_first = bip->next; - bip_buffer_free(bip); - } - ph->bip_last = NULL; - ph->peer = NULL; -} - - -static int -charpipehalf_write( CharDriverState* cs, const uint8_t* buf, int len ) -{ - CharPipeHalf* ph = cs->opaque; - CharPipeHalf* peer = ph->peer; - BipBuffer* bip = ph->bip_last; - int ret = 0; - - D("%s: writing %d bytes to %p: '%s'", __FUNCTION__, - len, ph, quote_bytes( buf, len )); - - if (bip == NULL && peer != NULL && peer->cs->chr_read != NULL) { - /* no buffered data, try to write directly to the peer */ - while (len > 0) { - int size; - - if (peer->cs->chr_can_read) { - size = qemu_chr_can_read( peer->cs ); - if (size == 0) - break; - - if (size > len) - size = len; - } else - size = len; - - qemu_chr_read( peer->cs, (uint8_t*)buf, size ); - buf += size; - len -= size; - ret += size; - } - } - - if (len == 0) - return ret; - - /* buffer the remaining data */ - if (bip == NULL) { - bip = bip_buffer_alloc(); - ph->bip_first = ph->bip_last = bip; - } - - while (len > 0) { - int len2 = cbuffer_write( bip->cb, buf, len ); - - buf += len2; - ret += len2; - len -= len2; - if (len == 0) - break; - - /* ok, we need another buffer */ - ph->bip_last = bip_buffer_alloc(); - bip->next = ph->bip_last; - bip = ph->bip_last; - } - return ret; -} - - -static void -charpipehalf_poll( CharPipeHalf* ph ) -{ - CharPipeHalf* peer = ph->peer; - int size; - - if (peer == NULL || peer->cs->chr_read == NULL) - return; - - while (1) { - BipBuffer* bip = ph->bip_first; - uint8_t* base; - int avail; - - if (bip == NULL) - break; - - size = cbuffer_read_avail(bip->cb); - if (size == 0) { - ph->bip_first = bip->next; - if (ph->bip_first == NULL) - ph->bip_last = NULL; - bip_buffer_free(bip); - continue; - } - - if (ph->cs->chr_can_read) { - int size2 = qemu_chr_can_read(peer->cs); - - if (size2 == 0) - break; - - if (size > size2) - size = size2; - } - - avail = cbuffer_read_peek( bip->cb, &base ); - if (avail > size) - avail = size; - D("%s: sending %d bytes from %p: '%s'", __FUNCTION__, - avail, ph, quote_bytes( base, avail )); - - qemu_chr_read( peer->cs, base, avail ); - cbuffer_read_step( bip->cb, avail ); - } -} - - -static void -charpipehalf_init( CharPipeHalf* ph, CharPipeHalf* peer ) -{ - CharDriverState* cs = ph->cs; - - ph->bip_first = NULL; - ph->bip_last = NULL; - ph->peer = peer; - - cs->chr_write = charpipehalf_write; - cs->chr_ioctl = NULL; - cs->chr_send_event = NULL; - cs->chr_close = charpipehalf_close; - cs->opaque = ph; -} - - -typedef struct CharPipeState { - CharPipeHalf a[1]; - CharPipeHalf b[1]; -} CharPipeState; - - - -#define MAX_CHAR_PIPES 8 - -static CharPipeState _s_charpipes[ MAX_CHAR_PIPES ]; - -int -qemu_chr_open_charpipe( CharDriverState* *pfirst, CharDriverState* *psecond ) -{ - CharPipeState* cp = _s_charpipes; - CharPipeState* cp_end = cp + MAX_CHAR_PIPES; - - for ( ; cp < cp_end; cp++ ) { - if ( cp->a->peer == NULL && cp->b->peer == NULL ) - break; - } - - if (cp == cp_end) { /* can't allocate one */ - *pfirst = NULL; - *psecond = NULL; - return -1; - } - - charpipehalf_init( cp->a, cp->b ); - charpipehalf_init( cp->b, cp->a ); - - *pfirst = cp->a->cs; - *psecond = cp->b->cs; - return 0; -} - -void -charpipe_poll( void ) -{ - CharPipeState* cp = _s_charpipes; - CharPipeState* cp_end = cp + MAX_CHAR_PIPES; - - for ( ; cp < cp_end; cp++ ) { - CharPipeHalf* half; - - half = cp->a; - if (half->peer != NULL) - charpipehalf_poll(half); - - half = cp->b; - if (half->peer != NULL) - charpipehalf_poll(half); - } -} |