Add to git.
[pthrlib.git] / src / test_select.c
1 /* Test pth_select call (this also tests pth_poll, implicitly).
2  * Copyright (C) 2001 Richard W.M. Jones <rich@annexia.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the Free
16  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  *
18  * $Id: test_select.c,v 1.4 2003/02/05 22:13:33 rich Exp $
19  */
20
21 #include "config.h"
22
23 #include <stdio.h>
24 #include <stdlib.h>
25
26 #ifdef HAVE_UNISTD_H
27 #include <unistd.h>
28 #endif
29
30 #ifdef HAVE_FCNTL_H
31 #include <fcntl.h>
32 #endif
33
34 #ifdef HAVE_SYS_TIME_H
35 #include <sys/time.h>
36 #endif
37
38 #ifdef HAVE_STRING_H
39 #include <string.h>
40 #endif
41
42 #include "pthr_reactor.h"
43 #include "pthr_pseudothread.h"
44
45 #define NR_WRITERS   4
46 #define NR_CHARS   100
47
48 static pool reader_pool;
49 static pseudothread reader_pth;
50 static pool writer_pool[NR_WRITERS];
51 static pseudothread writer_pth[NR_WRITERS];
52
53 static int fds[NR_WRITERS][2];
54
55 static void
56 writer (void *vp)
57 {
58   int id = *(int *)vp;
59   int i, fd = fds[id][1];
60   char c[1] = { '0' + id };
61
62   for (i = 0; i < NR_CHARS; ++i)
63     {
64       pth_write (fd, c, 1);
65       pth_millisleep (3);
66     }
67
68   c[0] = '\xff';
69   pth_write (fd, c, 1);
70   close (fd);
71 }
72
73 static void
74 reader (void *vp)
75 {
76   int i, running = NR_WRITERS, r, max_fd = -1;
77   fd_set readfds, returnfds;
78   struct timeval tv;
79
80   FD_ZERO (&readfds);
81
82   for (i = 0; i < NR_WRITERS; ++i)
83     {
84       int fd = fds[i][0];
85
86       if (fd > max_fd) max_fd = fd;
87       FD_SET (fd, &readfds);
88     }
89
90   while (running)
91     {
92       tv.tv_sec = 0;
93       tv.tv_usec = 1000;
94       returnfds = readfds;
95       r = pth_select (max_fd+1, &returnfds, 0, 0, &tv);
96
97       if (r == -1) abort ();
98       if (r > 0)
99         {
100           for (i = 0; i <= max_fd; ++i)
101             {
102               if (FD_ISSET (i, &returnfds))
103                 {
104                   char c[1];
105
106                   pth_read (i, c, 1);
107                   if (c[0] == '\xff')
108                     {
109                       running--;
110                       close (i);
111                     }
112                   else
113                     {
114                       putchar (c[0]); putchar ('\r'); fflush (stdout);
115                     }
116                 }
117             }
118         }
119     }
120 }
121
122 int
123 main ()
124 {
125   int i;
126
127   for (i = 0; i < NR_WRITERS; ++i)
128     {
129       if (pipe (fds[i]) == -1) abort ();
130
131       if (fcntl (fds[i][0], F_SETFL, O_NONBLOCK) == -1) abort ();
132       if (fcntl (fds[i][1], F_SETFL, O_NONBLOCK) == -1) abort ();
133
134       writer_pool[i] = new_subpool (global_pool);
135       writer_pth[i] = new_pseudothread (writer_pool[i], writer, &i,
136                                         "writer");
137       pth_start (writer_pth[i]);
138     }
139
140   reader_pool = new_subpool (global_pool);
141   reader_pth = new_pseudothread (reader_pool, reader, 0, "reader");
142   pth_start (reader_pth);
143
144   while (pseudothread_count_threads () > 0)
145     reactor_invoke ();
146
147   exit (0);
148 }