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