Alien-uv
view release on metacpan or search on metacpan
libuv/src/unix/stream.c view on Meta::CPAN
s->fake_fd = fds[0];
s->int_fd = fds[1];
old_fd = *fd;
s->stream = stream;
stream->select = s;
*fd = s->fake_fd;
err = uv_thread_create(&s->thread, uv__stream_osx_select, stream);
if (err != 0)
goto failed_thread_create;
return 0;
failed_thread_create:
s->stream = NULL;
stream->select = NULL;
*fd = old_fd;
uv_sem_destroy(&s->async_sem);
failed_async_sem_init:
uv_sem_destroy(&s->close_sem);
failed_close_sem_init:
uv__close(fds[0]);
uv__close(fds[1]);
uv_close((uv_handle_t*) &s->async, uv__stream_osx_cb_close);
return err;
failed_async_init:
uv__free(s);
failed_malloc:
uv__close(fds[0]);
uv__close(fds[1]);
return err;
}
#endif /* defined(__APPLE__) */
int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
#if defined(__APPLE__)
int enable;
#endif
if (!(stream->io_watcher.fd == -1 || stream->io_watcher.fd == fd))
return UV_EBUSY;
assert(fd >= 0);
stream->flags |= flags;
if (stream->type == UV_TCP) {
if ((stream->flags & UV_HANDLE_TCP_NODELAY) && uv__tcp_nodelay(fd, 1))
return UV__ERR(errno);
/* TODO Use delay the user passed in. */
if ((stream->flags & UV_HANDLE_TCP_KEEPALIVE) &&
uv__tcp_keepalive(fd, 1, 60)) {
return UV__ERR(errno);
}
}
#if defined(__APPLE__)
enable = 1;
if (setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, &enable, sizeof(enable)) &&
errno != ENOTSOCK &&
errno != EINVAL) {
return UV__ERR(errno);
}
#endif
stream->io_watcher.fd = fd;
return 0;
}
void uv__stream_flush_write_queue(uv_stream_t* stream, int error) {
uv_write_t* req;
QUEUE* q;
while (!QUEUE_EMPTY(&stream->write_queue)) {
q = QUEUE_HEAD(&stream->write_queue);
QUEUE_REMOVE(q);
req = QUEUE_DATA(q, uv_write_t, queue);
req->error = error;
QUEUE_INSERT_TAIL(&stream->write_completed_queue, &req->queue);
}
}
void uv__stream_destroy(uv_stream_t* stream) {
assert(!uv__io_active(&stream->io_watcher, POLLIN | POLLOUT));
assert(stream->flags & UV_HANDLE_CLOSED);
if (stream->connect_req) {
uv__req_unregister(stream->loop, stream->connect_req);
stream->connect_req->cb(stream->connect_req, UV_ECANCELED);
stream->connect_req = NULL;
}
uv__stream_flush_write_queue(stream, UV_ECANCELED);
uv__write_callbacks(stream);
if (stream->shutdown_req) {
/* The ECANCELED error code is a lie, the shutdown(2) syscall is a
* fait accompli at this point. Maybe we should revisit this in v0.11.
* A possible reason for leaving it unchanged is that it informs the
* callee that the handle has been destroyed.
*/
uv__req_unregister(stream->loop, stream->shutdown_req);
stream->shutdown_req->cb(stream->shutdown_req, UV_ECANCELED);
stream->shutdown_req = NULL;
}
assert(stream->write_queue_size == 0);
}
( run in 0.796 second using v1.01-cache-2.11-cpan-df04353d9ac )