static void bev_async_consider_reading(struct bufferevent_async *beva) { size_t cur_size; size_t read_high; size_t at_most; int limit; struct bufferevent *bev = &beva->bev.bev; /* Don't read if there is a read in progress, or we do not * want to read. */ if (beva->read_in_progress || beva->bev.connecting) return; if (!beva->ok || !(bev->enabled&EV_READ)) { bev_async_del_read(beva); return; } /* Don't read if we're full */ cur_size = evbuffer_get_length(bev->input); read_high = bev->wm_read.high; if (read_high) { if (cur_size >= read_high) { bev_async_del_read(beva); return; } at_most = read_high - cur_size; } else { at_most = 16384; /* FIXME totally magic. */ } /* XXXX This over-commits. */ /* XXXX see also not above on cast on _bufferevent_get_write_max() */ limit = (int)_bufferevent_get_read_max(&beva->bev); if (at_most >= (size_t)limit && limit >= 0) at_most = limit; if (beva->bev.read_suspended) { bev_async_del_read(beva); return; } bufferevent_incref(bev); if (evbuffer_launch_read(bev->input, at_most, &beva->read_overlapped)) { beva->ok = 0; _bufferevent_run_eventcb(bev, BEV_EVENT_ERROR); bufferevent_decref(bev); } else { beva->read_in_progress = at_most; _bufferevent_decrement_read_buckets(&beva->bev, at_most); bev_async_add_read(beva); } return; }
static int be_async_disable(struct bufferevent *bev, short what) { struct bufferevent_async *bev_async = upcast(bev); /* XXXX If we disable reading or writing, we may want to consider * canceling any in-progress read or write operation, though it might * not work. */ if (what & EV_READ) { BEV_DEL_GENERIC_READ_TIMEOUT(bev); bev_async_del_read(bev_async); } if (what & EV_WRITE) { BEV_DEL_GENERIC_WRITE_TIMEOUT(bev); bev_async_del_write(bev_async); } return 0; }
static void be_async_destruct(struct bufferevent *bev) { struct bufferevent_async *bev_async = upcast(bev); struct bufferevent_private *bev_p = BEV_UPCAST(bev); evutil_socket_t fd; EVUTIL_ASSERT(!upcast(bev)->write_in_progress && !upcast(bev)->read_in_progress); bev_async_del_read(bev_async); bev_async_del_write(bev_async); fd = evbuffer_overlapped_get_fd_(bev->input); if (bev_p->options & BEV_OPT_CLOSE_ON_FREE) { /* XXXX possible double-close */ ld_evutil_closesocket(fd); } }
static void be_async_destruct(struct bufferevent *bev) { struct bufferevent_async *bev_async = upcast(bev); struct bufferevent_private *bev_p = BEV_UPCAST(bev); evutil_socket_t fd; EVUTIL_ASSERT(!upcast(bev)->write_in_progress && !upcast(bev)->read_in_progress); bev_async_del_read(bev_async); bev_async_del_write(bev_async); fd = evbuffer_overlapped_get_fd_(bev->input); if (fd != (evutil_socket_t)INVALID_SOCKET && (bev_p->options & BEV_OPT_CLOSE_ON_FREE)) { evutil_closesocket(fd); evbuffer_overlapped_set_fd_(bev->input, INVALID_SOCKET); } }
static void be_async_destruct(struct bufferevent *bev) { struct bufferevent_async *bev_async = upcast(bev); struct bufferevent_private *bev_p = BEV_UPCAST(bev); evutil_socket_t fd; EVUTIL_ASSERT(!upcast(bev)->write_in_progress && !upcast(bev)->read_in_progress); bev_async_del_read(bev_async); bev_async_del_write(bev_async); fd = _evbuffer_overlapped_get_fd(bev->input); if (bev_p->options & BEV_OPT_CLOSE_ON_FREE) { /* XXXX possible double-close */ evutil_closesocket(fd); } /* delete this in case non-blocking connect was used */ if (event_initialized(&bev->ev_write)) { event_del(&bev->ev_write); _bufferevent_del_generic_timeout_cbs(bev); } }