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 long bio_bufq_ctrl(BIO *h, int cmd, long arg1, void *arg2) { ph_unused_parameter(h); ph_unused_parameter(cmd); ph_unused_parameter(arg1); ph_unused_parameter(arg2); return 1; }
static int bio_bufq_read(BIO *h, char *buf, int size) { ph_unused_parameter(h); ph_unused_parameter(buf); ph_unused_parameter(size); errno = ENOSYS; return -1; }
int main(int argc, char **argv) { ph_stream_t *stm; char namebuf[128]; int fd; char buf[BUFSIZ]; uint64_t amount; int len; ph_unused_parameter(argc); ph_unused_parameter(argv); ph_library_init(); plan_tests(18); strcpy(namebuf, "/tmp/phenomXXXXXX"); fd = ph_mkostemp(namebuf, 0); diag("opened %s -> %d", namebuf, fd); unlink(namebuf); stm = ph_stm_fd_open(fd, 0, PH_STM_BUFSIZE); ph_stm_write(stm, "lemon\n", 6, &amount); is(amount, 6); // Shouldn't see it yet is(0, pread(fd, buf, sizeof(buf), 0)); // Should see it now ph_stm_flush(stm); is(6, pread(fd, buf, sizeof(buf), 0)); ok(!memcmp("lemon\n", buf, 6), "right content"); ok(ph_stm_seek(stm, 0, SEEK_SET, NULL), "seeked"); memset(buf, 0, sizeof(buf)); ok(ph_stm_read(stm, buf, 3, &amount), "read ok"); ok(amount == 3, "amount is %" PRIu64, amount); ok(!memcmp("lem", buf, 3), "got prefix"); ok(ph_stm_read(stm, buf, 3, &amount), "read ok"); ok(amount == 3, "amount is %" PRIu64, amount); ok(!memcmp("on\n", buf, 3), "got remainder"); ok(ph_stm_seek(stm, 0, SEEK_SET, NULL), "seeked"); len = ph_stm_printf(stm, "testing %d %s!", 1, "two"); ok(14 == len, "printed len %d", len); ok(ph_stm_seek(stm, 0, SEEK_SET, NULL), "seeked"); memset(buf, 0, sizeof(buf)); ok(ph_stm_read(stm, buf, 14, &amount), "read ok"); ok(amount == 14, "len was %" PRIu64, amount); ok(!memcmp("testing 1 two!", buf, 14), "got formatted"); ok(ph_stm_close(stm), "closed"); return exit_status(); }
int main(int argc, char** argv) { ph_unused_parameter(argc); ph_unused_parameter(argv); ph_library_init(); plan_tests(39); basicCounterFunctionality(); concurrentCounters(); return exit_status(); }
int main(int argc, char **argv) { ph_unused_parameter(argc); ph_unused_parameter(argv); ph_library_init(); plan_tests(25); test_straddle_edges(); return exit_status(); }
static long bio_stm_ctrl(BIO *h, int cmd, long arg1, void *arg2) { ph_stream_t *stm = h->ptr; switch (cmd) { case BIO_CTRL_FLUSH: ph_stm_flush(stm); return 1; default: ph_unused_parameter(arg1); ph_unused_parameter(arg2); return 1; } }
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 acceptor(ph_listener_t *lstn, ph_sock_t *sock) { ph_unused_parameter(lstn); sock->callback = debug_con_processor; ph_sock_enable(sock, true); }
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 bool apply_affinity(ph_cpu_set_t *set, ph_thread_t *me) { # ifdef HAVE_CPUSET_SETAFFINITY ph_unused_parameter(me); return cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(*set), set) == 0; # else return pthread_setaffinity_np(me->thr, sizeof(*set), set) == 0; #endif }
static void tick_epoll(ph_job_t *job, ph_iomask_t why, void *data) { uint64_t expirations = 0; struct ph_nbio_emitter *emitter = data; ph_unused_parameter(job); ph_unused_parameter(why); ph_unused_parameter(data); /* consume the number of ticks; ideally this is 1; anything bigger * means that we've fallen behind */ if (read(emitter->timer_fd, &expirations, sizeof(expirations)) > 0) { if (expirations) { ph_nbio_emitter_timer_tick(emitter); } } ph_job_set_nbio(job, PH_IOMASK_READ, 0); }
int main(int argc, char **argv) { ph_job_t timer; ph_unused_parameter(argc); ph_unused_parameter(argv); ph_library_init(); plan_tests(8); is(PH_OK, ph_nbio_init(0)); is(PH_OK, ph_job_init(&timer)); timer.callback = record_tick; last_tick = ph_time_now(); is(PH_OK, ph_job_set_timer_at(&timer, last_tick)); is(PH_OK, ph_sched_run()); return exit_status(); }
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(); } }
// Called each time the listener has accepted a client connection static void acceptor(ph_listener_t *lstn, ph_sock_t *sock) { ph_unused_parameter(lstn); // Allocate an echo_state instance and stash it. // This is set to be zero'd on creation and will show up as the // `arg` parameter in `echo_processor` sock->job.data = ph_mem_alloc(mt_state); // Tell it how to dispatch sock->callback = echo_processor; ph_log(PH_LOG_ERR, "accepted `P{sockaddr:%p}", (void*)&sock->peername); ph_sock_enable(sock, true); }
/* called when ares creates a new socket */ static int sock_create_cb(ares_socket_t socket_fd, int type, void *data) { ph_dns_channel_t *chan = data; ph_job_t *job = ph_mem_alloc(mt.job); ph_unused_parameter(type); if (!job) { return -1; } ph_job_init(job); job->callback = process_ares; job->data = chan; job->fd = socket_fd; if (ph_ht_set(&chan->sock_map, &socket_fd, &job) != PH_OK) { ph_mem_free(mt.job, job); return -1; } return 0; }
static void done_handshake(ph_sock_t *sock, int res) { ph_unused_parameter(sock); ph_log(PH_LOG_ERR, "handshake completed with res=%d", res); }
int main(int argc, char **argv) { ph_string_t *str, *str2; ph_unused_parameter(argc); ph_unused_parameter(argv); ph_library_init(); plan_tests(102); mt_misc = ph_memtype_register(&mt_def); stack_tests(); // Tests reallocation str = ph_string_make_empty(mt_misc, 16); is(ph_string_append_cstr(str, "1234567890"), PH_OK); is(10, ph_string_len(str)); is(ph_string_append_cstr(str, "1234567890"), PH_OK); is(20, ph_string_len(str)); is(memcmp(str->buf, "12345678901234567890", 20), 0); ph_string_delref(str); // Tests reallocation and string formatting str = ph_string_make_empty(mt_misc, 4); is(ph_string_printf(str, "Hello %s", "world"), 11); is(ph_string_len(str), 11); str2 = ph_string_make_empty(mt_misc, 10); is(ph_string_printf(str2, "copy `Ps%p", (void*)str), 16); diag(":%.*s:", str2->len, str2->buf); is(ph_string_len(str2), 16); is(memcmp(str2->buf, "copy Hello world", 16), 0); ph_string_delref(str2); str2 = ph_string_make_empty(mt_misc, 10); is(ph_string_printf(str2, "copy `Ps%d%p", 5, (void*)str), 10); is(memcmp(str2->buf, "copy Hello", 10), 0); ok(!ph_string_equal(str, str2), "not same"); ph_string_delref(str2); str2 = ph_string_make_empty(mt_misc, 10); ph_string_append_buf(str2, str->buf, str->len); ok(ph_string_equal(str, str2), "same"); is(ph_string_compare(str, str2), 0); ph_string_delref(str); ph_string_delref(str2); str = ph_string_make_cstr(mt_misc, "abc"); str2 = ph_string_make_cstr(mt_misc, "bbc"); ok(ph_string_compare(str, str2) < 0, "abc < bbc"); ok(ph_string_compare(str2, str) > 0, "abc < bbc"); ph_string_delref(str2); str2 = ph_string_make_cstr(mt_misc, "abca"); ok(ph_string_compare(str, str2) < 0, "abc < abca"); ok(ph_string_compare(str2, str) > 0, "abc < abca"); ph_string_delref(str2); str2 = ph_string_make_cstr(mt_misc, "ab"); ok(ph_string_compare(str, str2) > 0, "abc > ab"); ok(ph_string_compare(str2, str) < 0, "abc > ab"); ph_string_delref(str2); ph_string_delref(str); str = ph_string_make_printf(mt_misc, 16, "Hello %d", 42); ok(ph_string_equal_cstr(str, "Hello 42"), "same"); ph_string_delref(str); utf16_tests(); string_stream_tests(); return exit_status(); }
static bool str_flush(void *arg) { ph_unused_parameter(arg); return true; }