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/. */
13 #include "obsolete/probslet.h"
19 #define NUMBER_ROUNDS 5
23 ** Make win16 unit_time interval 300 milliseconds, others get 100
25 #define UNIT_TIME 200 /* unit time in milliseconds */
27 #define UNIT_TIME 100 /* unit time in milliseconds */
30 #undef USE_PR_SELECT /* If defined, we use PR_Select.
31 * If not defined, use PR_Poll instead. */
33 #if defined(USE_PR_SELECT)
37 static void PR_CALLBACK
38 clientThreadFunc(void *arg
)
40 PRUintn port
= (PRUintn
)arg
;
45 PRIntervalTime unitTime
= PR_MillisecondsToInterval(UNIT_TIME
);
46 PRSocketOptionData optval
;
50 /* Initialize the buffer so that Purify won't complain */
51 memset(buf
, 0, sizeof(buf
));
53 addr
.inet
.family
= PR_AF_INET
;
54 addr
.inet
.port
= PR_htons((PRUint16
)port
);
55 addr
.inet
.ip
= PR_htonl(PR_INADDR_LOOPBACK
);
56 PR_snprintf(buf
, sizeof(buf
), "%hu", addr
.inet
.ip
);
60 sock
= PR_NewTCPSocket();
61 optval
.option
= PR_SockOpt_Nonblocking
;
62 optval
.value
.non_blocking
= PR_TRUE
;
63 PR_SetSocketOption(sock
, &optval
);
64 retVal
= PR_Connect(sock
, &addr
, PR_INTERVAL_NO_TIMEOUT
);
65 if (retVal
== PR_FAILURE
&& PR_GetError() == PR_IN_PROGRESS_ERROR
) {
66 #if !defined(USE_PR_SELECT)
69 fprintf(stderr
, "connect: EWOULDBLOCK, good\n");
71 pd
.in_flags
= PR_POLL_WRITE
;
72 n
= PR_Poll(&pd
, 1, PR_INTERVAL_NO_TIMEOUT
);
74 PR_ASSERT(pd
.out_flags
== PR_POLL_WRITE
);
78 fprintf(stderr
, "connect: EWOULDBLOCK, good\n");
79 PR_FD_ZERO(&writeSet
);
80 PR_FD_SET(sock
, &writeSet
);
81 n
= PR_Select(0, NULL
, &writeSet
, NULL
, PR_INTERVAL_NO_TIMEOUT
);
83 PR_ASSERT(PR_FD_ISSET(sock
, &writeSet
));
86 printf("client connected\n");
89 /* time 4, 7, 11, etc. */
90 for (i
= 0; i
< NUMBER_ROUNDS
; i
++) {
91 PR_Sleep(3 * unitTime
);
92 nBytes
= PR_Write(sock
, buf
, sizeof(buf
));
94 if (PR_GetError() == PR_WOULD_BLOCK_ERROR
) {
95 fprintf(stderr
, "write: EWOULDBLOCK\n");
98 fprintf(stderr
, "write: failed\n");
101 printf("client sent %d bytes\n", nBytes
);
108 static PRIntn PR_CALLBACK
RealMain( PRIntn argc
, char **argv
)
110 PRFileDesc
*listenSock
, *sock
;
113 char buf
[CHUNK_SIZE
];
114 PRThread
*clientThread
;
116 PRSocketOptionData optval
;
118 PRIntervalTime unitTime
= PR_MillisecondsToInterval(UNIT_TIME
);
120 /* Create a listening socket */
121 if ((listenSock
= PR_NewTCPSocket()) == NULL
) {
122 fprintf(stderr
, "Can't create a new TCP socket\n");
125 addr
.inet
.family
= PR_AF_INET
;
126 addr
.inet
.ip
= PR_htonl(PR_INADDR_ANY
);
127 addr
.inet
.port
= PR_htons(0);
128 if (PR_Bind(listenSock
, &addr
) == PR_FAILURE
) {
129 fprintf(stderr
, "Can't bind socket\n");
132 if (PR_GetSockName(listenSock
, &addr
) == PR_FAILURE
) {
133 fprintf(stderr
, "PR_GetSockName failed\n");
136 listenPort
= PR_ntohs(addr
.inet
.port
);
137 if (PR_Listen(listenSock
, 5) == PR_FAILURE
) {
138 fprintf(stderr
, "Can't listen on a socket\n");
142 PR_snprintf(buf
, sizeof(buf
),
143 "The server thread is listening on port %hu\n\n",
147 clientThread
= PR_CreateThread(PR_USER_THREAD
,
148 clientThreadFunc
, (void *) listenPort
,
149 PR_PRIORITY_NORMAL
, PR_LOCAL_THREAD
,
150 PR_UNJOINABLE_THREAD
, 0);
151 if (clientThread
== NULL
) {
152 fprintf(stderr
, "can't create thread\n");
156 printf("client thread created.\n");
158 optval
.option
= PR_SockOpt_Nonblocking
;
159 optval
.value
.non_blocking
= PR_TRUE
;
160 PR_SetSocketOption(listenSock
, &optval
);
162 sock
= PR_Accept(listenSock
, NULL
, PR_INTERVAL_NO_TIMEOUT
);
163 if (sock
!= NULL
|| PR_GetError() != PR_WOULD_BLOCK_ERROR
) {
164 PL_PrintError("First Accept\n");
165 fprintf(stderr
, "First PR_Accept() xxx\n" );
168 printf("accept: EWOULDBLOCK, good\n");
171 PR_Sleep(2 * unitTime
);
172 sock
= PR_Accept(listenSock
, NULL
, PR_INTERVAL_NO_TIMEOUT
);
174 PL_PrintError("Second Accept\n");
175 fprintf(stderr
, "Second PR_Accept() failed: (%d, %d)\n",
176 PR_GetError(), PR_GetOSError());
179 printf("accept: succeeded, good\n");
181 PR_Close(listenSock
);
183 PR_SetSocketOption(sock
, &optval
);
185 /* time 3, 5, 6, 8, etc. */
186 for (i
= 0; i
< NUMBER_ROUNDS
; i
++) {
188 retVal
= PR_Recv(sock
, buf
, sizeof(buf
), 0, PR_INTERVAL_NO_TIMEOUT
);
189 if (retVal
!= -1 || PR_GetError() != PR_WOULD_BLOCK_ERROR
) {
190 PL_PrintError("First Receive:\n");
191 fprintf(stderr
, "First PR_Recv: retVal: %ld, Error: %ld\n",
192 retVal
, PR_GetError());
195 printf("read: EWOULDBLOCK, good\n");
197 PR_Sleep(2 * unitTime
);
198 retVal
= PR_Recv(sock
, buf
, sizeof(buf
), 0, PR_INTERVAL_NO_TIMEOUT
);
199 if (retVal
!= CHUNK_SIZE
) {
200 PL_PrintError("Second Receive:\n");
201 fprintf(stderr
, "Second PR_Recv: retVal: %ld, Error: %ld\n",
202 retVal
, PR_GetError());
205 printf("read: %d bytes, good\n", retVal
);
210 printf("All tests finished\n");
215 int main(int argc
, char **argv
)
220 rv
= PR_Initialize(RealMain
, argc
, argv
, 0);