| 1 | /* Common definition for tst-cancel4_* tests. |
| 2 | |
| 3 | Copyright (C) 2016-2024 Free Software Foundation, Inc. |
| 4 | This file is part of the GNU C Library. |
| 5 | |
| 6 | The GNU C Library is free software; you can redistribute it and/or |
| 7 | modify it under the terms of the GNU Lesser General Public |
| 8 | License as published by the Free Software Foundation; either |
| 9 | version 2.1 of the License, or (at your option) any later version. |
| 10 | |
| 11 | The GNU C Library is distributed in the hope that it will be useful, |
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 14 | Lesser General Public License for more details. |
| 15 | |
| 16 | You should have received a copy of the GNU Lesser General Public |
| 17 | License along with the GNU C Library; if not, see |
| 18 | <https://www.gnu.org/licenses/>. */ |
| 19 | |
| 20 | #include <pthread.h> |
| 21 | |
| 22 | #include <support/check.h> |
| 23 | #include <support/xthread.h> |
| 24 | #include <support/xunistd.h> |
| 25 | |
| 26 | /* Pipe descriptors. */ |
| 27 | static int fds[2]; |
| 28 | |
| 29 | /* Temporary file descriptor, to be closed after each round. */ |
| 30 | static int tempfd = -1; |
| 31 | static int tempfd2 = -1; |
| 32 | /* Name of temporary file to be removed after each round. */ |
| 33 | static char *tempfname; |
| 34 | /* Temporary message queue. */ |
| 35 | static int tempmsg = -1; |
| 36 | |
| 37 | /* Often used barrier for two threads. */ |
| 38 | static pthread_barrier_t b2; |
| 39 | |
| 40 | /* The WRITE_BUFFER_SIZE value needs to be chosen such that if we set |
| 41 | the socket send buffer size to '1', a write of this size on that |
| 42 | socket will block. |
| 43 | |
| 44 | The Linux kernel imposes a minimum send socket buffer size which |
| 45 | has changed over the years. As of Linux 3.10 the value is: |
| 46 | |
| 47 | 2 * (2048 + SKB_DATA_ALIGN(sizeof(struct sk_buff))) |
| 48 | |
| 49 | which is attempting to make sure that with standard MTUs, |
| 50 | TCP can always queue up at least 2 full sized packets. |
| 51 | |
| 52 | Furthermore, there is logic in the socket send paths that |
| 53 | will allow one more packet (of any size) to be queued up as |
| 54 | long as some socket buffer space remains. Blocking only |
| 55 | occurs when we try to queue up a new packet and the send |
| 56 | buffer space has already been fully consumed. |
| 57 | |
| 58 | Therefore we must set this value to the largest possible value of |
| 59 | the formula above (and since it depends upon the size of "struct |
| 60 | sk_buff", it is dependent upon machine word size etc.) plus some |
| 61 | slack space. */ |
| 62 | |
| 63 | #define WRITE_BUFFER_SIZE 16384 |
| 64 | |
| 65 | /* Set the send buffer of socket S to 1 byte so any send operation |
| 66 | done with WRITE_BUFFER_SIZE bytes will force syscall blocking. */ |
| 67 | static void |
| 68 | set_socket_buffer (int s) |
| 69 | { |
| 70 | int val = 1; |
| 71 | socklen_t len = sizeof (val); |
| 72 | |
| 73 | TEST_VERIFY_EXIT (setsockopt (s, SOL_SOCKET, SO_SNDBUF, &val, |
| 74 | sizeof (val)) == 0); |
| 75 | TEST_VERIFY_EXIT (getsockopt (s, SOL_SOCKET, SO_SNDBUF, &val, &len) == 0); |
| 76 | TEST_VERIFY_EXIT (val < WRITE_BUFFER_SIZE); |
| 77 | printf(format: "got size %d\n" , val); |
| 78 | } |
| 79 | |
| 80 | /* Cleanup handling test. */ |
| 81 | static int cl_called; |
| 82 | |
| 83 | static void |
| 84 | cl (void *arg) |
| 85 | { |
| 86 | ++cl_called; |
| 87 | } |
| 88 | |
| 89 | /* Named pipe used to check for blocking open. It should be closed |
| 90 | after the cancellation handling. */ |
| 91 | static char fifoname[] = "/tmp/tst-cancel4-fifo-XXXXXX" ; |
| 92 | static int fifofd; |
| 93 | |
| 94 | static void |
| 95 | __attribute__ ((used)) |
| 96 | cl_fifo (void *arg) |
| 97 | { |
| 98 | ++cl_called; |
| 99 | |
| 100 | unlink (name: fifoname); |
| 101 | close (fd: fifofd); |
| 102 | fifofd = -1; |
| 103 | } |
| 104 | |
| 105 | struct cancel_tests |
| 106 | { |
| 107 | const char *name; |
| 108 | void *(*tf) (void *); |
| 109 | int nb; |
| 110 | int only_early; |
| 111 | }; |
| 112 | #define ADD_TEST(name, nbar, early) { #name, tf_##name, nbar, early } |
| 113 | |