static void read_stdin(ph_job_t *job, ph_iomask_t why, void *data) { char buf[128]; int x, i; ph_unused_parameter(why); ph_unused_parameter(data); x = read(job->fd, buf, sizeof(buf)); if (x <= 0) { if (x == -1) { ph_log(PH_LOG_ERR, "read(stdin): `Pe%d", errno); } ph_sched_stop(); return; } // Writing to the other job is safe here because we have the // same affinity: we know that it is not executing and mutating // its state for (i = 0; i < x; i++) { if (buf[i] == '\n') { ph_stm_write(remote_sock->stream, "\r\n", 2, NULL); } else { ph_stm_write(remote_sock->stream, buf + i, 1, NULL); } } // Force the sock to wakeup and send the buffer. // FIXME: Need something nicer than this hack ph_sock_enable(remote_sock, false); ph_sock_enable(remote_sock, true); ph_job_set_nbio_timeout_in(job, PH_IOMASK_READ, timeout); }
static void read_remote(ph_sock_t *sock, ph_iomask_t why, void *data) { ph_buf_t *buf; ph_unused_parameter(data); if (why & (PH_IOMASK_TIME|PH_IOMASK_ERR)) { ph_log(PH_LOG_ERR, "disconnecting `P{sockaddr:%p}", (void*)&sock->peername); ph_sock_shutdown(sock, PH_SOCK_SHUT_RDWR); ph_sock_free(sock); remote_sock = NULL; ph_sched_stop(); return; } while (1) { buf = ph_sock_read_line(sock); if (!buf) { // Not available yet, we'll try again later return; } ph_ignore_result(write(STDOUT_FILENO, ph_buf_mem(buf), ph_buf_len(buf))); ph_buf_delref(buf); } }
static void connected(ph_sock_t *sock, int overall_status, int errcode, const ph_sockaddr_t *addr, struct timeval *elapsed, void *arg) { SSL_CTX *ctx; SSL *ssl; ph_unused_parameter(arg); ph_unused_parameter(elapsed); switch (overall_status) { case PH_SOCK_CONNECT_GAI_ERR: ph_log(PH_LOG_ERR, "resolve %s:%d failed %s", addrstring, portno, gai_strerror(errcode)); ph_sched_stop(); return; case PH_SOCK_CONNECT_ERRNO: ph_log(PH_LOG_ERR, "connect %s:%d (`P{sockaddr:%p}) failed: `Pe%d", addrstring, portno, (void*)addr, errcode); ph_sched_stop(); return; } sock->callback = read_remote; remote_sock = sock; // Now set up stdin to feed into this new sock ph_job_init(&stdin_job); stdin_job.fd = STDIN_FILENO; stdin_job.callback = read_stdin; // Ensure that we have the same affinity as the other job stdin_job.emitter_affinity = sock->job.emitter_affinity; ph_socket_set_nonblock(STDIN_FILENO, true); ph_job_set_nbio_timeout_in(&stdin_job, PH_IOMASK_READ, timeout); ctx = SSL_CTX_new(SSLv23_client_method()); SSL_CTX_set_cipher_list(ctx, "ALL"); SSL_CTX_set_options(ctx, SSL_OP_ALL); SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); ssl = SSL_new(ctx); ph_sock_openssl_enable(sock, ssl, true, done_handshake); ph_sock_enable(sock, true); }
static void record_tick(ph_job_t *job, ph_iomask_t why, void *data) { struct timeval now, diff; int64_t diffn; ph_unused_parameter(why); ph_unused_parameter(data); now = ph_time_now(); // ~100ms resolution timersub(&now, &last_tick, &diff); diffn = (diff.tv_sec * 1000) + (diff.tv_usec / 1000); ok(diffn >= 80 && diffn <= 120, "100ms resolution: diff=%d", (int)diffn); last_tick = now; if (ticks++ < 3) { ph_job_set_timer_in_ms(job, 100); } else { // Stop the scheduler now ph_sched_stop(); } }