static void bufferevent_run_deferred_callbacks_unlocked(struct deferred_cb *_, void *arg) { struct bufferevent_private *bufev_private = arg; struct bufferevent *bufev = &bufev_private->bev; BEV_LOCK(bufev); #define UNLOCKED(stmt) \ do { BEV_UNLOCK(bufev); stmt; BEV_LOCK(bufev); } while(0) if ((bufev_private->eventcb_pending & BEV_EVENT_CONNECTED) && bufev->errorcb) { /* The "connected" happened before any reads or writes, so send it first. */ bufferevent_event_cb errorcb = bufev->errorcb; void *cbarg = bufev->cbarg; bufev_private->eventcb_pending &= ~BEV_EVENT_CONNECTED; UNLOCKED(errorcb(bufev, BEV_EVENT_CONNECTED, cbarg)); } if (bufev_private->readcb_pending && bufev->readcb) { bufferevent_data_cb readcb = bufev->readcb; void *cbarg = bufev->cbarg; bufev_private->readcb_pending = 0; UNLOCKED(readcb(bufev, cbarg)); } if (bufev_private->writecb_pending && bufev->writecb) { bufferevent_data_cb writecb = bufev->writecb; void *cbarg = bufev->cbarg; bufev_private->writecb_pending = 0; UNLOCKED(writecb(bufev, cbarg)); } if (bufev_private->eventcb_pending && bufev->errorcb) { bufferevent_event_cb errorcb = bufev->errorcb; void *cbarg = bufev->cbarg; short what = bufev_private->eventcb_pending; int err = bufev_private->errno_pending; bufev_private->eventcb_pending = 0; bufev_private->errno_pending = 0; EVUTIL_SET_SOCKET_ERROR(err); UNLOCKED(errorcb(bufev,what,cbarg)); } _bufferevent_decref_and_unlock(bufev); #undef UNLOCKED }
static void eventcb(struct bufferevent *bev, short what, void *ctx) { struct bufferevent *partner = ctx; if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) { if (what & BEV_EVENT_ERROR) { unsigned long err; while ((err = (bufferevent_get_openssl_error(bev)))) { const char *msg = (const char*) ERR_reason_error_string(err); const char *lib = (const char*) ERR_lib_error_string(err); const char *func = (const char*) ERR_func_error_string(err); fprintf(stderr, "%s in %s %s\n", msg, lib, func); } if (errno) perror("connection error"); } if (partner) { /* Flush all pending data */ readcb(bev, ctx); if (evbuffer_get_length( bufferevent_get_output(partner))) { /* We still have to flush data from the other * side, but when that's done, close the other * side. */ bufferevent_setcb(partner, NULL, close_on_finished_writecb, eventcb, NULL); bufferevent_disable(partner, EV_READ); } else { /* We have nothing left to say to the other * side; close it. */ bufferevent_free(partner); } } bufferevent_free(bev); } }
static void eventcb (struct bufferevent *bev, short what, void *ctx) { struct bufferevent * partner = getpartner (bev, (pcallback_info) ctx); if (what & (BEV_EVENT_EOF | BEV_EVENT_ERROR)) { if (what & BEV_EVENT_ERROR) { if (errno) perror ("connection error"); } if (partner) { /* Flush all pending data */ readcb (bev, ctx); if (evbuffer_get_length (bufferevent_get_output (partner))) { /* We still have to flush data from the other * side, but when that's done, close the other * side. */ bufferevent_setcb (partner, NULL, close_on_finished_writecb, eventcb, NULL); bufferevent_disable (partner, EV_READ); } else { /* We have nothing left to say to the other * side; close it. */ bufferevent_free (partner); } } bufferevent_free (bev); } }