1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 /*
7 * File: pipeself.c
8 *
9 * Description:
10 * This test has two threads communicating with each other using
11 * two unidirectional pipes. The primordial thread is the ping
12 * thread and the other thread is the pong thread. The ping
13 * thread writes "ping" to the pong thread and the pong thread
14 * writes "pong" back.
15 */
16
17 #include "prio.h"
18 #include "prerror.h"
19 #include "prthread.h"
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24
25 #define NUM_ITERATIONS 10
26
27 static PRFileDesc *ping_in, *ping_out;
28 static PRFileDesc *pong_in, *pong_out;
29
PongThreadFunc(void * arg)30 static void PongThreadFunc(void *arg)
31 {
32 char buf[1024];
33 int idx;
34 PRInt32 nBytes;
35 PRStatus status;
36
37 for (idx = 0; idx < NUM_ITERATIONS; idx++) {
38 memset(buf, 0, sizeof(buf));
39 nBytes = PR_Read(pong_in, buf, sizeof(buf));
40 if (nBytes == -1) {
41 fprintf(stderr, "PR_Read failed\n");
42 exit(1);
43 }
44 printf("pong thread: received \"%s\"\n", buf);
45 if (nBytes != 5) {
46 fprintf(stderr, "pong thread: expected 5 bytes but got %d bytes\n",
47 nBytes);
48 exit(1);
49 }
50 if (strcmp(buf, "ping") != 0) {
51 fprintf(stderr, "pong thread: expected \"ping\" but got \"%s\"\n",
52 buf);
53 exit(1);
54 }
55 strcpy(buf, "pong");
56 printf("pong thread: sending \"%s\"\n", buf);
57 nBytes = PR_Write(pong_out, buf, 5);
58 if (nBytes == -1) {
59 fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(),
60 PR_GetOSError());
61 exit(1);
62 }
63 }
64
65 status = PR_Close(pong_in);
66 if (status == PR_FAILURE) {
67 fprintf(stderr, "PR_Close failed\n");
68 exit(1);
69 }
70 status = PR_Close(pong_out);
71 if (status == PR_FAILURE) {
72 fprintf(stderr, "PR_Close failed\n");
73 exit(1);
74 }
75 }
76
main(int argc,char ** argv)77 int main(int argc, char **argv)
78 {
79 PRStatus status;
80 PRThread *pongThread;
81 char buf[1024];
82 PRInt32 nBytes;
83 int idx;
84
85 status = PR_CreatePipe(&ping_in, &pong_out);
86 if (status == PR_FAILURE) {
87 fprintf(stderr, "PR_CreatePipe failed\n");
88 exit(1);
89 }
90 status = PR_CreatePipe(&pong_in, &ping_out);
91 if (status == PR_FAILURE) {
92 fprintf(stderr, "PR_CreatePipe failed\n");
93 exit(1);
94 }
95
96 pongThread = PR_CreateThread(PR_USER_THREAD, PongThreadFunc, NULL,
97 PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
98 if (pongThread == NULL) {
99 fprintf(stderr, "PR_CreateThread failed\n");
100 exit(1);
101 }
102
103 for (idx = 0; idx < NUM_ITERATIONS; idx++) {
104 strcpy(buf, "ping");
105 printf("ping thread: sending \"%s\"\n", buf);
106 nBytes = PR_Write(ping_out, buf, 5);
107 if (nBytes == -1) {
108 fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(),
109 PR_GetOSError());
110 exit(1);
111 }
112 memset(buf, 0, sizeof(buf));
113 nBytes = PR_Read(ping_in, buf, sizeof(buf));
114 if (nBytes == -1) {
115 fprintf(stderr, "PR_Read failed\n");
116 exit(1);
117 }
118 printf("ping thread: received \"%s\"\n", buf);
119 if (nBytes != 5) {
120 fprintf(stderr, "ping thread: expected 5 bytes but got %d bytes\n",
121 nBytes);
122 exit(1);
123 }
124 if (strcmp(buf, "pong") != 0) {
125 fprintf(stderr, "ping thread: expected \"pong\" but got \"%s\"\n",
126 buf);
127 exit(1);
128 }
129 }
130
131 status = PR_Close(ping_in);
132 if (status == PR_FAILURE) {
133 fprintf(stderr, "PR_Close failed\n");
134 exit(1);
135 }
136 status = PR_Close(ping_out);
137 if (status == PR_FAILURE) {
138 fprintf(stderr, "PR_Close failed\n");
139 exit(1);
140 }
141 status = PR_JoinThread(pongThread);
142 if (status == PR_FAILURE) {
143 fprintf(stderr, "PR_JoinThread failed\n");
144 exit(1);
145 }
146
147 #if defined(XP_UNIX) && !defined(SYMBIAN)
148 /*
149 * Test PR_Available for pipes
150 */
151 status = PR_CreatePipe(&ping_in, &ping_out);
152 if (status == PR_FAILURE) {
153 fprintf(stderr, "PR_CreatePipe failed\n");
154 exit(1);
155 }
156 nBytes = PR_Write(ping_out, buf, 250);
157 if (nBytes == -1) {
158 fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(),
159 PR_GetOSError());
160 exit(1);
161 }
162 nBytes = PR_Available(ping_in);
163 if (nBytes < 0) {
164 fprintf(stderr, "PR_Available failed: (%d, %d)\n", PR_GetError(),
165 PR_GetOSError());
166 exit(1);
167 } else if (nBytes != 250) {
168 fprintf(stderr, "PR_Available: expected 250 bytes but got %d bytes\n",
169 nBytes);
170 exit(1);
171 }
172 printf("PR_Available: expected %d, got %d bytes\n",250, nBytes);
173 /* read some data */
174 nBytes = PR_Read(ping_in, buf, 7);
175 if (nBytes == -1) {
176 fprintf(stderr, "PR_Read failed\n");
177 exit(1);
178 }
179 /* check available data */
180 nBytes = PR_Available(ping_in);
181 if (nBytes < 0) {
182 fprintf(stderr, "PR_Available failed: (%d, %d)\n", PR_GetError(),
183 PR_GetOSError());
184 exit(1);
185 } else if (nBytes != (250 - 7)) {
186 fprintf(stderr, "PR_Available: expected 243 bytes but got %d bytes\n",
187 nBytes);
188 exit(1);
189 }
190 printf("PR_Available: expected %d, got %d bytes\n",243, nBytes);
191 /* read all data */
192 nBytes = PR_Read(ping_in, buf, sizeof(buf));
193 if (nBytes == -1) {
194 fprintf(stderr, "PR_Read failed\n");
195 exit(1);
196 } else if (nBytes != 243) {
197 fprintf(stderr, "PR_Read failed: expected %d, got %d bytes\n",
198 243, nBytes);
199 exit(1);
200 }
201 /* check available data */
202 nBytes = PR_Available(ping_in);
203 if (nBytes < 0) {
204 fprintf(stderr, "PR_Available failed: (%d, %d)\n", PR_GetError(),
205 PR_GetOSError());
206 exit(1);
207 } else if (nBytes != 0) {
208 fprintf(stderr, "PR_Available: expected 0 bytes but got %d bytes\n",
209 nBytes);
210 exit(1);
211 }
212 printf("PR_Available: expected %d, got %d bytes\n", 0, nBytes);
213
214 status = PR_Close(ping_in);
215 if (status == PR_FAILURE) {
216 fprintf(stderr, "PR_Close failed\n");
217 exit(1);
218 }
219 status = PR_Close(ping_out);
220 if (status == PR_FAILURE) {
221 fprintf(stderr, "PR_Close failed\n");
222 exit(1);
223 }
224 #endif /* XP_UNIX */
225
226 printf("PASS\n");
227 return 0;
228 }
229