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 + -
显示快捷键?