⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 selector.c

📁 This project provides a proxy that allows telnet/tcp connections to be made to serial ports on a mac
💻 C
📖 第 1 页 / 共 2 页
字号:
	parent->up = elem;	parent->left = tmp1;	if (parent->left)	    parent->left->up = parent;	parent->right = tmp2;	if (parent->right)	    parent->right->up = parent;	if (*last == elem)	    *last = parent;	parent = elem->up;    }}static voidsend_down(sel_timer_t *elem, sel_timer_t **top, sel_timer_t **last){    sel_timer_t *tmp1, *tmp2, *left, *right;    left = elem->left;    while (left) {	right = elem->right;	/* Choose the smaller of the two below me to swap with. */	if ((right) && (cmp_timeval(&left->timeout, &right->timeout) > 0)) {	    if (cmp_timeval(&elem->timeout, &right->timeout) > 0) {		/* Swap with the right element. */		tmp1 = right->left;		tmp2 = right->right;		if (elem->up) {		    if (elem->up->left == elem) {			elem->up->left = right;		    } else {			elem->up->right = right;		    }		} else {		    *top = right;		}		right->up = elem->up;		elem->up = right;		right->left = elem->left;		right->right = elem;		elem->left = tmp1;		elem->right = tmp2;		if (right->left)		    right->left->up = right;		if (elem->left)		    elem->left->up = elem;		if (elem->right)		    elem->right->up = elem;		if (*last == right)		    *last = elem;	    } else		goto done;	} else {	    /* The left element is smaller, or the right doesn't exist. */	    if (cmp_timeval(&elem->timeout, &left->timeout) > 0) {		/* Swap with the left element. */		tmp1 = left->left;		tmp2 = left->right;		if (elem->up) {		    if (elem->up->left == elem) {			elem->up->left = left;		    } else {			elem->up->right = left;		    }		} else {		    *top = left;		}		left->up = elem->up;		elem->up = left;		left->left = elem;		left->right = elem->right;		elem->left = tmp1;		elem->right = tmp2;		if (left->right)		    left->right->up = left;		if (elem->left)		    elem->left->up = elem;		if (elem->right)		    elem->right->up = elem;		if (*last == left)		    *last = elem;	    } else		goto done;	}	left = elem->left;    }done:    return;}static voidadd_to_heap(sel_timer_t **top, sel_timer_t **last, sel_timer_t *elem){    sel_timer_t **next;    sel_timer_t *parent;#ifdef MASSIVE_DEBUG    fprintf(*debug_out, "add_to_heap entry\n");    print_tree(*top, *last);    check_tree(*top, *last);#endif    elem->left = NULL;    elem->right = NULL;    elem->up = NULL;    if (*top == NULL) {	*top = elem;	*last = elem;	goto out;    }    find_next_pos(*last, &next, &parent);    *next = elem;    elem->up = parent;    *last = elem;    if (cmp_timeval(&elem->timeout, &parent->timeout) < 0) {	send_up(elem, top, last);    } out:#ifdef MASSIVE_DEBUG    fprintf(*debug_out, "add_to_heap exit\n");    print_tree(*top, *last);    check_tree(*top, *last);#endif    return;}static voidremove_from_heap(sel_timer_t **top, sel_timer_t **last, sel_timer_t *elem){    sel_timer_t *to_insert;#ifdef MASSIVE_DEBUG    fprintf(*debug_out, "remove_from_head entry\n");    print_tree(*top, *last);    check_tree(*top, *last);#endif    /* First remove the last element from the tree, if it's not what's       being removed, we will use it for insertion into the removal       place. */    to_insert = *last;    if (! to_insert->up) {	/* This is the only element in the heap. */	*top = NULL;	*last = NULL;	goto out;    } else {	/* Set the new last position, and remove the item we will           insert. */	find_prev_elem(to_insert, last);	if (to_insert->up->left == to_insert) {	    to_insert->up->left = NULL;	} else {	    to_insert->up->right = NULL;	}    }    if (elem == to_insert) {	/* We got lucky and removed the last element.  We are done. */	goto out;    }    /* Now stick the formerly last element into the removed element's       position. */    if (elem->up) {	if (elem->up->left == elem) {	    elem->up->left = to_insert;	} else {	    elem->up->right = to_insert;	}    } else {	/* The head of the tree is being replaced. */	*top = to_insert;    }    to_insert->up = elem->up;    if (elem->left)	elem->left->up = to_insert;    if (elem->right)	elem->right->up = to_insert;    to_insert->left = elem->left;    to_insert->right = elem->right;    if (*last == elem)	*last = to_insert;    elem = to_insert;    /* Now propigate it to the right place in the tree. */    if (elem->up && cmp_timeval(&elem->timeout, &elem->up->timeout) < 0) {	send_up(elem, top, last);    } else {	send_down(elem, top, last);    } out:#ifdef MASSIVE_DEBUG    fprintf(*debug_out, "remove_from_head exit\n");    print_tree(*top, *last);    check_tree(*top, *last);#endif    return;}intsel_alloc_timer(selector_t            *sel,		sel_timeout_handler_t handler,		void                  *user_data,		sel_timer_t           **new_timer){    sel_timer_t *timer;    timer = malloc(sizeof(*timer));    if (!timer)	return ENOMEM;    timer->handler = handler;    timer->user_data = user_data;    timer->in_heap = 0;    timer->sel = sel;    *new_timer = timer;    return 0;}intsel_free_timer(sel_timer_t *timer){    if (timer->in_heap) {	sel_stop_timer(timer);    }    free(timer);    return 0;}intsel_start_timer(sel_timer_t    *timer,		struct timeval *timeout){    if (timer->in_heap)	return EBUSY;    timer->timeout = *timeout;    add_to_heap(&(timer->sel->timer_top), &(timer->sel->timer_last), timer);    timer->in_heap = 1;    return 0;}intsel_stop_timer(sel_timer_t *timer){    if (!timer->in_heap)	return ETIMEDOUT;    remove_from_heap(&(timer->sel->timer_top),		     &(timer->sel->timer_last),		     timer);    timer->in_heap = 0;    return 0;}/* The main loop for the program.  This will select on the various   sets, then scan for any available I/O to process.  It also monitors   the time and call the timeout handlers periodically. */voidsel_select_loop(selector_t *sel){    fd_set      tmp_read_set;    fd_set      tmp_write_set;    fd_set      tmp_except_set;    int         i;    int         err;    sel_timer_t *timer;    struct timeval timeout, *to_time;    for (;;) {	if (sel->timer_top) {	    struct timeval now;	    /* Check for timers to time out. */	    gettimeofday(&now, NULL);	    timer = sel->timer_top;	    while (cmp_timeval(&now, &timer->timeout) >= 0) {		remove_from_heap(&(sel->timer_top),				 &(sel->timer_last),				 timer);		timer->in_heap = 0;		timer->handler(sel, timer, timer->user_data);		timer = sel->timer_top;		gettimeofday(&now, NULL);		if (!timer)		    goto no_timers;	    }	    /* Calculate how long to wait now. */	    diff_timeval(&timeout, &sel->timer_top->timeout, &now);	    to_time = &timeout;	} else {	no_timers:	    to_time = NULL;	}	memcpy(&tmp_read_set, &sel->read_set, sizeof(tmp_read_set));	memcpy(&tmp_write_set, &sel->write_set, sizeof(tmp_write_set));	memcpy(&tmp_except_set, &sel->except_set, sizeof(tmp_except_set));	err = select(sel->maxfd+1,		     &tmp_read_set,		     &tmp_write_set,		     &tmp_except_set,		     to_time);	if (err == 0) {	    /* A timeout occurred. */	} else if (err < 0) {	    /* An error occurred. */	    if (errno == EINTR) {		/* EINTR is ok, just restart the operation. */		timeout.tv_sec = 1;		timeout.tv_usec = 0;	    } else {		/* An error is bad, we need to abort. */		syslog(LOG_ERR, "select_loop() - select: %m");		exit(1);	    }	} else {	    /* We got some I/O. */	    for (i=0; i<=sel->maxfd; i++) {		if (FD_ISSET(i, &tmp_read_set)) {		    if (sel->fds[i].handle_read == NULL) {			/* Somehow we don't have a handler for this.                           Just shut it down. */			sel_set_fd_read_handler(sel, i, SEL_FD_HANDLER_DISABLED);		    } else {			sel->fds[i].handle_read(i, sel->fds[i].data);		    }		}		if (FD_ISSET(i, &tmp_write_set)) {		    if (sel->fds[i].handle_write == NULL) {			/* Somehow we don't have a handler for this.                           Just shut it down. */			sel_set_fd_write_handler(sel, i, SEL_FD_HANDLER_DISABLED);		    } else {			sel->fds[i].handle_write(i, sel->fds[i].data);		    }		}		if (FD_ISSET(i, &tmp_except_set)) {		    if (sel->fds[i].handle_except == NULL) {			/* Somehow we don't have a handler for this.                           Just shut it down. */			sel_set_fd_except_handler(sel, i, SEL_FD_HANDLER_DISABLED);		    } else {			sel->fds[i].handle_except(i, sel->fds[i].data);		    }		}	    }	}	if (got_sighup) {	    got_sighup = 0;	    if (user_sighup_handler != NULL) {		user_sighup_handler();	    }	}    }}/* Initialize the select code. */intsel_alloc_selector(selector_t **new_selector){    selector_t *sel;    int        i;    sel = malloc(sizeof(*sel));    if (!sel)	return ENOMEM;    FD_ZERO(&sel->read_set);    FD_ZERO(&sel->write_set);    FD_ZERO(&sel->except_set);    for (i=0; i<FD_SETSIZE; i++) {	init_fd(&(sel->fds[i]));    }    sel->timer_top = NULL;    sel->timer_last = NULL;    *new_selector = sel;    return 0;}static voidfree_heap_element(sel_timer_t *elem){    if (!elem)	return;    free_heap_element(elem->left);    free_heap_element(elem->right);    free(elem);}intsel_free_selector(selector_t *sel){    sel_timer_t *heap;    heap = sel->timer_top;    free(sel);    free_heap_element(heap);    return 0;}voidset_sighup_handler(t_sighup_handler handler){    user_sighup_handler = handler;}void sighup_handler(int sig){    got_sighup = 1;}voidsetup_sighup(void){    struct sigaction act;    int              err;    act.sa_handler = sighup_handler;    sigemptyset(&act.sa_mask);    act.sa_flags = SA_RESTART;    err = sigaction(SIGHUP, &act, NULL);    if (err) {	perror("sigaction");    }}

⌨️ 快捷键说明

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