VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/nsprpub/pr/tests/nonblock.c@ 55761

最後變更 在這個檔案從55761是 1,由 vboxsync 提交於 55 年 前

import

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 8.0 KB
 
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 *
15 * The Original Code is the Netscape Portable Runtime (NSPR).
16 *
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998-2000
20 * the Initial Developer. All Rights Reserved.
21 *
22 * Contributor(s):
23 *
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
35 *
36 * ***** END LICENSE BLOCK ***** */
37
38#include "nspr.h"
39#include "prio.h"
40#include "prerror.h"
41#include "prlog.h"
42#include "prprf.h"
43#include "prnetdb.h"
44#include "plerror.h"
45#ifndef XP_MAC
46#include "obsolete/probslet.h"
47#else
48#include "probslet.h"
49#endif
50
51#include <stdio.h>
52#include <string.h>
53#include <stdlib.h>
54
55#define NUMBER_ROUNDS 5
56
57#if defined(WIN16)
58/*
59** Make win16 unit_time interval 300 milliseconds, others get 100
60*/
61#define UNIT_TIME 200 /* unit time in milliseconds */
62#else
63#define UNIT_TIME 100 /* unit time in milliseconds */
64#endif
65#define CHUNK_SIZE 10
66#undef USE_PR_SELECT /* If defined, we use PR_Select.
67 * If not defined, use PR_Poll instead. */
68
69#if defined(USE_PR_SELECT)
70#include "pprio.h"
71#endif
72
73#ifdef XP_MAC
74int fprintf(FILE *stream, const char *fmt, ...)
75{
76PR_LogPrint(fmt);
77return 0;
78}
79#define printf PR_LogPrint
80extern void SetupMacPrintfLog(char *logFile);
81#endif
82
83static void PR_CALLBACK
84clientThreadFunc(void *arg)
85{
86 PRUintn port = (PRUintn)arg;
87 PRFileDesc *sock;
88 PRNetAddr addr;
89 char buf[CHUNK_SIZE];
90 int i;
91 PRIntervalTime unitTime = PR_MillisecondsToInterval(UNIT_TIME);
92 PRSocketOptionData optval;
93 PRStatus retVal;
94 PRInt32 nBytes;
95
96 /* Initialize the buffer so that Purify won't complain */
97 memset(buf, 0, sizeof(buf));
98
99 addr.inet.family = PR_AF_INET;
100 addr.inet.port = PR_htons((PRUint16)port);
101 addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
102 PR_snprintf(buf, sizeof(buf), "%hu", addr.inet.ip);
103
104 /* time 1 */
105 PR_Sleep(unitTime);
106 sock = PR_NewTCPSocket();
107 optval.option = PR_SockOpt_Nonblocking;
108 optval.value.non_blocking = PR_TRUE;
109 PR_SetSocketOption(sock, &optval);
110 retVal = PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT);
111 if (retVal == PR_FAILURE && PR_GetError() == PR_IN_PROGRESS_ERROR) {
112#if !defined(USE_PR_SELECT)
113 PRPollDesc pd;
114 PRInt32 n;
115 fprintf(stderr, "connect: EWOULDBLOCK, good\n");
116 pd.fd = sock;
117 pd.in_flags = PR_POLL_WRITE;
118 n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
119 PR_ASSERT(n == 1);
120 PR_ASSERT(pd.out_flags == PR_POLL_WRITE);
121#else
122 PR_fd_set writeSet;
123 PRInt32 n;
124 fprintf(stderr, "connect: EWOULDBLOCK, good\n");
125 PR_FD_ZERO(&writeSet);
126 PR_FD_SET(sock, &writeSet);
127 n = PR_Select(0, NULL, &writeSet, NULL, PR_INTERVAL_NO_TIMEOUT);
128 PR_ASSERT(n == 1);
129 PR_ASSERT(PR_FD_ISSET(sock, &writeSet));
130#endif
131 }
132 printf("client connected\n");
133 fflush(stdout);
134
135 /* time 4, 7, 11, etc. */
136 for (i = 0; i < NUMBER_ROUNDS; i++) {
137 PR_Sleep(3 * unitTime);
138 nBytes = PR_Write(sock, buf, sizeof(buf));
139 if (nBytes == -1) {
140 if (PR_GetError() == PR_WOULD_BLOCK_ERROR) {
141 fprintf(stderr, "write: EWOULDBLOCK\n");
142 exit(1);
143 } else {
144 fprintf(stderr, "write: failed\n");
145 }
146 }
147 printf("client sent %d bytes\n", nBytes);
148 fflush(stdout);
149 }
150
151 PR_Close(sock);
152}
153
154static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
155{
156 PRFileDesc *listenSock, *sock;
157 PRUint16 listenPort;
158 PRNetAddr addr;
159 char buf[CHUNK_SIZE];
160 PRThread *clientThread;
161 PRInt32 retVal;
162 PRSocketOptionData optval;
163 PRIntn i;
164 PRIntervalTime unitTime = PR_MillisecondsToInterval(UNIT_TIME);
165
166#ifdef XP_MAC
167 SetupMacPrintfLog("nonblock.log");
168#endif
169
170 /* Create a listening socket */
171 if ((listenSock = PR_NewTCPSocket()) == NULL) {
172 fprintf(stderr, "Can't create a new TCP socket\n");
173 exit(1);
174 }
175 addr.inet.family = PR_AF_INET;
176 addr.inet.ip = PR_htonl(PR_INADDR_ANY);
177 addr.inet.port = PR_htons(0);
178 if (PR_Bind(listenSock, &addr) == PR_FAILURE) {
179 fprintf(stderr, "Can't bind socket\n");
180 exit(1);
181 }
182 if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) {
183 fprintf(stderr, "PR_GetSockName failed\n");
184 exit(1);
185 }
186 listenPort = PR_ntohs(addr.inet.port);
187 if (PR_Listen(listenSock, 5) == PR_FAILURE) {
188 fprintf(stderr, "Can't listen on a socket\n");
189 exit(1);
190 }
191
192 PR_snprintf(buf, sizeof(buf),
193 "The server thread is listening on port %hu\n\n",
194 listenPort);
195 printf("%s", buf);
196
197 clientThread = PR_CreateThread(PR_USER_THREAD,
198 clientThreadFunc, (void *) listenPort,
199 PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
200 PR_UNJOINABLE_THREAD, 0);
201 if (clientThread == NULL) {
202 fprintf(stderr, "can't create thread\n");
203 exit(1);
204 }
205
206 printf("client thread created.\n");
207
208 optval.option = PR_SockOpt_Nonblocking;
209 optval.value.non_blocking = PR_TRUE;
210 PR_SetSocketOption(listenSock, &optval);
211 /* time 0 */
212 sock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT);
213 if (sock != NULL || PR_GetError() != PR_WOULD_BLOCK_ERROR) {
214 PL_PrintError("First Accept\n");
215 fprintf(stderr, "First PR_Accept() xxx\n" );
216 exit(1);
217 }
218 printf("accept: EWOULDBLOCK, good\n");
219 fflush(stdout);
220 /* time 2 */
221 PR_Sleep(2 * unitTime);
222 sock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT);
223 if (sock == NULL) {
224 PL_PrintError("Second Accept\n");
225 fprintf(stderr, "Second PR_Accept() failed: (%d, %d)\n",
226 PR_GetError(), PR_GetOSError());
227 exit(1);
228 }
229 printf("accept: succeeded, good\n");
230 fflush(stdout);
231 PR_Close(listenSock);
232
233 PR_SetSocketOption(sock, &optval);
234
235 /* time 3, 5, 6, 8, etc. */
236 for (i = 0; i < NUMBER_ROUNDS; i++) {
237 PR_Sleep(unitTime);
238 retVal = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT);
239 if (retVal != -1 || PR_GetError() != PR_WOULD_BLOCK_ERROR) {
240 PL_PrintError("First Receive:\n");
241 fprintf(stderr, "First PR_Recv: retVal: %ld, Error: %ld\n",
242 retVal, PR_GetError());
243 exit(1);
244 }
245 printf("read: EWOULDBLOCK, good\n");
246 fflush(stdout);
247 PR_Sleep(2 * unitTime);
248 retVal = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT);
249 if (retVal != CHUNK_SIZE) {
250 PL_PrintError("Second Receive:\n");
251 fprintf(stderr, "Second PR_Recv: retVal: %ld, Error: %ld\n",
252 retVal, PR_GetError());
253 exit(1);
254 }
255 printf("read: %d bytes, good\n", retVal);
256 fflush(stdout);
257 }
258 PR_Close(sock);
259
260 printf("All tests finished\n");
261 printf("PASS\n");
262 return 0;
263}
264
265PRIntn main(PRIntn argc, char *argv[])
266{
267 PRIntn rv;
268
269 PR_STDIO_INIT();
270 rv = PR_Initialize(RealMain, argc, argv, 0);
271 return rv;
272} /* main */
273
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette