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 }
CDBuffer* CD_CreateBuffer (void) { CDBuffer* self = CD_malloc(sizeof(CDBuffer)); self->raw = evbuffer_new(); self->external = false; evbuffer_enable_locking(self->raw, NULL); return self; }
CDBuffer* CD_WrapBuffer (CDRawBuffer buffer) { CDBuffer* self = CD_malloc(sizeof(CDBuffer)); self->raw = buffer; self->external = true; evbuffer_enable_locking(self->raw, NULL); return self; }
static void thread_libevent_process(int fd, short which, void *arg) { LIBEVENT_THREAD *me = (LIBEVENT_THREAD *)arg; CQ_ITEM *item; char buf[1]; if (read(fd, buf, 1) != 1) merror("can't read from libevent pipe!"); switch(buf[0]) { case 'c': { item = cq_pop(me->new_conn_queue); if (NULL != item) { listener_info *li = (listener_info *)item->data; conn *c = conn_new(); if (NULL == c) { } else { struct bufferevent* bev = bufferevent_socket_new(me->base, item->fd, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS); if (NULL == bev) { merror("create bufferevent failed!"); } else { strncpy(c->addrtext, li->addrtext, 32); evbuffer *input = bufferevent_get_input(bev); evbuffer_enable_locking(input, NULL); bufferevent_setcb(bev, conn_read_cb, conn_write_cb, conn_event_cb, c); bufferevent_enable(bev, EV_READ); c->data = li->l; c->bev = bev; c->thread = me; mdebug("new connection %s established!", c->addrtext); } } free(item->data); cqi_free(item); } } break; case 't': { item = cq_pop(me->new_conn_queue); if (NULL != item) { connector *cr = (connector *)item->data; conn *c = conn_new(); if (NULL == c) { } else { struct bufferevent *bev = bufferevent_socket_new(me->base, -1, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS); if (NULL == bev) { merror("create bufferevent failed!"); } else { evbuffer *input = bufferevent_get_input(bev); evbuffer_enable_locking(input, NULL); bufferevent_setcb(bev, NULL, NULL, connecting_event_cb, c); c->bev = bev; c->data = cr; c->thread = me; cr->c = c; cr->state = STATE_NOT_CONNECTED; minfo("connecting %s!", cr->addrtext); bufferevent_socket_connect(c->bev, cr->sa, cr->socklen); } } cqi_free(item); } } break; case 'k': { event_base_loopbreak(me->base); } break; } }