1*d327dbeaSPatrick Mooney /*
2*d327dbeaSPatrick Mooney * This file and its contents are supplied under the terms of the
3*d327dbeaSPatrick Mooney * Common Development and Distribution License ("CDDL"), version 1.0.
4*d327dbeaSPatrick Mooney * You may only use this file in accordance with the terms of version
5*d327dbeaSPatrick Mooney * 1.0 of the CDDL.
6*d327dbeaSPatrick Mooney *
7*d327dbeaSPatrick Mooney * A full copy of the text of the CDDL should have accompanied this
8*d327dbeaSPatrick Mooney * source. A copy of the CDDL is also available via the Internet at
9*d327dbeaSPatrick Mooney * http://www.illumos.org/license/CDDL.
10*d327dbeaSPatrick Mooney */
11*d327dbeaSPatrick Mooney
12*d327dbeaSPatrick Mooney /*
13*d327dbeaSPatrick Mooney * Copyright 2018 Joyent, Inc.
14*d327dbeaSPatrick Mooney */
15*d327dbeaSPatrick Mooney
16*d327dbeaSPatrick Mooney /*
17*d327dbeaSPatrick Mooney * Test: read.requeue
18*d327dbeaSPatrick Mooney * Assertion: A sequence of writes turns into a sequence of events.
19*d327dbeaSPatrick Mooney *
20*d327dbeaSPatrick Mooney * Strategy: 1. Create a pipe
21*d327dbeaSPatrick Mooney * 2. Call mevent_add() to be notified of writes to the pipe. The
22*d327dbeaSPatrick Mooney * callback will signal a cv.
23*d327dbeaSPatrick Mooney * 3. In a loop, write to the pipe then wait on the cv.
24*d327dbeaSPatrick Mooney */
25*d327dbeaSPatrick Mooney
26*d327dbeaSPatrick Mooney #include <errno.h>
27*d327dbeaSPatrick Mooney #include <fcntl.h>
28*d327dbeaSPatrick Mooney #include <pthread.h>
29*d327dbeaSPatrick Mooney #include <signal.h>
30*d327dbeaSPatrick Mooney #include <stdio.h>
31*d327dbeaSPatrick Mooney #include <stdlib.h>
32*d327dbeaSPatrick Mooney #include <strings.h>
33*d327dbeaSPatrick Mooney #include <unistd.h>
34*d327dbeaSPatrick Mooney
35*d327dbeaSPatrick Mooney #include <sys/types.h>
36*d327dbeaSPatrick Mooney #include <sys/stat.h>
37*d327dbeaSPatrick Mooney
38*d327dbeaSPatrick Mooney #include "testlib.h"
39*d327dbeaSPatrick Mooney #include "mevent.h"
40*d327dbeaSPatrick Mooney
41*d327dbeaSPatrick Mooney static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
42*d327dbeaSPatrick Mooney static pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
43*d327dbeaSPatrick Mooney
44*d327dbeaSPatrick Mooney static char *cookie = "Chocolate chip with fudge stripes";
45*d327dbeaSPatrick Mooney
46*d327dbeaSPatrick Mooney static void
munch(int fd,enum ev_type ev,void * arg)47*d327dbeaSPatrick Mooney munch(int fd, enum ev_type ev, void *arg)
48*d327dbeaSPatrick Mooney {
49*d327dbeaSPatrick Mooney static int i = 0;
50*d327dbeaSPatrick Mooney char buf[8] = { 0 };
51*d327dbeaSPatrick Mooney ssize_t nbytes;
52*d327dbeaSPatrick Mooney
53*d327dbeaSPatrick Mooney ASSERT_INT_EQ(("bad event"), ev, EVF_READ);
54*d327dbeaSPatrick Mooney ASSERT_PTR_EQ(("bad cookie"), arg, cookie);
55*d327dbeaSPatrick Mooney
56*d327dbeaSPatrick Mooney if ((nbytes = read(fd, buf, sizeof (buf))) < 0) {
57*d327dbeaSPatrick Mooney ASSERT_INT64_EQ(("bad read: %s", strerror(errno)), nbytes, 1);
58*d327dbeaSPatrick Mooney }
59*d327dbeaSPatrick Mooney VERBOSE(("read %ld bytes '%s'", nbytes, buf));
60*d327dbeaSPatrick Mooney
61*d327dbeaSPatrick Mooney ASSERT_INT64_EQ(("wanted a byte of cookie"), nbytes, 1);
62*d327dbeaSPatrick Mooney
63*d327dbeaSPatrick Mooney ASSERT_CHAR_EQ(("bad byte %d of cookie", i), buf[0], cookie[i]);
64*d327dbeaSPatrick Mooney
65*d327dbeaSPatrick Mooney pthread_mutex_lock(&mtx);
66*d327dbeaSPatrick Mooney pthread_cond_signal(&cv);
67*d327dbeaSPatrick Mooney VERBOSE(("wakeup"));
68*d327dbeaSPatrick Mooney pthread_mutex_unlock(&mtx);
69*d327dbeaSPatrick Mooney
70*d327dbeaSPatrick Mooney i++;
71*d327dbeaSPatrick Mooney }
72*d327dbeaSPatrick Mooney
73*d327dbeaSPatrick Mooney int
main(int argc,const char * argv[])74*d327dbeaSPatrick Mooney main(int argc, const char *argv[])
75*d327dbeaSPatrick Mooney {
76*d327dbeaSPatrick Mooney int pipefds[2];
77*d327dbeaSPatrick Mooney struct mevent *evp;
78*d327dbeaSPatrick Mooney
79*d327dbeaSPatrick Mooney start_test(argv[0], 5);
80*d327dbeaSPatrick Mooney start_event_thread();
81*d327dbeaSPatrick Mooney
82*d327dbeaSPatrick Mooney if (pipe(pipefds) != 0) {
83*d327dbeaSPatrick Mooney FAIL_ERRNO("pipe");
84*d327dbeaSPatrick Mooney }
85*d327dbeaSPatrick Mooney if (fcntl(pipefds[0], F_SETFL, O_NONBLOCK) != 0) {
86*d327dbeaSPatrick Mooney FAIL_ERRNO("set pipe nonblocking");
87*d327dbeaSPatrick Mooney }
88*d327dbeaSPatrick Mooney
89*d327dbeaSPatrick Mooney evp = mevent_add(pipefds[0], EVF_READ, munch, cookie);
90*d327dbeaSPatrick Mooney ASSERT_PTR_NEQ(("mevent_add"), evp, NULL);
91*d327dbeaSPatrick Mooney
92*d327dbeaSPatrick Mooney for (int i = 0; cookie[i] != '\0'; i++) {
93*d327dbeaSPatrick Mooney ssize_t written;
94*d327dbeaSPatrick Mooney
95*d327dbeaSPatrick Mooney pthread_mutex_lock(&mtx);
96*d327dbeaSPatrick Mooney written = write(pipefds[1], cookie + i, 1);
97*d327dbeaSPatrick Mooney if (written < 0) {
98*d327dbeaSPatrick Mooney FAIL_ERRNO("bad write");
99*d327dbeaSPatrick Mooney }
100*d327dbeaSPatrick Mooney ASSERT_INT64_EQ(("write byte %d of cookie", i), written, 1);
101*d327dbeaSPatrick Mooney
102*d327dbeaSPatrick Mooney /* Wait for it to be read */
103*d327dbeaSPatrick Mooney pthread_cond_wait(&cv, &mtx);
104*d327dbeaSPatrick Mooney pthread_mutex_unlock(&mtx);
105*d327dbeaSPatrick Mooney }
106*d327dbeaSPatrick Mooney
107*d327dbeaSPatrick Mooney PASS();
108*d327dbeaSPatrick Mooney }
109