/* got new socket from accept() */ bool sbuf_accept(SBuf *sbuf, int sock, bool is_unix) { bool res; Assert(iobuf_empty(sbuf->io) && sbuf->sock == 0); AssertSanity(sbuf); sbuf->sock = sock; if (!tune_socket(sock, is_unix)) goto failed; if (!cf_reboot) { res = sbuf_wait_for_data(sbuf); if (!res) goto failed; /* socket should already have some data (linux only) */ if (cf_tcp_defer_accept && !is_unix) { sbuf_main_loop(sbuf, DO_RECV); if (!sbuf->sock) return false; } } return true; failed: sbuf_call_proto(sbuf, SBUF_EV_RECV_FAILED); return false; }
int term_writepoll() { char c; if( iobuf_empty( &oterm ) ) return 1; if( (*TERM_FLAG & (TXFF_MASK | TXBUSY_MASK)) ) return 2; if( iobuf_get( &oterm, &c ) ) return 3; *TERM_DATA = c; return 0; }
int train_writepoll() { char c; if( iobuf_empty( &otrain ) ) return 1; if( (*TRAIN_FLAG & (TXFF_MASK | TXBUSY_MASK)) || !(*TRAIN_FLAG & CTS_MASK) ) return 2; if( iobuf_get( &otrain, &c ) ) { return 3; } *TRAIN_DATA = c; return 0; }
/* need to connect() to get a socket */ bool sbuf_connect(SBuf *sbuf, const struct sockaddr *sa, int sa_len, int timeout_sec) { int res, sock; struct timeval timeout; bool is_unix = sa->sa_family == AF_UNIX; Assert(iobuf_empty(sbuf->io) && sbuf->sock == 0); AssertSanity(sbuf); /* * common stuff */ sock = socket(sa->sa_family, SOCK_STREAM, 0); if (sock < 0) { /* probably fd limit */ goto failed; } if (!tune_socket(sock, is_unix)) goto failed; sbuf->sock = sock; timeout.tv_sec = timeout_sec; timeout.tv_usec = 0; /* launch connection */ res = safe_connect(sock, sa, sa_len); if (res == 0) { /* unix socket gives connection immediately */ sbuf_connect_cb(sock, EV_WRITE, sbuf); return true; } else if (errno == EINPROGRESS) { /* tcp socket needs waiting */ event_set(&sbuf->ev, sock, EV_WRITE, sbuf_connect_cb, sbuf); res = event_add(&sbuf->ev, &timeout); if (res >= 0) { sbuf->wait_type = W_CONNECT; return true; } } failed: log_warning("sbuf_connect failed: %s", strerror(errno)); if (sock >= 0) safe_close(sock); sbuf->sock = 0; sbuf_call_proto(sbuf, SBUF_EV_CONNECT_FAILED); return false; }
/* reposition at buffer start again */ static void sbuf_try_resync(SBuf *sbuf, bool release) { IOBuf *io = sbuf->io; if (io) { log_noise("resync: done=%d, parse=%d, recv=%d", io->done_pos, io->parse_pos, io->recv_pos); } AssertActive(sbuf); if (!io) return; if (release && iobuf_empty(io)) { slab_free(iobuf_cache, io); sbuf->io = NULL; } else { iobuf_try_resync(io, SBUF_SMALL_PKT); } }