示例#1
0
int async_sleep(uint64_t const milliseconds) {
	uv_timer_t timer[1];
	timer->data = async_active();
	int rc = uv_timer_init(async_loop, timer);
	if(rc < 0) return rc;
	if(milliseconds > 0) {
		rc = uv_timer_start(timer, timer_cb, milliseconds, 0);
		if(rc < 0) return rc;
		async_yield();
	}
	// Not worth calling async_close.
	uv_close((uv_handle_t *)timer, close_cb);
	async_yield();
	return 0;
}
示例#2
0
void async_close(uv_handle_t *const handle) {
	if(UV_UNKNOWN_HANDLE == handle->type) return;
	handle->data = async_active();
	uv_close(handle, close_cb);
	async_yield();
	memset(handle, 0, uv_handle_size(handle->type));
	// Luckily UV_UNKNOWN_HANDLE is 0.
}
示例#3
0
int async_tcp_connect(uv_tcp_t *const stream, struct sockaddr const *const addr) {
	async_state state[1];
	state->thread = async_active();
	uv_connect_t req[1];
	req->data = state;
	int rc = uv_tcp_connect(req, stream, addr, connect_cb);
	if(rc < 0) return rc;
	async_yield();
	return state->status;
}
示例#4
0
int async_write(uv_stream_t *const stream, uv_buf_t const bufs[], unsigned const nbufs) {
	async_state state[1];
	state->thread = async_active();
	uv_write_t req[1];
	req->data = &state;
	int rc = uv_write(req, stream, bufs, nbufs, write_cb);
	if(rc < 0) return rc;
	async_yield();
	return state->status;
}
示例#5
0
int async_getnameinfo(uv_getnameinfo_t *const req, struct sockaddr const *const addr, int const flags) {
	uv_getnameinfo_cb cb = NULL;
	if(async_main) {
		req->data = async_active();
		cb = getnameinfo_cb;
	}
	int rc = uv_getnameinfo(async_loop, req, cb, addr, flags);
	if(rc < 0) return rc;
	if(cb) async_yield();
	return req->retcode;
}
示例#6
0
void async_rwlock_wrlock(async_rwlock_t *const lock) {
	assert(lock);
	assert(async_main);
	assert(async_active() != async_main);
	if(async_rwlock_trywrlock(lock) >= 0) return;
	async_thread_list us = {
		.thread = async_active(),
		.next = NULL,
	};
	if(!lock->wrhead) lock->wrhead = &us;
	if(lock->wrtail) lock->wrtail->next = &us;
	lock->wrtail = &us;
	async_yield();
	assert(s_write == lock->state);
	assert(!lock->upgrade);
}
示例#7
0
int async_rwlock_upgrade(async_rwlock_t *const lock) {
	assert(lock);
	assert(lock->state > 0);
	assert(lock->state <= READERS_MAX);
	if(lock->upgrade) return -1;
	--lock->state;
	if(lock->state > 0) {
		lock->upgrade = async_active();
		async_yield();
		assert(!lock->upgrade && "Upgrade not cleared");
		assert(s_write == lock->state && "Wrong upgrade woken");
	} else {
		lock->state = s_write;
	}
	return 0;
}
示例#8
0
int async_yield_cancelable(void) {
	async_t *const thread = async_active();
	if(ASYNC_CANCELED & thread->flags) {
		thread->flags &= ~ASYNC_CANCELED;
		return UV_ECANCELED;
	}
	assert(!(ASYNC_CANCELABLE & thread->flags));
	thread->flags |= ASYNC_CANCELABLE;
	async_yield();
	thread->flags &= ~ASYNC_CANCELABLE;
	if(ASYNC_CANCELED & thread->flags) {
		thread->flags &= ~ASYNC_CANCELED;
		return UV_ECANCELED;
	}
	return 0;
}
示例#9
0
int async_poll_socket(uv_os_sock_t const socket, int *const events) {
	assert(events);
	struct poll_state state[1];
	state->thread = async_active();
	state->status = 0;
	state->events = 0;
	uv_poll_t poll[1];
	poll->data = state;
	int rc = uv_poll_init_socket(async_loop, poll, socket);
	if(rc < 0) return rc;
	rc = uv_poll_start(poll, *events, poll_cb);
	if(rc < 0) return rc;
	async_yield();
	async_close((uv_handle_t *)poll);
	*events = state->events;
	return state->status;
}
示例#10
0
void async_rwlock_rdlock(async_rwlock_t *const lock) {
	assert(lock);
	assert(async_main);
	assert(async_active() != async_main);
	if(async_rwlock_tryrdlock(lock) >= 0) return;
	async_thread_list us = {
		.thread = async_active(),
		.next = NULL,
	};
	if(!lock->rdhead) lock->rdhead = &us;
	if(lock->rdtail) lock->rdtail->next = &us;
	lock->rdtail = &us;
	async_yield();
	assert(lock->state > 0);
	assert(lock->state <= READERS_MAX);
	assert(!lock->wrhead);
	assert(!lock->upgrade);
}
示例#11
0
int async_getaddrinfo(char const *const node, char const *const service, struct addrinfo const *const hints, struct addrinfo **const res) {
// uv_getaddrinfo kind of sucks so we try to avoid it.
// TODO: We don't ever define __POSIX__ currently.
#if defined(__POSIX__) || defined(CORO_USE_VALGRIND)
	async_pool_enter(NULL);
	int rc = getaddrinfo(node, service, hints, res);
	async_pool_leave(NULL);
	return rc;
#else
	getaddrinfo_state state[1];
	uv_getaddrinfo_t req[1];
	req->data = state;
	uv_getaddrinfo_cb cb = NULL;
	if(async_main) {
		state->thread = async_active();
		cb = getaddrinfo_cb;
	}
	int rc = uv_getaddrinfo(async_loop, req, cb, node, service, hints);
	if(rc < 0) return rc;
	if(cb) async_yield();
	if(res) *res = state->res;
	return state->status;
#endif
}
示例#12
0
int async_yield_flags(unsigned const flags) {
	if(ASYNC_CANCELABLE & flags) return async_yield_cancelable();
	async_yield();
	return 0;
}