sysdeps_win32.c

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

C
1,954
字号
        hook->ready = 0;        if (hook->prepare) {            hook->prepare(hook);            if (hook->ready != 0) {                event_hook_signal( hook );                gotone = 1;            }        }    }    /* nothing's ready yet, so wait for something to happen */    if (!gotone)    {        looper->htab_count = 0;                    for (hook = looper->hooks; hook; hook = hook->next)         {            if (hook->start && !hook->start(hook)) {                D( "fdevent_process: error when starting a hook\n" );                return;            }            if (hook->h != INVALID_HANDLE_VALUE) {                int  nn;                for (nn = 0; nn < looper->htab_count; nn++)                {                    if ( looper->htab[nn] == hook->h )                        goto DontAdd;                }                looper->htab[ looper->htab_count++ ] = hook->h;            DontAdd:                ;            }        }        if (looper->htab_count == 0) {            D( "fdevent_process: nothing to wait for !!\n" );            return;        }        do        {            int   wait_ret;            D( "adb_win32: waiting for %d events\n", looper->htab_count );            if (looper->htab_count > MAXIMUM_WAIT_OBJECTS) {                D("handle count %d exceeds MAXIMUM_WAIT_OBJECTS, aborting!\n", looper->htab_count);                abort();            }            wait_ret = WaitForMultipleObjects( looper->htab_count, looper->htab, FALSE, INFINITE );            if (wait_ret == (int)WAIT_FAILED) {                D( "adb_win32: wait failed, error %ld\n", GetLastError() );            } else {                D( "adb_win32: got one (index %d)\n", wait_ret );                            /* according to Cygwin, some objects like consoles wake up on "inappropriate" events                 * like mouse movements. we need to filter these with the "check" function                 */                if ((unsigned)wait_ret < (unsigned)looper->htab_count)                {                    for (hook = looper->hooks; hook; hook = hook->next)                    {                        if ( looper->htab[wait_ret] == hook->h       &&                         (!hook->check || hook->check(hook)) )                        {                            D( "adb_win32: signaling %s for %x\n", hook->fh->name, hook->ready );                            event_hook_signal( hook );                            gotone = 1;                            break;                        }                    }                }            }        }        while (!gotone);        for (hook = looper->hooks; hook; hook = hook->next) {            if (hook->stop)                hook->stop( hook );        }    }    for (hook = looper->hooks; hook; hook = hook->next) {        if (hook->peek && hook->peek(hook))                event_hook_signal( hook );    }}static void fdevent_register(fdevent *fde){    int  fd = fde->fd - WIN32_FH_BASE;    if(fd < 0) {        FATAL("bogus negative fd (%d)\n", fde->fd);    }        if(fd >= fd_table_max) {        int oldmax = fd_table_max;        if(fde->fd > 32000) {            FATAL("bogus huuuuge fd (%d)\n", fde->fd);        }        if(fd_table_max == 0) {            fdevent_init();            fd_table_max = 256;        }        while(fd_table_max <= fd) {            fd_table_max *= 2;        }        fd_table = realloc(fd_table, sizeof(fdevent*) * fd_table_max);        if(fd_table == 0) {            FATAL("could not expand fd_table to %d entries\n", fd_table_max);        }        memset(fd_table + oldmax, 0, sizeof(int) * (fd_table_max - oldmax));    }    fd_table[fd] = fde;}static void fdevent_unregister(fdevent *fde){    int  fd = fde->fd - WIN32_FH_BASE;        if((fd < 0) || (fd >= fd_table_max)) {        FATAL("fd out of range (%d)\n", fde->fd);    }    if(fd_table[fd] != fde) {        FATAL("fd_table out of sync");    }    fd_table[fd] = 0;    if(!(fde->state & FDE_DONT_CLOSE)) {        dump_fde(fde, "close");        adb_close(fde->fd);    }}static void fdevent_plist_enqueue(fdevent *node){    fdevent *list = &list_pending;    node->next = list;    node->prev = list->prev;    node->prev->next = node;    list->prev = node;}static void fdevent_plist_remove(fdevent *node){    node->prev->next = node->next;    node->next->prev = node->prev;    node->next = 0;    node->prev = 0;}static fdevent *fdevent_plist_dequeue(void){    fdevent *list = &list_pending;    fdevent *node = list->next;        if(node == list) return 0;        list->next = node->next;    list->next->prev = list;    node->next = 0;    node->prev = 0;    return node;}fdevent *fdevent_create(int fd, fd_func func, void *arg){    fdevent *fde = (fdevent*) malloc(sizeof(fdevent));    if(fde == 0) return 0;    fdevent_install(fde, fd, func, arg);    fde->state |= FDE_CREATED;    return fde;}void fdevent_destroy(fdevent *fde){    if(fde == 0) return;    if(!(fde->state & FDE_CREATED)) {        FATAL("fde %p not created by fdevent_create()\n", fde);    }    fdevent_remove(fde);}void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg) {    memset(fde, 0, sizeof(fdevent));    fde->state = FDE_ACTIVE;    fde->fd = fd;    fde->func = func;    fde->arg = arg;    fdevent_register(fde);    dump_fde(fde, "connect");    fdevent_connect(fde);    fde->state |= FDE_ACTIVE;}void fdevent_remove(fdevent *fde){    if(fde->state & FDE_PENDING) {        fdevent_plist_remove(fde);    }    if(fde->state & FDE_ACTIVE) {        fdevent_disconnect(fde);        dump_fde(fde, "disconnect");            fdevent_unregister(fde);    }    fde->state = 0;    fde->events = 0;}void fdevent_set(fdevent *fde, unsigned events){    events &= FDE_EVENTMASK;        if((fde->state & FDE_EVENTMASK) == (int)events) return;        if(fde->state & FDE_ACTIVE) {        fdevent_update(fde, events);        dump_fde(fde, "update");    }    fde->state = (fde->state & FDE_STATEMASK) | events;    if(fde->state & FDE_PENDING) {            /* if we're pending, make sure            ** we don't signal an event that            ** is no longer wanted.            */        fde->events &= (~events);        if(fde->events == 0) {            fdevent_plist_remove(fde);            fde->state &= (~FDE_PENDING);        }    }}void fdevent_add(fdevent *fde, unsigned events){    fdevent_set(        fde, (fde->state & FDE_EVENTMASK) | (events & FDE_EVENTMASK));}void fdevent_del(fdevent *fde, unsigned events){    fdevent_set(        fde, (fde->state & FDE_EVENTMASK) & (~(events & FDE_EVENTMASK)));}void fdevent_loop(){    fdevent *fde;        for(;;) {#if DEBUG        fprintf(stderr,"--- ---- waiting for events\n");#endif        fdevent_process();                while((fde = fdevent_plist_dequeue())) {            unsigned events = fde->events;            fde->events = 0;            fde->state &= (~FDE_PENDING);            dump_fde(fde, "callback");            fde->func(fde->fd, events, fde->arg);        }    }}/**  FILE EVENT HOOKS **/ static void  _event_file_prepare( EventHook  hook ){    if (hook->wanted & (FDE_READ|FDE_WRITE)) {        /* we can always read/write */        hook->ready |= hook->wanted & (FDE_READ|FDE_WRITE);    }}static int  _event_file_peek( EventHook  hook ){    return (hook->wanted & (FDE_READ|FDE_WRITE));}static void  _fh_file_hook( FH  f, int  events, EventHook  hook ){    hook->h       = f->fh_handle;    hook->prepare = _event_file_prepare;    hook->peek    = _event_file_peek;}/** SOCKET EVENT HOOKS **/static void  _event_socket_verify( EventHook  hook, WSANETWORKEVENTS*  evts ){    if ( evts->lNetworkEvents & (FD_READ|FD_ACCEPT|FD_CLOSE) ) {        if (hook->wanted & FDE_READ)            hook->ready |= FDE_READ;        if ((evts->iErrorCode[FD_READ] != 0) && hook->wanted & FDE_ERROR)            hook->ready |= FDE_ERROR;    }    if ( evts->lNetworkEvents & (FD_WRITE|FD_CONNECT|FD_CLOSE) ) {        if (hook->wanted & FDE_WRITE)            hook->ready |= FDE_WRITE;        if ((evts->iErrorCode[FD_WRITE] != 0) && hook->wanted & FDE_ERROR)            hook->ready |= FDE_ERROR;    }    if ( evts->lNetworkEvents & FD_OOB ) {        if (hook->wanted & FDE_ERROR)            hook->ready |= FDE_ERROR;    }}static void  _event_socket_prepare( EventHook  hook ){    WSANETWORKEVENTS  evts;        /* look if some of the events we want already happened ? */    if (!WSAEnumNetworkEvents( hook->fh->fh_socket, NULL, &evts ))        _event_socket_verify( hook, &evts );}static int  _socket_wanted_to_flags( int  wanted ){    int  flags = 0;    if (wanted & FDE_READ)        flags |= FD_READ | FD_ACCEPT | FD_CLOSE;    if (wanted & FDE_WRITE)        flags |= FD_WRITE | FD_CONNECT | FD_CLOSE;    if (wanted & FDE_ERROR)        flags |= FD_OOB;    return flags;}static int _event_socket_start( EventHook  hook ){    /* create an event which we're going to wait for */    FH    fh    = hook->fh;    long  flags = _socket_wanted_to_flags( hook->wanted );        hook->h = fh->event;    if (hook->h == INVALID_HANDLE_VALUE) {        D( "_event_socket_start: no event for %s\n", fh->name );        return 0;    }        if ( flags != fh->mask ) {        D( "_event_socket_start: hooking %s for %x (flags %ld)\n", hook->fh->name, hook->wanted, flags );        if ( WSAEventSelect( fh->fh_socket, hook->h, flags ) ) {            D( "_event_socket_start: WSAEventSelect() for %s failed, error %d\n", hook->fh->name, WSAGetLastError() );            CloseHandle( hook->h );            hook->h = INVALID_HANDLE_VALUE;            exit(1);            return 0;        }        fh->mask = flags;    }    return 1;}static void _event_socket_stop( EventHook  hook ){    hook->h = INVALID_HANDLE_VALUE;}static int  _event_socket_check( EventHook  hook ){    int               result = 0;    FH                fh = hook->fh;    WSANETWORKEVENTS  evts;        if (!WSAEnumNetworkEvents( fh->fh_socket, hook->h, &evts ) ) {        _event_socket_verify( hook, &evts );        result = (hook->ready != 0);        if (result) {            ResetEvent( hook->h );        }    }    D( "_event_socket_check %s returns %d\n", fh->name, result );    return  result;}static int  _event_socket_peek( EventHook  hook ){    WSANETWORKEVENTS  evts;    FH                fh = hook->fh;        /* look if some of the events we want already happened ? */    if (!WSAEnumNetworkEvents( fh->fh_socket, NULL, &evts )) {        _event_socket_verify( hook, &evts );        if (hook->ready)            ResetEvent( hook->h );    }    return hook->ready != 0;}static void  _fh_socket_hook( FH  f, int  events, EventHook  hook ){    hook->prepare = _event_socket_prepare;    hook->start   = _event_socket_start;    hook->stop    = _event_socket_stop;    hook->check   = _event_socket_check;    hook->peek    = _event_socket_peek;        _event_socket_start( hook );}/** SOCKETPAIR EVENT HOOKS **/ static void  _event_socketpair_prepare( EventHook  hook ){    FH          fh   = hook->fh;    SocketPair  pair = fh->fh_pair;    BipBuffer   rbip = (pair->a_fd == fh) ? &pair->b2a_bip : &pair->a2b_bip;    BipBuffer   wbip = (pair->a_fd == fh) ? &pair->a2b_bip : &pair->b2a_bip;       if (hook->wanted & FDE_READ && rbip->can_read)        hook->ready |= FDE_READ;        if (hook->wanted & FDE_WRITE && wbip->can_write)         hook->ready |= FDE_WRITE; }  static int  _event_socketpair_start( EventHook  hook ) {    FH          fh   = hook->fh;    SocketPair  pair = fh->fh_pair;    BipBuffer   rbip = (pair->a_fd == fh) ? &pair->b2a_bip : &pair->a2b_bip;    BipBuffer   wbip = (pair->a_fd == fh) ? &pair->a2b_bip : &pair->b2a_bip;        if (hook->wanted == FDE_READ)        hook->h = rbip->evt_read;            else if (hook->wanted == FDE_WRITE)        hook->h = wbip->evt_write;        else {        D("_event_socketpair_start: can't handle FDE_READ+FDE_WRITE\n" );        return 0;    }    D( "_event_socketpair_start: hook %s for %x wanted=%x\n",        hook->fh->name, _fh_to_int(fh), hook->wanted);    return 1;}static int  _event_socketpair_peek( EventHook  hook ){    _event_socketpair_prepare( hook );    return hook->ready != 0;}static void  _fh_socketpair_hook( FH  fh, int  events, EventHook  hook ){    hook->prepare = _event_socketpair_prepare;    hook->start   = _event_socketpair_start;    hook->peek    = _event_socketpair_peek;}voidadb_sysdeps_init( void ){#define  ADB_MUTEX(x)  InitializeCriticalSection( & x );#include "mutex_list.h"    InitializeCriticalSection( &_win32_lock );}

⌨️ 快捷键说明

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