aboutsummaryrefslogtreecommitdiff
path: root/tests/sys/kern/unix_seqpacket_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/sys/kern/unix_seqpacket_test.c')
-rw-r--r--tests/sys/kern/unix_seqpacket_test.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/tests/sys/kern/unix_seqpacket_test.c b/tests/sys/kern/unix_seqpacket_test.c
index b9a6be015241..27bd430430b4 100644
--- a/tests/sys/kern/unix_seqpacket_test.c
+++ b/tests/sys/kern/unix_seqpacket_test.c
@@ -1314,6 +1314,67 @@ ATF_TC_BODY(random_eor_and_waitall, tc)
free(params.records);
}
+/* See bug 290658. */
+#define PEEK_RACE_SIZE 10
+#define PEEK_RACE_TRIES 10000
+static void *
+peek_race_writer(void *args)
+{
+ struct timespec ts = {};
+ u_short seed[3];
+ char buf[PEEK_RACE_SIZE];
+ int fd = *(int *)args;
+
+ arc4random_buf(seed, sizeof(seed));
+ for (u_int i = 0; i < PEEK_RACE_TRIES; i++) {
+ ATF_REQUIRE_EQ(PEEK_RACE_SIZE,
+ send(fd, buf, sizeof(buf), MSG_EOR));
+ ts.tv_nsec = nrand48(seed) % 20;
+ (void)clock_nanosleep(CLOCK_MONOTONIC_FAST, 0, &ts, NULL);
+ }
+
+ return (NULL);
+}
+
+static void *
+peek_race_peeker(void *args)
+{
+ char buf[PEEK_RACE_SIZE * 10];
+ int fd = *(int *)args;
+
+ for (u_int i = 0; i < PEEK_RACE_TRIES; i++) {
+ ssize_t rcvd;
+
+ while ((rcvd = recv(fd, buf, sizeof(buf),
+ MSG_PEEK | MSG_DONTWAIT)) == -1)
+ ATF_REQUIRE(errno == EAGAIN);
+ ATF_REQUIRE(rcvd == PEEK_RACE_SIZE);
+
+ ATF_REQUIRE_EQ(PEEK_RACE_SIZE,
+ recv(fd, buf, sizeof(buf), 0));
+ }
+
+ return (NULL);
+}
+
+ATF_TC_WITHOUT_HEAD(peek_race);
+ATF_TC_BODY(peek_race, tc)
+{
+ pthread_t peeker, writer;
+ int sv[2];
+
+ do_socketpair(sv);
+
+ ATF_REQUIRE_EQ(0, pthread_create(&writer, NULL, peek_race_writer,
+ &sv[0]));
+ ATF_REQUIRE_EQ(0, pthread_create(&peeker, NULL, peek_race_peeker,
+ &sv[1]));
+ ATF_REQUIRE_EQ(0, pthread_join(writer, NULL));
+ ATF_REQUIRE_EQ(0, pthread_join(peeker, NULL));
+ close(sv[0]);
+ close(sv[1]);
+}
+
/*
* Main.
*/
@@ -1370,6 +1431,7 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, pipe_128k_8k);
ATF_TP_ADD_TC(tp, pipe_128k_128k);
ATF_TP_ADD_TC(tp, random_eor_and_waitall);
+ ATF_TP_ADD_TC(tp, peek_race);
return atf_no_error();
}