示例#1
0
static void
accepted_socket_cb(struct event_overlapped *o, ev_uintptr_t key, ev_ssize_t n, int ok)
{
	struct accepting_socket *as =
	    EVUTIL_UPCAST(o, struct accepting_socket, overlapped);

	LOCK(&as->lev->base);
	EnterCriticalSection(&as->lock);
	if (ok) {
		/* XXXX Don't do this if some EV_MT flag is set. */
		event_deferred_cb_schedule_(
			as->lev->event_base,
			&as->deferred);
		LeaveCriticalSection(&as->lock);
	} else if (as->free_on_cb) {
		struct evconnlistener *lev = &as->lev->base;
		free_and_unlock_accepting_socket(as);
		listener_decref_and_unlock(lev);
		return;
	} else if (as->s == INVALID_SOCKET) {
		/* This is okay; we were disabled by iocp_listener_disable. */
		LeaveCriticalSection(&as->lock);
	} else {
		/* Some error on accept that we couldn't actually handle. */
		BOOL ok;
		DWORD transfer = 0, flags=0;
		event_sock_warn(as->s, "Unexpected error on AcceptEx");
		ok = WSAGetOverlappedResult(as->s, &o->overlapped,
		    &transfer, FALSE, &flags);
		if (ok) {
			/* well, that was confusing! */
			as->error = 1;
		} else {
			as->error = WSAGetLastError();
		}
		event_deferred_cb_schedule_(
			as->lev->event_base,
			&as->deferred);
		LeaveCriticalSection(&as->lock);
	}
	UNLOCK(&as->lev->base);
}
示例#2
0
static int
start_accepting(struct accepting_socket *as)
{
	/* requires lock */
	const struct win32_extension_fns *ext = event_get_win32_extension_fns_();
	DWORD pending = 0;
	SOCKET s = socket(as->family, SOCK_STREAM, 0);
	int error = 0;

	if (!as->lev->base.enabled)
		return 0;

	if (s == INVALID_SOCKET) {
		error = WSAGetLastError();
		goto report_err;
	}

	/* XXXX It turns out we need to do this again later.  Does this call
	 * have any effect? */
	setsockopt(s, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
	    (char *)&as->lev->fd, sizeof(&as->lev->fd));

	if (!(as->lev->base.flags & LEV_OPT_LEAVE_SOCKETS_BLOCKING))
		evutil_make_socket_nonblocking(s);

	if (event_iocp_port_associate_(as->lev->port, s, 1) < 0) {
		closesocket(s);
		return -1;
	}

	as->s = s;

	if (ext->AcceptEx(as->lev->fd, s, as->addrbuf, 0,
		as->buflen/2, as->buflen/2, &pending, &as->overlapped.overlapped))
	{
		/* Immediate success! */
		accepted_socket_cb(&as->overlapped, 1, 0, 1);
	} else {
		error = WSAGetLastError();
		if (error != ERROR_IO_PENDING) {
			goto report_err;
		}
	}

	return 0;

report_err:
	as->error = error;
	event_deferred_cb_schedule_(
		as->lev->event_base,
		&as->deferred);
	return 0;
}
示例#3
0
static THREAD_FN
load_deferred_queue(void *arg)
{
	struct deferred_test_data *data = arg;
	size_t i;

	for (i = 0; i < CB_COUNT; ++i) {
		event_deferred_cb_init_(&data->cbs[i], 0, deferred_callback,
		    NULL);
		event_deferred_cb_schedule_(data->queue, &data->cbs[i]);
		SLEEP_MS(1);
	}

	THREAD_RETURN();
}