sysdeps_win32.c

来自「Android 一些工具」· C语言 代码 · 共 1,954 行 · 第 1/4 页

C
1,954
字号
        bip->can_read = 1;        SetEvent( bip->evt_read );    }      BIPD(( "bip_buffer_write: exit %d->%d count %d (as=%d ae=%d be=%d cw=%d cr=%d\n",             bip->fdin, bip->fdout, count, bip->a_start, bip->a_end, bip->b_end, bip->can_write, bip->can_read ));    LeaveCriticalSection( &bip->lock );    return count; }static intbip_buffer_read( BipBuffer  bip, void*  dst, int  len ){    int  avail, count = 0;        if (len <= 0)        return 0;        BIPD(( "bip_buffer_read: enter %d->%d len %d\n", bip->fdin, bip->fdout, len ));        EnterCriticalSection( &bip->lock );    while ( !bip->can_read )    {#if 0        LeaveCriticalSection( &bip->lock );        errno = EAGAIN;        return -1;#else            int  ret;        LeaveCriticalSection( &bip->lock );                if (bip->closed) {            errno = EPIPE;            return -1;        }        ret = WaitForSingleObject( bip->evt_read, INFINITE );        if (ret != WAIT_OBJECT_0) { /* probably closed buffer */            D( "bip_buffer_read: error %d->%d WaitForSingleObject returned %d, error %ld\n", bip->fdin, bip->fdout, ret, GetLastError());            return 0;        }        if (bip->closed) {            errno = EPIPE;            return -1;        }        EnterCriticalSection( &bip->lock );#endif            }    BIPD(( "bip_buffer_read: exec %d->%d len %d\n", bip->fdin, bip->fdout, len ));       avail = bip->a_end - bip->a_start;    assert( avail > 0 );  /* since can_read is TRUE */        if (avail > len)        avail = len;        memcpy( dst, bip->buff + bip->a_start, avail );    dst   += avail;    count += avail;    len   -= avail;        bip->a_start += avail;    if (bip->a_start < bip->a_end)        goto Exit;        bip->a_start = 0;    bip->a_end   = bip->b_end;    bip->b_end   = 0;        avail = bip->a_end;    if (avail > 0) {        if (avail > len)            avail = len;        memcpy( dst, bip->buff, avail );        count += avail;        bip->a_start += avail;                if ( bip->a_start < bip->a_end )            goto Exit;                    bip->a_start = bip->a_end = 0;    }        bip->can_read = 0;    ResetEvent( bip->evt_read );Exit:    assert( count > 0 );    if (!bip->can_write ) {        bip->can_write = 1;        SetEvent( bip->evt_write );    }        BIPDUMP( (const unsigned char*)dst - count, count );    BIPD(( "bip_buffer_read: exit %d->%d count %d (as=%d ae=%d be=%d cw=%d cr=%d\n",             bip->fdin, bip->fdout, count, bip->a_start, bip->a_end, bip->b_end, bip->can_write, bip->can_read ));    LeaveCriticalSection( &bip->lock );        return count;} typedef struct SocketPairRec_ {    BipBufferRec  a2b_bip;    BipBufferRec  b2a_bip;    FH            a_fd;    int           used;    } SocketPairRec;void _fh_socketpair_init( FH  f ){    f->fh_pair = NULL;}static int_fh_socketpair_close( FH  f ){    if ( f->fh_pair ) {        SocketPair  pair = f->fh_pair;        if ( f == pair->a_fd ) {            pair->a_fd = NULL;        }                bip_buffer_close( &pair->b2a_bip );        bip_buffer_close( &pair->a2b_bip );        if ( --pair->used == 0 ) {            bip_buffer_done( &pair->b2a_bip );            bip_buffer_done( &pair->a2b_bip );            free( pair );        }        f->fh_pair = NULL;    }    return 0;}static int_fh_socketpair_lseek( FH  f, int pos, int  origin ){    errno = ESPIPE;    return -1;}static int_fh_socketpair_read( FH  f, void* buf, int  len ){    SocketPair  pair = f->fh_pair;    BipBuffer   bip;    if (!pair)        return -1;    if ( f == pair->a_fd )        bip = &pair->b2a_bip;    else        bip = &pair->a2b_bip;    return bip_buffer_read( bip, buf, len );}static int_fh_socketpair_write( FH  f, const void*  buf, int  len ){    SocketPair  pair = f->fh_pair;    BipBuffer   bip;    if (!pair)        return -1;    if ( f == pair->a_fd )        bip = &pair->a2b_bip;    else        bip = &pair->b2a_bip;    return bip_buffer_write( bip, buf, len );}static void  _fh_socketpair_hook( FH  f, int  event, EventHook  hook );  /* forward */static const FHClassRec  _fh_socketpair_class ={    _fh_socketpair_init,    _fh_socketpair_close,    _fh_socketpair_lseek,    _fh_socketpair_read,    _fh_socketpair_write,    _fh_socketpair_hook};int  adb_socketpair( int  sv[2] ){    FH          fa, fb;    SocketPair  pair;    fa = _fh_alloc( &_fh_socketpair_class );    fb = _fh_alloc( &_fh_socketpair_class );    if (!fa || !fb)        goto Fail;    pair = malloc( sizeof(*pair) );    if (pair == NULL) {        D("adb_socketpair: not enough memory to allocate pipes\n" );        goto Fail;    }    bip_buffer_init( &pair->a2b_bip );    bip_buffer_init( &pair->b2a_bip );    fa->fh_pair = pair;    fb->fh_pair = pair;    pair->used  = 2;    pair->a_fd  = fa;    sv[0] = _fh_to_int(fa);    sv[1] = _fh_to_int(fb);        pair->a2b_bip.fdin  = sv[0];    pair->a2b_bip.fdout = sv[1];    pair->b2a_bip.fdin  = sv[1];    pair->b2a_bip.fdout = sv[0];    snprintf( fa->name, sizeof(fa->name), "%d(pair:%d)", sv[0], sv[1] );    snprintf( fb->name, sizeof(fb->name), "%d(pair:%d)", sv[1], sv[0] );    D( "adb_socketpair: returns (%d, %d)\n", sv[0], sv[1] );    return 0;Fail:    _fh_close(fb);    _fh_close(fa);    return -1;}/**************************************************************************//**************************************************************************//*****                                                                *****//*****    fdevents emulation                                          *****//*****                                                                *****//*****   this is a very simple implementation, we rely on the fact    *****//*****   that ADB doesn't use FDE_ERROR.                              *****//*****                                                                *****//**************************************************************************//**************************************************************************/#define FATAL(x...) fatal(__FUNCTION__, x)#if DEBUGstatic void dump_fde(fdevent *fde, const char *info){    fprintf(stderr,"FDE #%03d %c%c%c %s\n", fde->fd,            fde->state & FDE_READ ? 'R' : ' ',            fde->state & FDE_WRITE ? 'W' : ' ',            fde->state & FDE_ERROR ? 'E' : ' ',            info);}#else#define dump_fde(fde, info) do { } while(0)#endif#define FDE_EVENTMASK  0x00ff#define FDE_STATEMASK  0xff00#define FDE_ACTIVE     0x0100#define FDE_PENDING    0x0200#define FDE_CREATED    0x0400static void fdevent_plist_enqueue(fdevent *node);static void fdevent_plist_remove(fdevent *node);static fdevent *fdevent_plist_dequeue(void);static fdevent list_pending = {    .next = &list_pending,    .prev = &list_pending,};static fdevent **fd_table = 0;static int       fd_table_max = 0;typedef struct EventLooperRec_*  EventLooper;typedef struct EventHookRec_{    EventHook    next;    FH           fh;    HANDLE       h;    int          wanted;   /* wanted event flags */    int          ready;    /* ready event flags  */    void*        aux;    void        (*prepare)( EventHook  hook );    int         (*start)  ( EventHook  hook );    void        (*stop)   ( EventHook  hook );    int         (*check)  ( EventHook  hook );    int         (*peek)   ( EventHook  hook );} EventHookRec;static EventHook  _free_hooks;static EventHookevent_hook_alloc( FH  fh ){    EventHook  hook = _free_hooks;    if (hook != NULL)        _free_hooks = hook->next;    else {        hook = malloc( sizeof(*hook) );        if (hook == NULL)            fatal( "could not allocate event hook\n" );    }    hook->next   = NULL;    hook->fh     = fh;    hook->wanted = 0;    hook->ready  = 0;    hook->h      = INVALID_HANDLE_VALUE;    hook->aux    = NULL;    hook->prepare = NULL;    hook->start   = NULL;    hook->stop    = NULL;    hook->check   = NULL;    hook->peek    = NULL;        return hook;}static voidevent_hook_free( EventHook  hook ){    hook->fh     = NULL;    hook->wanted = 0;    hook->ready  = 0;    hook->next   = _free_hooks;    _free_hooks  = hook;}static voidevent_hook_signal( EventHook  hook ){    FH        f   = hook->fh;    int       fd  = _fh_to_int(f);    fdevent*  fde = fd_table[ fd - WIN32_FH_BASE ];        if (fde != NULL && fde->fd == fd) {        if ((fde->state & FDE_PENDING) == 0) {            fde->state |= FDE_PENDING;            fdevent_plist_enqueue( fde );        }        fde->events |= hook->wanted;    }}#define  MAX_LOOPER_HANDLES  WIN32_MAX_FHStypedef struct EventLooperRec_{    EventHook    hooks;    HANDLE       htab[ MAX_LOOPER_HANDLES ];    int          htab_count;} EventLooperRec;static EventHook*event_looper_find_p( EventLooper  looper, FH  fh ){    EventHook  *pnode = &looper->hooks;    EventHook   node  = *pnode;    for (;;) {        if ( node == NULL || node->fh == fh )            break;        pnode = &node->next;        node  = *pnode;    }    return  pnode;}static voidevent_looper_hook( EventLooper  looper, int  fd, int  events ){    FH          f = _fh_from_int(fd);    EventHook  *pnode;    EventHook   node;        if (f == NULL)  /* invalid arg */ {        D("event_looper_hook: invalid fd=%d\n", fd);        return;    }    pnode = event_looper_find_p( looper, f );    node  = *pnode;    if ( node == NULL ) {        node       = event_hook_alloc( f );        node->next = *pnode;        *pnode     = node;    }    if ( (node->wanted & events) != events ) {        /* this should update start/stop/check/peek */        D("event_looper_hook: call hook for %d (new=%x, old=%x)\n",           fd, node->wanted, events);        f->clazz->_fh_hook( f, events & ~node->wanted, node );        node->wanted |= events;    } else {        D("event_looper_hook: ignoring events %x for %d wanted=%x)\n",            events, fd, node->wanted);    }}static voidevent_looper_unhook( EventLooper  looper, int  fd, int  events ){    FH          fh    = _fh_from_int(fd);    EventHook  *pnode = event_looper_find_p( looper, fh );    EventHook   node  = *pnode;        if (node != NULL) {        int  events2 = events & node->wanted;        if ( events2 == 0 ) {            D( "event_looper_unhook: events %x not registered for fd %d\n", events, fd );            return;        }        node->wanted &= ~events2;        if (!node->wanted) {            *pnode = node->next;            event_hook_free( node );        }    }}static EventLooperRec  win32_looper;static void fdevent_init(void){    win32_looper.htab_count = 0;    win32_looper.hooks      = NULL;}static void fdevent_connect(fdevent *fde){    EventLooper  looper = &win32_looper;    int          events = fde->state & FDE_EVENTMASK;        if (events != 0)        event_looper_hook( looper, fde->fd, events );}static void fdevent_disconnect(fdevent *fde){    EventLooper  looper = &win32_looper;    int          events = fde->state & FDE_EVENTMASK;        if (events != 0)        event_looper_unhook( looper, fde->fd, events );}static void fdevent_update(fdevent *fde, unsigned events){    EventLooper  looper  = &win32_looper;    unsigned     events0 = fde->state & FDE_EVENTMASK;    if (events != events0) {        int  removes = events0 & ~events;        int  adds    = events  & ~events0;        if (removes) {            D("fdevent_update: remove %x from %d\n", removes, fde->fd);            event_looper_unhook( looper, fde->fd, removes );        }        if (adds) {            D("fdevent_update: add %x to %d\n", adds, fde->fd);            event_looper_hook  ( looper, fde->fd, adds );        }    }}static void fdevent_process(){    EventLooper  looper = &win32_looper;    EventHook    hook;    int          gotone = 0;        /* if we have at least one ready hook, execute it/them */    for (hook = looper->hooks; hook; hook = hook->next) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?