int bufferevent_enable_locking(struct bufferevent *bufev, void *lock) { #ifdef _EVENT_DISABLE_THREAD_SUPPORT return -1; #else struct bufferevent *underlying; if (BEV_UPCAST(bufev)->lock) return -1; underlying = bufferevent_get_underlying(bufev); if (!lock && underlying && BEV_UPCAST(underlying)->lock) { lock = BEV_UPCAST(underlying)->lock; BEV_UPCAST(bufev)->lock = lock; BEV_UPCAST(bufev)->own_lock = 0; } else if (!lock) { EVTHREAD_ALLOC_LOCK(lock, EVTHREAD_LOCKTYPE_RECURSIVE); if (!lock) return -1; BEV_UPCAST(bufev)->lock = lock; BEV_UPCAST(bufev)->own_lock = 1; } else { BEV_UPCAST(bufev)->lock = lock; BEV_UPCAST(bufev)->own_lock = 0; } evbuffer_enable_locking(bufev->input, lock); evbuffer_enable_locking(bufev->output, lock); if (underlying && !BEV_UPCAST(underlying)->lock) bufferevent_enable_locking(underlying, lock); return 0; #endif }
static void _bufferevent_transfer_lock_ownership(struct bufferevent *donor, struct bufferevent *recipient) { struct bufferevent_private *d = BEV_UPCAST(donor); struct bufferevent_private *r = BEV_UPCAST(recipient); if (d->lock != r->lock) return; if (r->own_lock) return; if (d->own_lock) { d->own_lock = 0; r->own_lock = 1; } }
void _bufferevent_incref_and_lock(struct bufferevent *bufev) { struct bufferevent_private *bufev_private = BEV_UPCAST(bufev); BEV_LOCK(bufev); ++bufev_private->refcnt; }
static void be_async_destruct(struct bufferevent *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); /* XXX cancel any outstanding I/O operations */ fd = _evbuffer_overlapped_get_fd(bev->input); /* delete this in case non-blocking connect was used */ event_del(&bev->ev_write); if (bev_p->options & BEV_OPT_CLOSE_ON_FREE) EVUTIL_CLOSESOCKET(fd); _bufferevent_del_generic_timeout_cbs(bev); }
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); } }