pipetest.c revision 07e2e433c27fb8c0bebe2b6b2f0865f3314aaeca
1/* 2 * Copyright 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17/* Helper to test linux pipe's */ 18 19#include <pthread.h> 20#include <stdlib.h> 21#include <stdio.h> 22#include <errno.h> 23#include <unistd.h> 24#include <sys/poll.h> 25#include <sys/socket.h> 26 27static void print_events(int events) { 28 if (events & POLLIN) printf("POLLIN "); 29 if (events & POLLPRI) printf("POLLPRI "); 30 if (events & POLLOUT) printf("POLLOUT "); 31 if (events & POLLERR) printf("POLLERR "); 32 if (events & POLLHUP) printf("POLLHUP "); 33 if (events & POLLNVAL) printf("POLLNVAL "); 34 printf("\n"); 35} 36 37static int _close(int fd) { 38 int ret; 39 printf("%d: close(%d)\n", gettid(), fd); 40 ret = close(fd); 41 printf("%d: close(%d) = %d\n", gettid(), fd, ret); 42 if (ret) printf("\terr %d (%s)\n", errno, strerror(errno)); 43 return ret; 44} 45 46static int _poll(struct pollfd *ufds, nfds_t nfds, int timeout) { 47 int ret; 48 unsigned int i; 49 printf("%d: poll()\n", gettid()); 50 ret = poll(ufds, nfds, timeout); 51 printf("%d: poll() = %d\n", gettid(), ret); 52 if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno)); 53 if (ret > 0) { 54 for (i=0; i<nfds; i++) { 55 if (ufds[i].revents) { 56 printf("\tfd %d ", ufds[i].fd); print_events(ufds[i].revents); 57 } 58 } 59 } 60 return ret; 61} 62 63static int _write(int fd, char *buf, int len) { 64 int ret; 65 66 printf("%d: write(%d)\n", gettid(), fd); 67 ret = write(fd, buf, len); 68 printf("%d: write(%d) = %d\n", gettid(), fd, ret); 69 if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno)); 70 71 return ret; 72} 73 74static int _shutdown(int fd, int how) { 75 int ret; 76 77 printf("%d: shutdown(%d)\n", gettid(), fd); 78 ret = shutdown(fd, how); 79 printf("%d: shutdown(%d) = %d\n", gettid(), fd, ret); 80 if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno)); 81 82 return ret; 83} 84static void thread_poll(void *args) { 85 int fd = (int)args; 86 struct pollfd pfd; 87 printf("%d: START\n", gettid()); 88 pfd.fd = fd; 89 pfd.events = 0; 90 _poll(&pfd, 1, -1); 91 printf("%d: END\n", gettid()); 92} 93 94static void thread_pollin(void *args) { 95 int fd = (int)args; 96 struct pollfd pfd; 97 printf("%d: START\n", gettid()); 98 pfd.fd = fd; 99 pfd.events = POLLIN; 100 _poll(&pfd, 1, -1); 101 printf("%d: END\n", gettid()); 102} 103 104static void thread_close(void *args) { 105 int fd = (int)args; 106 printf("%d: START\n", gettid()); 107 _close(fd); 108 printf("%d: END\n", gettid()); 109} 110 111static int do_poll_poll_close() { 112 pthread_t t1; 113 pthread_t t2; 114 int fd[2]; 115 116 if (pipe(fd)) return -1; 117 118 pthread_create(&t1, NULL, (void *)thread_poll, NULL); 119 pthread_create(&t2, NULL, (void *)thread_poll, NULL); 120 121 sleep(1); 122 123 _close(fd[1]); 124 125 pthread_join(t1, NULL); 126 pthread_join(t2, NULL); 127 128 return 0; 129} 130 131static int do_pipe_pipe_pipe() { 132 int fd[2]; 133 int i; 134 135 while (1) { 136 if (pipe(fd)) { 137 printf("pipe: %s\n", strerror(errno)); 138 return -1; 139 } 140 printf("%d %d\n", fd[0], fd[1]); 141 close(fd[0]); 142 close(fd[1]); 143 } 144 145 return 0; 146} 147static int do_pollin_pollin_write() { 148 pthread_t t1; 149 pthread_t t2; 150 int fd[2]; 151 char buf = 'a'; 152 int i; 153 154 if (pipe(fd)) return -1; 155 156 pthread_create(&t1, NULL, (void *)thread_pollin, (void *)fd[0]); 157 pthread_create(&t2, NULL, (void *)thread_pollin, (void *)fd[0]); 158 159 sleep(1); 160 161 for (i = 0; i < 100; i++) 162 _write(fd[1], &buf, 1); 163 164 pthread_join(t1, NULL); 165 pthread_join(t2, NULL); 166 167 return 0; 168} 169 170static int do_poll_poll_shutdown() { 171#if 0 172 pthread_t t1; 173 pthread_t t2; 174 int fd[2]; 175 176 if (pipe(fd)) return -1; 177 178 pthread_create(&t1, NULL, (void *)thread_poll, (void *)fd[0]); 179 pthread_create(&t2, NULL, (void *)thread_poll, (void *)fd[0]); 180 181 sleep(1); 182 183 _shutdown(fd[1], SHUT_RDWR); 184 185 pthread_join(t1, NULL); 186 pthread_join(t2, NULL); 187#endif 188 189 return -1; 190} 191 192static int THREADS = 100; 193 194static int do_close_poll_poll_poll() { 195 pthread_t t[THREADS]; 196 int i; 197 int fd[2]; 198 199 if (pipe(fd)) return -1; 200 201 _close(fd[1]); 202 203 for (i = 0; i < THREADS; i++) 204 pthread_create(&t[i], NULL, (void *)thread_poll, (void *)fd[0]); 205 206 for (i = 0; i < THREADS; i++) 207 pthread_join(t[i], NULL); 208 209 return 0; 210} 211 212static int do_close_close_close() { 213 pthread_t t[THREADS]; 214 int i; 215 int fd[2]; 216 217 if (pipe(fd)) return -1; 218 219 for (i = 0; i < THREADS; i++) 220 pthread_create(&t[i], NULL, (void *)thread_close, (void *)fd[i%2]); 221 222 return 0; 223} 224 225static int pipe_close_w_close_r_repeat() { 226 int fd[2]; 227 pthread_t t; 228 int i; 229 230 for (i = 0; i < THREADS; i++) { 231 if (pipe(fd)) return -1; 232 pthread_create(&t, NULL, (void *)thread_poll, (void *)fd[0]); 233 _close(fd[1]); 234 _close(fd[0]); 235 pthread_join(t, NULL); 236 } 237 238 return 0; 239} 240 241struct { 242 char *name; 243 int (*ptr)(); 244} function_table[] = { 245 {"pipe_pipe_pipe", do_pipe_pipe_pipe}, 246 {"poll_poll_close", do_poll_poll_close}, 247 {"pollin_pollin_write", do_pollin_pollin_write}, 248 {"poll_poll_shutdown", do_poll_poll_shutdown}, 249 {"close_poll_poll_poll", do_close_poll_poll_poll}, 250 {"close_close_close", do_close_close_close}, 251 {"pipe_close_w_close_w_repeat", pipe_close_w_close_r_repeat}, 252 {NULL, NULL}, 253}; 254 255static void usage() { 256 int i; 257 258 printf("Usage:\n"); 259 for (i = 0; function_table[i].name; i++) { 260 printf("\tpipetest %s\n", function_table[i].name); 261 } 262} 263 264int main(int argc, char **argv) { 265 int i; 266 267 if (argc != 2) { 268 usage(); 269 return -1; 270 } 271 for (i = 0; function_table[i].name; i++) { 272 if (!strcmp(argv[1], function_table[i].name)) { 273 printf("%s\n", function_table[i].name); 274 return (*function_table[i].ptr)(); 275 } 276 } 277 usage(); 278 return -1; 279} 280