int connector::do_connect() { int n; _conntime = time_prec_msec::now(); again: n = ::connect(_fd, _addr, _addr.length()); if (ll_sys_failed(n)) { switch (errno) { case EINTR: goto again; case ECONNREFUSED: ll_failed_return(do_emit(_fd, reactor::poll_err)); if (_interval) { _reactor->close(_fd); _timer = _timermgr->schedule(_conntime + _interval, &connector::timer_handler, this); return ok; } return fail; case EINPROGRESS: if (_timeout) { _timer = _timermgr->schedule(_conntime + _timeout, &connector::timer_handler, this); } return ok; default: return fail; } } return ok; }
int connector::connect_handler(file_io&, int type) { int n; socklen_t len; if (type & reactor::poll_close) { _fd.close(); return fail; } if (type & (reactor::poll_out | reactor::poll_err)) { close_timer(); len = sizeof(int); ll_sys_failed_return(getsockopt(_fd, SOL_SOCKET, SO_ERROR, &n, &len)); if (n || (type & reactor::poll_err)) { if (ll_ok(do_emit(_fd, reactor::poll_err))) { if (_interval) { _timer = _timermgr->schedule(_conntime + _interval, &connector::timer_handler, this); return fail; } } return fail; } else { _timer = _timermgr->idle(&connector::connect_ready, this); return ok; } } return ok; }
void connector::connect_ready() { _timer = nullptr; int fd = _fd.deattch(); _reactor->close(fd); do_emit(fd, reactor::poll_out); }
void *_tnl_emit_vertices_to_buffer( GLcontext *ctx, GLuint start, GLuint end, void *dest ) { struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); do_emit( ctx, start, end, dest ); return (void *)((GLubyte *)dest + vtx->vertex_size * (end - start)); }
timeval connector::timer_handler(timer &, timeval) { _timer = nullptr; if (_fd.opened()) { if (ll_failed(do_emit(_fd, reactor::poll_err))) { close(); return 0; } _reactor->close(_fd); } connect(); return 0; }
int listener::accept_handler(file_io&, int type) { if (type & reactor::poll_close) { do_emit(_fd, reactor::poll_close, _addr); close(); return -1; } if (type & reactor::poll_err) { do_emit(_fd, reactor::poll_err, _addr); return -1; } if (type & reactor::poll_in) { address addr; while (1) { socklen_t len = address::length(); int fd = ::accept(_fd, addr, &len); if (fd < 0) { switch (errno) { case EAGAIN: return ok; case EINTR: continue; default: do_emit(_fd, reactor::poll_err, _addr); return -1; } } ll_failed_return(do_emit(fd, reactor::poll_in, addr)); } } return ok; }
void _tnl_build_vertices( GLcontext *ctx, GLuint start, GLuint end, GLuint newinputs ) { struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); const GLuint stride = vtx->vertex_size; GLubyte *vDest = ((GLubyte *)vtx->vertex_buf + (start*stride)); newinputs |= vtx->new_inputs; vtx->new_inputs = 0; if (newinputs) do_emit( ctx, start, end, vDest ); }
int listener::listen() { if (listening()) { return e_busy; } ll_sys_failed_return(_fd = ::socket(AF_INET, SOCK_STREAM, 0)); auto guard = make_guard([this](){ _fd.close(); }); int n = 1; ll_sys_failed_return(::setsockopt(_fd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(int))); ll_sys_failed_return(::bind(_fd, _addr, _addr.length())); ll_sys_failed_return(::listen(_fd, _backlog)); ll_failed_return(_reactor->open(_fd, reactor::poll_in | reactor::poll_err, &listener::accept_handler, this)); guard.dismiss(); if (ll_failed(do_emit(_fd, reactor::poll_open, _addr))) { close(); return fail; } return ok; }