struct bufferevent * bufferevent_async_new_(struct event_base *base, evutil_socket_t fd, int options) { struct bufferevent_async *bev_a; struct bufferevent *bev; struct event_iocp_port *iocp; options |= BEV_OPT_THREADSAFE; if (!(iocp = event_base_get_iocp_(base))) return NULL; if (fd >= 0 && event_iocp_port_associate_(iocp, fd, 1)<0) { int err = GetLastError(); /* We may have alrady associated this fd with a port. * Let's hope it's this port, and that the error code * for doing this neer changes. */ if (err != ERROR_INVALID_PARAMETER) return NULL; } if (!(bev_a = mm_calloc(1, sizeof(struct bufferevent_async)))) return NULL; bev = &bev_a->bev.bev; if (!(bev->input = evbuffer_overlapped_new_(fd))) { mm_free(bev_a); return NULL; } if (!(bev->output = evbuffer_overlapped_new_(fd))) { evbuffer_free(bev->input); mm_free(bev_a); return NULL; } if (bufferevent_init_common_(&bev_a->bev, base, &bufferevent_ops_async, options)<0) goto err; evbuffer_add_cb(bev->input, be_async_inbuf_callback, bev); evbuffer_add_cb(bev->output, be_async_outbuf_callback, bev); event_overlapped_init_(&bev_a->connect_overlapped, connect_complete); event_overlapped_init_(&bev_a->read_overlapped, read_complete); event_overlapped_init_(&bev_a->write_overlapped, write_complete); bev_a->ok = fd >= 0; if (bev_a->ok) bufferevent_init_generic_timeout_cbs_(bev); return bev; err: bufferevent_free(&bev_a->bev.bev); return NULL; }
static struct accepting_socket * new_accepting_socket(struct evconnlistener_iocp *lev, int family) { struct accepting_socket *res; int addrlen; int buflen; if (family == AF_INET) addrlen = sizeof(struct sockaddr_in); else if (family == AF_INET6) addrlen = sizeof(struct sockaddr_in6); else return NULL; buflen = (addrlen+16)*2; res = (struct accepting_socket *)mm_calloc(1,sizeof(struct accepting_socket)-1+buflen); if (!res) return NULL; event_overlapped_init_(&res->overlapped, accepted_socket_cb); res->s = INVALID_SOCKET; res->lev = lev; res->buflen = buflen; res->family = family; event_deferred_cb_init_(&res->deferred, event_base_get_npriorities(lev->event_base) / 2, accepted_socket_invoke_user_cb, res); InitializeCriticalSectionAndSpinCount(&res->lock, 1000); return res; }