int co_epoll_del( int epfd,int fd ) { struct timespec t = { 0 }; struct kevent_pair_t *ptr = ( struct kevent_pair_t* )get_fd_map()->get( fd ); if( !ptr ) return 0; if( EPOLLIN & ptr->events ) { struct kevent kev = { 0 }; kev.ident = fd; kev.filter = EVFILT_READ; kev.flags = EV_DELETE; kevent( epfd,&kev,1, NULL,0,&t ); } if( EPOLLOUT & ptr->events ) { struct kevent kev = { 0 }; kev.ident = fd; kev.filter = EVFILT_WRITE; kev.flags = EV_DELETE; kevent( epfd,&kev,1, NULL,0,&t ); } get_fd_map()->clear( fd ); free( ptr ); return 0; }
void protobuf_c_dispatch_clear_changes (ProtobufCDispatch *dispatch) { RealDispatch *d = (RealDispatch *) dispatch; unsigned i; for (i = 0; i < dispatch->n_changes; i++) { FDMap *fm = get_fd_map (d, dispatch->changes[i].fd); assert (fm->change_index == (int) i); fm->change_index = -1; } dispatch->n_changes = 0; }
static void deallocate_change_index (RealDispatch *d, FDMap *fm) { unsigned ch_ind = fm->change_index; unsigned from = d->base.n_changes - 1; ProtobufC_FD from_fd; fm->change_index = -1; if (ch_ind == from) { d->base.n_changes--; return; } from_fd = d->base.changes[ch_ind].fd; get_fd_map (d, from_fd)->change_index = ch_ind; d->base.changes[ch_ind] = d->base.changes[from]; d->base.n_changes--; }
int safe_remove_from_hash(io_wait_h * h, int fd) { struct fd_map * e; if (fd < 0 || fd > h->max_fd_no) { LM_ERR("Invalid fd : fd = %d max_fd = %d\n", fd, h->max_fd_no); goto error; } e = get_fd_map(h, fd); if (e == NULL) { LM_ERR("Cannot get fd_map from hash\n"); goto error; } unhash_fd_map(e); return 0; error: return -1; }
static void deallocate_notify_desired_index (RealDispatch *d, ProtobufC_FD fd, FDMap *fm) { unsigned nd_ind = fm->notify_desired_index; unsigned from = d->base.n_notifies_desired - 1; ProtobufC_FD from_fd; (void) fd; #if DEBUG_DISPATCH_INTERNALS fprintf (stderr, "deallocate_notify_desired_index: fd=%d, nd_ind=%u\n",fd,nd_ind); #endif fm->notify_desired_index = -1; if (nd_ind == from) { d->base.n_notifies_desired--; return; } from_fd = d->base.notifies_desired[from].fd; get_fd_map (d, from_fd)->notify_desired_index = nd_ind; d->base.notifies_desired[nd_ind] = d->base.notifies_desired[from]; d->callbacks[nd_ind] = d->callbacks[from]; d->base.n_notifies_desired--; }
static inline FDMap * force_fd_map (RealDispatch *d, ProtobufC_FD fd) { #if HAVE_SMALL_FDS ensure_fd_map_big_enough (d, fd); return d->fd_map + fd; #else { FDMap *fm = get_fd_map (d, fd); ProtobufCAllocator *allocator = d->allocator; if (fm == NULL) { FDMapNode *node = ALLOC (sizeof (FDMapNode)); FDMapNode *conflict; node->fd = fd; memset (&node->map, 255, sizeof (FDMap)); GSK_RBTREE_INSERT (GET_FD_MAP_TREE (d), node, conflict); assert (conflict == NULL); fm = &node->map; } return fm; } #endif }
int co_epoll_ctl( int epfd,int op,int fd,struct epoll_event * ev ) { if( EPOLL_CTL_DEL == op ) { return co_epoll_del( epfd,fd ); } const int flags = ( EPOLLIN | EPOLLOUT | EPOLLERR | EPOLLHUP ); if( ev->events & ~flags ) { return -1; } if( EPOLL_CTL_ADD == op && get_fd_map()->get( fd ) ) { errno = EEXIST; return -1; } else if( EPOLL_CTL_MOD == op && !get_fd_map()->get( fd ) ) { errno = ENOENT; return -1; } struct kevent_pair_t *ptr = (struct kevent_pair_t*)get_fd_map()->get( fd ); if( !ptr ) { ptr = (kevent_pair_t*)calloc(1,sizeof(kevent_pair_t)); get_fd_map()->set( fd,ptr ); } int ret = 0; struct timespec t = { 0 }; printf("ptr->events 0x%X\n",ptr->events); if( EPOLL_CTL_MOD == op ) { //1.delete if exists if( ptr->events & EPOLLIN ) { struct kevent kev = { 0 }; EV_SET( &kev,fd,EVFILT_READ,EV_DELETE,0,0,NULL ); kevent( epfd, &kev,1, NULL,0, &t ); } //1.delete if exists if( ptr->events & EPOLLOUT ) { struct kevent kev = { 0 }; EV_SET( &kev,fd,EVFILT_WRITE,EV_DELETE,0,0,NULL ); ret = kevent( epfd, &kev,1, NULL,0, &t ); printf("delete write ret %d\n",ret ); } } do { if( ev->events & EPOLLIN ) { //2.add struct kevent kev = { 0 }; EV_SET( &kev,fd,EVFILT_READ,EV_ADD,0,0,ptr ); ret = kevent( epfd, &kev,1, NULL,0, &t ); if( ret ) break; } if( ev->events & EPOLLOUT ) { //2.add struct kevent kev = { 0 }; EV_SET( &kev,fd,EVFILT_WRITE,EV_ADD,0,0,ptr ); ret = kevent( epfd, &kev,1, NULL,0, &t ); if( ret ) break; } } while( 0 ); if( ret ) { get_fd_map()->clear( fd ); free( ptr ); return ret; } ptr->events = ev->events; ptr->u64 = ev->data.u64; return ret; }