From patchwork Sun Jul 5 18:11:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Samuel Thibault X-Patchwork-Id: 39915 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 787A83857000; Sun, 5 Jul 2020 18:12:01 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from hera.aquilenet.fr (hera.aquilenet.fr [185.233.100.1]) by sourceware.org (Postfix) with ESMTPS id 052C73858D38 for ; Sun, 5 Jul 2020 18:11:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 052C73858D38 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=ens-lyon.org Authentication-Results: sourceware.org; spf=fail smtp.mailfrom=samuel.thibault@ens-lyon.org Received: from localhost (localhost [127.0.0.1]) by hera.aquilenet.fr (Postfix) with ESMTP id 85E6715B1; Sun, 5 Jul 2020 20:11:57 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at aquilenet.fr Received: from hera.aquilenet.fr ([127.0.0.1]) by localhost (hera.aquilenet.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id B3Bsft70zHpb; Sun, 5 Jul 2020 20:11:56 +0200 (CEST) Received: from function (lfbn-bor-1-797-11.w86-234.abo.wanadoo.fr [86.234.239.11]) by hera.aquilenet.fr (Postfix) with ESMTPSA id A3E4011FE; Sun, 5 Jul 2020 20:11:56 +0200 (CEST) Received: from samy by function with local (Exim 4.94) (envelope-from ) id 1js97L-005qTp-0x; Sun, 05 Jul 2020 20:11:55 +0200 From: Samuel Thibault To: libc-alpha@sourceware.org Subject: [PATCH] tst-cancel4: Make blocking on write more portable Date: Sun, 5 Jul 2020 20:11:54 +0200 Message-Id: <20200705181154.1393332-1-samuel.thibault@ens-lyon.org> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 X-Spam-Status: No, score=-10.8 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, SPF_HELO_PASS, SPF_NEUTRAL, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: commit-hurd@gnu.org Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" We should not be assuming how PF_UNIX buffering works and just choose a "proper" write size. The additional pthread_testcancel() call after write() shows it: we don't really control how buffering works. We can however easily use select to fill the buffer byte by byte until select() says that write() will block, in which case write() will not even be able to perform a partial write. We should however do this on the same side of the socketpair as the read() tests, otherwise read() would get data from this. This is actually fine: we can just read() and write() on the same side, with nobody consuming or producing data on the other side. * nptl/tst-cancel4-common.h (set_socket_buffer): Write data on the socket until select informs us that it would block. * nptl/tst-cancel4-common.c (do_test): Set send buffer size on fds[0] instead of fds[1]. * nptl/tst-cancel4.c (tf_write, tf_writev): Use fds[0] instead of fds[1]. (tf_write): Do not call pthread_testcancel() after write(), we are now not even supposed to get partial writes. (tf_send, tf_sendto): Fill socket buffer after connecting. --- nptl/tst-cancel4-common.c | 2 +- nptl/tst-cancel4-common.h | 19 ++++++++++++++++++- nptl/tst-cancel4.c | 16 ++++++---------- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/nptl/tst-cancel4-common.c b/nptl/tst-cancel4-common.c index 9a6924c1c6..3d4b567d38 100644 --- a/nptl/tst-cancel4-common.c +++ b/nptl/tst-cancel4-common.c @@ -26,7 +26,7 @@ do_test (void) exit (1); } - set_socket_buffer (fds[1]); + set_socket_buffer (fds[0]); if (mktemp (fifoname) == NULL) { diff --git a/nptl/tst-cancel4-common.h b/nptl/tst-cancel4-common.h index c8763cacba..f99785c4f2 100644 --- a/nptl/tst-cancel4-common.h +++ b/nptl/tst-cancel4-common.h @@ -62,7 +62,7 @@ static pthread_barrier_t b2; #define WRITE_BUFFER_SIZE 16384 -/* Set the send buffer of socket S to 1 byte so any send operation +/* Set the send buffer of socket S to 1 byte and fill it so any send operation done with WRITE_BUFFER_SIZE bytes will force syscall blocking. */ static void set_socket_buffer (int s) @@ -74,6 +74,23 @@ set_socket_buffer (int s) sizeof (val)) == 0); TEST_VERIFY_EXIT (getsockopt (s, SOL_SOCKET, SO_SNDBUF, &val, &len) == 0); TEST_VERIFY_EXIT (val < WRITE_BUFFER_SIZE); + + char buf = '\0'; + struct timeval timeout = { .tv_sec = 0, .tv_usec = 0 }; + + while (1) + { + fd_set set; + int ret; + + FD_ZERO (&set); + FD_SET (s, &set); + ret = select (s + 1, NULL, &set, NULL, &timeout); + if (!ret) + break; + + write (s, &buf, 1); + } } /* Cleanup handling test. */ diff --git a/nptl/tst-cancel4.c b/nptl/tst-cancel4.c index 5250a30b2e..7c72d16d4c 100644 --- a/nptl/tst-cancel4.c +++ b/nptl/tst-cancel4.c @@ -147,7 +147,7 @@ tf_write (void *arg) int fd; if (arg == NULL) - fd = fds[1]; + fd = fds[0]; else { char fname[] = "/tmp/tst-cancel4-fd-XXXXXX"; @@ -167,10 +167,6 @@ tf_write (void *arg) char buf[WRITE_BUFFER_SIZE]; memset (buf, '\0', sizeof (buf)); s = write (fd, buf, sizeof (buf)); - /* The write can return a value higher than 0 (meaning partial write) - due to the SIGCANCEL, but the thread may still be pending - cancellation. */ - pthread_testcancel (); pthread_cleanup_pop (0); @@ -184,7 +180,7 @@ tf_writev (void *arg) int fd; if (arg == NULL) - fd = fds[1]; + fd = fds[0]; else { char fname[] = "/tmp/tst-cancel4-fd-XXXXXX"; @@ -753,13 +749,13 @@ tf_send (void *arg) if (tempfd2 == -1) FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m"); - set_socket_buffer (tempfd2); - if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0) FAIL_EXIT1 ("connect: %m"); unlink (sun.sun_path); + set_socket_buffer (tempfd2); + xpthread_barrier_wait (&b2); if (arg != NULL) @@ -1288,13 +1284,13 @@ tf_sendto (void *arg) if (tempfd2 == -1) FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m"); - set_socket_buffer (tempfd2); - if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0) FAIL_EXIT1 ("connect: %m"); unlink (sun.sun_path); + set_socket_buffer (tempfd2); + xpthread_barrier_wait (&b2); if (arg != NULL)