Bug Summary

File:pr/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/pr/tests/../../../pr/tests/cltsrv.c
Warning:line 1162, column 21
Value stored to 'rv' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name cltsrv.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nspr/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/pr/tests -fcoverage-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nspr/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/pr/tests -resource-dir /usr/lib/llvm-18/lib/clang/18 -U NDEBUG -D DEBUG_jenkins -D PACKAGE_NAME="" -D PACKAGE_TARNAME="" -D PACKAGE_VERSION="" -D PACKAGE_STRING="" -D PACKAGE_BUGREPORT="" -D PACKAGE_URL="" -D DEBUG=1 -D HAVE_VISIBILITY_HIDDEN_ATTRIBUTE=1 -D HAVE_VISIBILITY_PRAGMA=1 -D XP_UNIX=1 -D _GNU_SOURCE=1 -D HAVE_FCNTL_FILE_LOCKING=1 -D HAVE_POINTER_LOCALTIME_R=1 -D LINUX=1 -D HAVE_DLADDR=1 -D HAVE_GETTID=1 -D HAVE_LCHOWN=1 -D HAVE_SETPRIORITY=1 -D HAVE_STRERROR=1 -D HAVE_SYSCALL=1 -D HAVE_SECURE_GETENV=1 -D _REENTRANT=1 -D FORCE_PR_LOG -D _PR_PTHREADS -U HAVE_CVAR_BUILT_ON_SEM -I /var/lib/jenkins/workspace/nss-scan-build/nss/../dist/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/include -I ../../../pr/include -I ../../../pr/include/private -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -ferror-limit 19 -fvisibility=hidden -fgnuc-version=4.2.1 -fno-inline -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-05-18-082241-28900-1 -x c ../../../pr/tests/cltsrv.c
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 *
8 * Notes:
9 * [1] lth. The call to Sleep() is a hack to get the test case to run
10 * on Windows 95. Without it, the test case fails with an error
11 * WSAECONNRESET following a recv() call. The error is caused by the
12 * server side thread termination without a shutdown() or closesocket()
13 * call. Windows docmunentation suggests that this is predicted
14 * behavior; that other platforms get away with it is ... serindipity.
15 * The test case should shutdown() or closesocket() before
16 * thread termination. I didn't have time to figure out where or how
17 * to do it. The Sleep() call inserts enough delay to allow the
18 * client side to recv() all his data before the server side thread
19 * terminates. Whew! ...
20 *
21 ** Modification History:
22 * 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
23 * The debug mode will print all of the printfs associated with this test.
24 * The regress mode will be the default mode. Since the regress tool limits
25 * the output to a one line status:PASS or FAIL,all of the printf statements
26 * have been handled with an if (debug_mode) statement.
27 */
28
29#include "prclist.h"
30#include "prcvar.h"
31#include "prerror.h"
32#include "prinit.h"
33#include "prinrval.h"
34#include "prio.h"
35#include "prlock.h"
36#include "prlog.h"
37#include "prtime.h"
38#include "prmem.h"
39#include "prnetdb.h"
40#include "prprf.h"
41#include "prthread.h"
42
43#include "pprio.h"
44#include "primpl.h"
45
46#include "plstr.h"
47#include "plerror.h"
48#include "plgetopt.h"
49
50#include <stdlib.h>
51#include <string.h>
52
53#if defined(XP_UNIX1)
54#include <math.h>
55#endif
56
57/*
58** This is the beginning of the test
59*/
60
61#define RECV_FLAGS0 0
62#define SEND_FLAGS0 0
63#define DEFAULT_LOW0 0
64#define DEFAULT_HIGH0 0
65#define BUFFER_SIZE1024 1024
66#define DEFAULT_BACKLOG5 5
67
68#ifdef DEBUG1
69#define PORT_INC_DO+100 +100
70#else
71#define PORT_INC_DO+100
72#endif
73#ifdef IS_64
74#define PORT_INC_3264+200 +200
75#else
76#define PORT_INC_3264+200
77#endif
78
79#define DEFAULT_PORT12849 +100 +200 12849 PORT_INC_DO+100 PORT_INC_3264+200
80
81#define DEFAULT_CLIENTS1 1
82#define ALLOWED_IN_ACCEPT1 1
83#define DEFAULT_CLIPPING1000 1000
84#define DEFAULT_WORKERS_MIN1 1
85#define DEFAULT_WORKERS_MAX1 1
86#define DEFAULT_SERVER"localhost" "localhost"
87#define DEFAULT_EXECUTION_TIME10 10
88#define DEFAULT_CLIENT_TIMEOUT4000 4000
89#define DEFAULT_SERVER_TIMEOUT4000 4000
90#define DEFAULT_SERVER_PRIORITYPR_PRIORITY_HIGH PR_PRIORITY_HIGH
91
92typedef enum CSState_e {cs_init, cs_run, cs_stop, cs_exit} CSState_t;
93
94static void PR_CALLBACK Worker(void *arg);
95typedef struct CSPool_s CSPool_t;
96typedef struct CSWorker_s CSWorker_t;
97typedef struct CSServer_s CSServer_t;
98typedef enum Verbosity
99{
100 TEST_LOG_ALWAYS,
101 TEST_LOG_ERROR,
102 TEST_LOG_WARNING,
103 TEST_LOG_NOTICE,
104 TEST_LOG_INFO,
105 TEST_LOG_STATUS,
106 TEST_LOG_VERBOSE
107} Verbosity;
108
109static PRInt32 domain = AF_INET2;
110static PRInt32 protocol = 6; /* TCP */
111static PRFileDesc *debug_out = NULL((void*)0);
112static PRBool debug_mode = PR_FALSE0;
113static PRBool pthread_stats = PR_FALSE0;
114static Verbosity verbosity = TEST_LOG_ALWAYS;
115static PRThreadScope thread_scope = PR_LOCAL_THREAD;
116
117struct CSWorker_s
118{
119 PRCList element; /* list of the server's workers */
120
121 PRThread *thread; /* this worker objects thread */
122 CSServer_t *server; /* back pointer to server structure */
123};
124
125struct CSPool_s
126{
127 PRCondVar *exiting;
128 PRCondVar *acceptComplete;
129 PRUint32 accepting, active, workers;
130};
131
132struct CSServer_s
133{
134 PRCList list; /* head of worker list */
135
136 PRLock *ml;
137 PRThread *thread; /* the main server thread */
138 PRCondVar *stateChange;
139
140 PRUint16 port; /* port we're listening on */
141 PRUint32 backlog; /* size of our listener backlog */
142 PRFileDesc *listener; /* the fd accepting connections */
143
144 CSPool_t pool; /* statistics on worker threads */
145 CSState_t state; /* the server's state */
146 struct /* controlling worker counts */
147 {
148 PRUint32 minimum, maximum, accepting;
149 } workers;
150
151 /* statistics */
152 PRIntervalTime started, stopped;
153 PRUint32 operations, bytesTransferred;
154};
155
156typedef struct CSDescriptor_s
157{
158 PRInt32 size; /* size of transfer */
159 char filename[60]; /* filename, null padded */
160} CSDescriptor_t;
161
162typedef struct CSClient_s
163{
164 PRLock *ml;
165 PRThread *thread;
166 PRCondVar *stateChange;
167 PRNetAddr serverAddress;
168
169 CSState_t state;
170
171 /* statistics */
172 PRIntervalTime started, stopped;
173 PRUint32 operations, bytesTransferred;
174} CSClient_t;
175
176#define TEST_LOG(l, p, a)do { if (debug_mode || (p <= verbosity)) printf a; } while
(0)
\
177 do { \
178 if (debug_mode || (p <= verbosity)) printf a; \
179 } while (0)
180
181PRLogModuleInfo *cltsrv_log_file = NULL((void*)0);
182
183#define MY_ASSERT(_expr)((_expr)?((void)0):_MY_Assert("_expr","../../../pr/tests/cltsrv.c"
,183))
\
184 ((_expr)?((void)0):_MY_Assert(# _expr,__FILE__"../../../pr/tests/cltsrv.c",__LINE__184))
185
186#define TEST_ASSERT(_expr)((_expr)?((void)0):_MY_Assert("_expr","../../../pr/tests/cltsrv.c"
,186))
\
187 ((_expr)?((void)0):_MY_Assert(# _expr,__FILE__"../../../pr/tests/cltsrv.c",__LINE__187))
188
189static void _MY_Assert(const char *s, const char *file, PRIntn ln)
190{
191 PL_PrintError(NULL((void*)0));
192 PR_Assert(s, file, ln);
193} /* _MY_Assert */
194
195static PRBool Aborted(PRStatus rv)
196{
197 return ((PR_FAILURE == rv) && (PR_PENDING_INTERRUPT_ERROR(-5993L) == PR_GetError())) ?
198 PR_TRUE1 : PR_FALSE0;
199}
200
201static void TimeOfDayMessage(const char *msg, PRThread* me)
202{
203 char buffer[100];
204 PRExplodedTime tod;
205 PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &tod);
206 (void)PR_FormatTime(buffer, sizeof(buffer), "%H:%M:%S", &tod);
207
208 TEST_LOG(do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("%s(0x%p): %s\n", msg, me, buffer); } while (0)
209 cltsrv_log_file, TEST_LOG_ALWAYS,do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("%s(0x%p): %s\n", msg, me, buffer); } while (0)
210 ("%s(0x%p): %s\n", msg, me, buffer))do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("%s(0x%p): %s\n", msg, me, buffer); } while (0)
;
211} /* TimeOfDayMessage */
212
213
214static void PR_CALLBACK Client(void *arg)
215{
216 PRStatus rv;
217 PRIntn index;
218 char buffer[1024];
219 PRFileDesc *fd = NULL((void*)0);
220 PRUintn clipping = DEFAULT_CLIPPING1000;
221 PRThread *me = PR_GetCurrentThread();
222 CSClient_t *client = (CSClient_t*)arg;
223 CSDescriptor_t *descriptor = PR_NEW(CSDescriptor_t)((CSDescriptor_t *) (PR_Malloc((sizeof(CSDescriptor_t)))));
224 PRIntervalTime timeout = PR_MillisecondsToInterval(DEFAULT_CLIENT_TIMEOUT4000);
225
226
227 for (index = 0; index < sizeof(buffer); ++index) {
228 buffer[index] = (char)index;
229 }
230
231 client->started = PR_IntervalNow();
232
233 PR_Lock(client->ml);
234 client->state = cs_run;
235 PR_NotifyCondVar(client->stateChange);
236 PR_Unlock(client->ml);
237
238 TimeOfDayMessage("Client started at", me);
239
240 while (cs_run == client->state)
241 {
242 PRInt32 bytes, descbytes, filebytes, netbytes;
243
244 (void)PR_NetAddrToString(&client->serverAddress, buffer, sizeof(buffer));
245 TEST_LOG(cltsrv_log_file, TEST_LOG_INFO,do { if (debug_mode || (TEST_LOG_INFO <= verbosity)) printf
("\tClient(0x%p): connecting to server at %s\n", me, buffer)
; } while (0)
246 ("\tClient(0x%p): connecting to server at %s\n", me, buffer))do { if (debug_mode || (TEST_LOG_INFO <= verbosity)) printf
("\tClient(0x%p): connecting to server at %s\n", me, buffer)
; } while (0)
;
247
248 fd = PR_Socket(domain, SOCK_STREAMSOCK_STREAM, protocol);
249 TEST_ASSERT(NULL != fd)((((void*)0) != fd)?((void)0):_MY_Assert("NULL != fd","../../../pr/tests/cltsrv.c"
,249))
;
250 rv = PR_Connect(fd, &client->serverAddress, timeout);
251 if (PR_FAILURE == rv)
252 {
253 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tClient(0x%p): conection failed (%d, %d)\n", me, PR_GetError
(), PR_GetOSError()); } while (0)
254 cltsrv_log_file, TEST_LOG_ERROR,do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tClient(0x%p): conection failed (%d, %d)\n", me, PR_GetError
(), PR_GetOSError()); } while (0)
255 ("\tClient(0x%p): conection failed (%d, %d)\n",do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tClient(0x%p): conection failed (%d, %d)\n", me, PR_GetError
(), PR_GetOSError()); } while (0)
256 me, PR_GetError(), PR_GetOSError()))do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tClient(0x%p): conection failed (%d, %d)\n", me, PR_GetError
(), PR_GetOSError()); } while (0)
;
257 goto aborted;
258 }
259
260 memset(descriptor, 0, sizeof(*descriptor));
261 descriptor->size = PR_htonl(descbytes = rand() % clipping);
262 PR_snprintf(
263 descriptor->filename, sizeof(descriptor->filename),
264 "CS%p%p-%p.dat", client->started, me, client->operations);
265 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tClient(0x%p): sending descriptor for %u bytes\n", me, descbytes
); } while (0)
266 cltsrv_log_file, TEST_LOG_VERBOSE,do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tClient(0x%p): sending descriptor for %u bytes\n", me, descbytes
); } while (0)
267 ("\tClient(0x%p): sending descriptor for %u bytes\n", me, descbytes))do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tClient(0x%p): sending descriptor for %u bytes\n", me, descbytes
); } while (0)
;
268 bytes = PR_Send(
269 fd, descriptor, sizeof(*descriptor), SEND_FLAGS0, timeout);
270 if (sizeof(CSDescriptor_t) != bytes)
271 {
272 if (Aborted(PR_FAILURE)) {
273 goto aborted;
274 }
275 if (PR_IO_TIMEOUT_ERROR(-5990L) == PR_GetError())
276 {
277 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tClient(0x%p): send descriptor timeout\n", me); } while (
0)
278 cltsrv_log_file, TEST_LOG_ERROR,do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tClient(0x%p): send descriptor timeout\n", me); } while (
0)
279 ("\tClient(0x%p): send descriptor timeout\n", me))do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tClient(0x%p): send descriptor timeout\n", me); } while (
0)
;
280 goto retry;
281 }
282 }
283 TEST_ASSERT(sizeof(*descriptor) == bytes)((sizeof(*descriptor) == bytes)?((void)0):_MY_Assert("sizeof(*descriptor) == bytes"
,"../../../pr/tests/cltsrv.c",283))
;
284
285 netbytes = 0;
286 while (netbytes < descbytes)
287 {
288 filebytes = sizeof(buffer);
289 if ((descbytes - netbytes) < filebytes) {
290 filebytes = descbytes - netbytes;
291 }
292 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tClient(0x%p): sending %d bytes\n", me, filebytes); } while
(0)
293 cltsrv_log_file, TEST_LOG_VERBOSE,do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tClient(0x%p): sending %d bytes\n", me, filebytes); } while
(0)
294 ("\tClient(0x%p): sending %d bytes\n", me, filebytes))do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tClient(0x%p): sending %d bytes\n", me, filebytes); } while
(0)
;
295 bytes = PR_Send(fd, buffer, filebytes, SEND_FLAGS0, timeout);
296 if (filebytes != bytes)
297 {
298 if (Aborted(PR_FAILURE)) {
299 goto aborted;
300 }
301 if (PR_IO_TIMEOUT_ERROR(-5990L) == PR_GetError())
302 {
303 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tClient(0x%p): send data timeout\n", me); } while (0)
304 cltsrv_log_file, TEST_LOG_ERROR,do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tClient(0x%p): send data timeout\n", me); } while (0)
305 ("\tClient(0x%p): send data timeout\n", me))do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tClient(0x%p): send data timeout\n", me); } while (0)
;
306 goto retry;
307 }
308 }
309 TEST_ASSERT(bytes == filebytes)((bytes == filebytes)?((void)0):_MY_Assert("bytes == filebytes"
,"../../../pr/tests/cltsrv.c",309))
;
310 netbytes += bytes;
311 }
312 filebytes = 0;
313 while (filebytes < descbytes)
314 {
315 netbytes = sizeof(buffer);
316 if ((descbytes - filebytes) < netbytes) {
317 netbytes = descbytes - filebytes;
318 }
319 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tClient(0x%p): receiving %d bytes\n", me, netbytes); } while
(0)
320 cltsrv_log_file, TEST_LOG_VERBOSE,do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tClient(0x%p): receiving %d bytes\n", me, netbytes); } while
(0)
321 ("\tClient(0x%p): receiving %d bytes\n", me, netbytes))do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tClient(0x%p): receiving %d bytes\n", me, netbytes); } while
(0)
;
322 bytes = PR_Recv(fd, buffer, netbytes, RECV_FLAGS0, timeout);
323 if (-1 == bytes)
324 {
325 if (Aborted(PR_FAILURE))
326 {
327 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tClient(0x%p): receive data aborted\n", me); } while (0)
328 cltsrv_log_file, TEST_LOG_ERROR,do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tClient(0x%p): receive data aborted\n", me); } while (0)
329 ("\tClient(0x%p): receive data aborted\n", me))do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tClient(0x%p): receive data aborted\n", me); } while (0)
;
330 goto aborted;
331 }
332 else if (PR_IO_TIMEOUT_ERROR(-5990L) == PR_GetError())
333 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tClient(0x%p): receive data timeout\n", me); } while (0)
334 cltsrv_log_file, TEST_LOG_ERROR,do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tClient(0x%p): receive data timeout\n", me); } while (0)
335 ("\tClient(0x%p): receive data timeout\n", me))do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tClient(0x%p): receive data timeout\n", me); } while (0)
;
336 else
337 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tClient(0x%p): receive error (%d, %d)\n", me, PR_GetError
(), PR_GetOSError()); } while (0)
338 cltsrv_log_file, TEST_LOG_ERROR,do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tClient(0x%p): receive error (%d, %d)\n", me, PR_GetError
(), PR_GetOSError()); } while (0)
339 ("\tClient(0x%p): receive error (%d, %d)\n",do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tClient(0x%p): receive error (%d, %d)\n", me, PR_GetError
(), PR_GetOSError()); } while (0)
340 me, PR_GetError(), PR_GetOSError()))do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tClient(0x%p): receive error (%d, %d)\n", me, PR_GetError
(), PR_GetOSError()); } while (0)
;
341 goto retry;
342 }
343 if (0 == bytes)
344 {
345 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tClient(0x%p): unexpected end of stream\n", PR_GetCurrentThread
()); } while (0)
346 cltsrv_log_file, TEST_LOG_ERROR,do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tClient(0x%p): unexpected end of stream\n", PR_GetCurrentThread
()); } while (0)
347 ("\t\tClient(0x%p): unexpected end of stream\n",do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tClient(0x%p): unexpected end of stream\n", PR_GetCurrentThread
()); } while (0)
348 PR_GetCurrentThread()))do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tClient(0x%p): unexpected end of stream\n", PR_GetCurrentThread
()); } while (0)
;
349 break;
350 }
351 filebytes += bytes;
352 }
353
354 rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH);
355 if (Aborted(rv)) {
356 goto aborted;
357 }
358 TEST_ASSERT(PR_SUCCESS == rv)((PR_SUCCESS == rv)?((void)0):_MY_Assert("PR_SUCCESS == rv","../../../pr/tests/cltsrv.c"
,358))
;
359retry:
360 (void)PR_Close(fd); fd = NULL((void*)0);
361 TEST_LOG(do { if (debug_mode || (TEST_LOG_INFO <= verbosity)) printf
("\tClient(0x%p): disconnected from server\n", me); } while (
0)
362 cltsrv_log_file, TEST_LOG_INFO,do { if (debug_mode || (TEST_LOG_INFO <= verbosity)) printf
("\tClient(0x%p): disconnected from server\n", me); } while (
0)
363 ("\tClient(0x%p): disconnected from server\n", me))do { if (debug_mode || (TEST_LOG_INFO <= verbosity)) printf
("\tClient(0x%p): disconnected from server\n", me); } while (
0)
;
364
365 PR_Lock(client->ml);
366 client->operations += 1;
367 client->bytesTransferred += 2 * descbytes;
368 rv = PR_WaitCondVar(client->stateChange, rand() % clipping);
369 PR_Unlock(client->ml);
370 if (Aborted(rv)) {
371 break;
372 }
373 }
374
375aborted:
376 client->stopped = PR_IntervalNow();
377
378 PR_ClearInterrupt();
379 if (NULL((void*)0) != fd) {
380 rv = PR_Close(fd);
381 }
382
383 PR_Lock(client->ml);
384 client->state = cs_exit;
385 PR_NotifyCondVar(client->stateChange);
386 PR_Unlock(client->ml);
387 PR_DELETE(descriptor){ PR_Free(descriptor); (descriptor) = ((void*)0); };
388 TEST_LOG(do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("\tClient(0x%p): stopped after %u operations and %u bytes\n"
, PR_GetCurrentThread(), client->operations, client->bytesTransferred
); } while (0)
389 cltsrv_log_file, TEST_LOG_ALWAYS,do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("\tClient(0x%p): stopped after %u operations and %u bytes\n"
, PR_GetCurrentThread(), client->operations, client->bytesTransferred
); } while (0)
390 ("\tClient(0x%p): stopped after %u operations and %u bytes\n",do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("\tClient(0x%p): stopped after %u operations and %u bytes\n"
, PR_GetCurrentThread(), client->operations, client->bytesTransferred
); } while (0)
391 PR_GetCurrentThread(), client->operations, client->bytesTransferred))do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("\tClient(0x%p): stopped after %u operations and %u bytes\n"
, PR_GetCurrentThread(), client->operations, client->bytesTransferred
); } while (0)
;
392
393} /* Client */
394
395static PRStatus ProcessRequest(PRFileDesc *fd, CSServer_t *server)
396{
397 PRStatus drv, rv;
398 char buffer[1024];
399 PRFileDesc *file = NULL((void*)0);
400 PRThread * me = PR_GetCurrentThread();
401 PRInt32 bytes, descbytes, netbytes, filebytes = 0;
402 CSDescriptor_t *descriptor = PR_NEW(CSDescriptor_t)((CSDescriptor_t *) (PR_Malloc((sizeof(CSDescriptor_t)))));
403 PRIntervalTime timeout = PR_MillisecondsToInterval(DEFAULT_SERVER_TIMEOUT4000);
404
405 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tProcessRequest(0x%p): receiving desciptor\n", me); } while
(0)
406 cltsrv_log_file, TEST_LOG_VERBOSE,do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tProcessRequest(0x%p): receiving desciptor\n", me); } while
(0)
407 ("\tProcessRequest(0x%p): receiving desciptor\n", me))do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tProcessRequest(0x%p): receiving desciptor\n", me); } while
(0)
;
408 bytes = PR_Recv(
409 fd, descriptor, sizeof(*descriptor), RECV_FLAGS0, timeout);
410 if (-1 == bytes)
411 {
412 rv = PR_FAILURE;
413 if (Aborted(rv)) {
414 goto exit;
415 }
416 if (PR_IO_TIMEOUT_ERROR(-5990L) == PR_GetError())
417 {
418 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tProcessRequest(0x%p): receive timeout\n", me); } while (
0)
419 cltsrv_log_file, TEST_LOG_ERROR,do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tProcessRequest(0x%p): receive timeout\n", me); } while (
0)
420 ("\tProcessRequest(0x%p): receive timeout\n", me))do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tProcessRequest(0x%p): receive timeout\n", me); } while (
0)
;
421 }
422 goto exit;
423 }
424 if (0 == bytes)
425 {
426 rv = PR_FAILURE;
427 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tProcessRequest(0x%p): unexpected end of file\n", me); } while
(0)
428 cltsrv_log_file, TEST_LOG_ERROR,do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tProcessRequest(0x%p): unexpected end of file\n", me); } while
(0)
429 ("\tProcessRequest(0x%p): unexpected end of file\n", me))do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tProcessRequest(0x%p): unexpected end of file\n", me); } while
(0)
;
430 goto exit;
431 }
432 descbytes = PR_ntohl(descriptor->size);
433 TEST_ASSERT(sizeof(*descriptor) == bytes)((sizeof(*descriptor) == bytes)?((void)0):_MY_Assert("sizeof(*descriptor) == bytes"
,"../../../pr/tests/cltsrv.c",433))
;
434
435 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\t\tProcessRequest(0x%p): read descriptor {%d, %s}\n", me,
descbytes, descriptor->filename); } while (0)
436 cltsrv_log_file, TEST_LOG_VERBOSE,do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\t\tProcessRequest(0x%p): read descriptor {%d, %s}\n", me,
descbytes, descriptor->filename); } while (0)
437 ("\t\tProcessRequest(0x%p): read descriptor {%d, %s}\n",do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\t\tProcessRequest(0x%p): read descriptor {%d, %s}\n", me,
descbytes, descriptor->filename); } while (0)
438 me, descbytes, descriptor->filename))do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\t\tProcessRequest(0x%p): read descriptor {%d, %s}\n", me,
descbytes, descriptor->filename); } while (0)
;
439
440 file = PR_Open(
441 descriptor->filename, (PR_CREATE_FILE0x08 | PR_WRONLY0x02), 0666);
442 if (NULL((void*)0) == file)
443 {
444 rv = PR_FAILURE;
445 if (Aborted(rv)) {
446 goto aborted;
447 }
448 if (PR_IO_TIMEOUT_ERROR(-5990L) == PR_GetError())
449 {
450 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tProcessRequest(0x%p): open file timeout\n", me); } while
(0)
451 cltsrv_log_file, TEST_LOG_ERROR,do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tProcessRequest(0x%p): open file timeout\n", me); } while
(0)
452 ("\tProcessRequest(0x%p): open file timeout\n", me))do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tProcessRequest(0x%p): open file timeout\n", me); } while
(0)
;
453 goto aborted;
454 }
455 }
456 TEST_ASSERT(NULL != file)((((void*)0) != file)?((void)0):_MY_Assert("NULL != file","../../../pr/tests/cltsrv.c"
,456))
;
457
458 filebytes = 0;
459 while (filebytes < descbytes)
460 {
461 netbytes = sizeof(buffer);
462 if ((descbytes - filebytes) < netbytes) {
463 netbytes = descbytes - filebytes;
464 }
465 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tProcessRequest(0x%p): receive %d bytes\n", me, netbytes)
; } while (0)
466 cltsrv_log_file, TEST_LOG_VERBOSE,do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tProcessRequest(0x%p): receive %d bytes\n", me, netbytes)
; } while (0)
467 ("\tProcessRequest(0x%p): receive %d bytes\n", me, netbytes))do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tProcessRequest(0x%p): receive %d bytes\n", me, netbytes)
; } while (0)
;
468 bytes = PR_Recv(fd, buffer, netbytes, RECV_FLAGS0, timeout);
469 if (-1 == bytes)
470 {
471 rv = PR_FAILURE;
472 if (Aborted(rv)) {
473 goto aborted;
474 }
475 if (PR_IO_TIMEOUT_ERROR(-5990L) == PR_GetError())
476 {
477 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): receive data timeout\n", me); } while
(0)
478 cltsrv_log_file, TEST_LOG_ERROR,do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): receive data timeout\n", me); } while
(0)
479 ("\t\tProcessRequest(0x%p): receive data timeout\n", me))do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): receive data timeout\n", me); } while
(0)
;
480 goto aborted;
481 }
482 /*
483 * XXX: I got (PR_CONNECT_RESET_ERROR, ERROR_NETNAME_DELETED)
484 * on NT here. This is equivalent to ECONNRESET on Unix.
485 * -wtc
486 */
487 TEST_LOG(do { if (debug_mode || (TEST_LOG_WARNING <= verbosity)) printf
("\t\tProcessRequest(0x%p): unexpected error (%d, %d)\n", me
, PR_GetError(), PR_GetOSError()); } while (0)
488 cltsrv_log_file, TEST_LOG_WARNING,do { if (debug_mode || (TEST_LOG_WARNING <= verbosity)) printf
("\t\tProcessRequest(0x%p): unexpected error (%d, %d)\n", me
, PR_GetError(), PR_GetOSError()); } while (0)
489 ("\t\tProcessRequest(0x%p): unexpected error (%d, %d)\n",do { if (debug_mode || (TEST_LOG_WARNING <= verbosity)) printf
("\t\tProcessRequest(0x%p): unexpected error (%d, %d)\n", me
, PR_GetError(), PR_GetOSError()); } while (0)
490 me, PR_GetError(), PR_GetOSError()))do { if (debug_mode || (TEST_LOG_WARNING <= verbosity)) printf
("\t\tProcessRequest(0x%p): unexpected error (%d, %d)\n", me
, PR_GetError(), PR_GetOSError()); } while (0)
;
491 goto aborted;
492 }
493 if(0 == bytes)
494 {
495 TEST_LOG(do { if (debug_mode || (TEST_LOG_WARNING <= verbosity)) printf
("\t\tProcessRequest(0x%p): unexpected end of stream\n", me)
; } while (0)
496 cltsrv_log_file, TEST_LOG_WARNING,do { if (debug_mode || (TEST_LOG_WARNING <= verbosity)) printf
("\t\tProcessRequest(0x%p): unexpected end of stream\n", me)
; } while (0)
497 ("\t\tProcessRequest(0x%p): unexpected end of stream\n", me))do { if (debug_mode || (TEST_LOG_WARNING <= verbosity)) printf
("\t\tProcessRequest(0x%p): unexpected end of stream\n", me)
; } while (0)
;
498 rv = PR_FAILURE;
499 goto aborted;
500 }
501 filebytes += bytes;
502 netbytes = bytes;
503 /* The byte count for PR_Write should be positive */
504 MY_ASSERT(netbytes > 0)((netbytes > 0)?((void)0):_MY_Assert("netbytes > 0","../../../pr/tests/cltsrv.c"
,504))
;
505 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tProcessRequest(0x%p): write %d bytes to file\n", me, netbytes
); } while (0)
506 cltsrv_log_file, TEST_LOG_VERBOSE,do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tProcessRequest(0x%p): write %d bytes to file\n", me, netbytes
); } while (0)
507 ("\tProcessRequest(0x%p): write %d bytes to file\n", me, netbytes))do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tProcessRequest(0x%p): write %d bytes to file\n", me, netbytes
); } while (0)
;
508 bytes = PR_Write(file, buffer, netbytes);
509 if (netbytes != bytes)
510 {
511 rv = PR_FAILURE;
512 if (Aborted(rv)) {
513 goto aborted;
514 }
515 if (PR_IO_TIMEOUT_ERROR(-5990L) == PR_GetError())
516 {
517 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): write file timeout\n", me); } while
(0)
518 cltsrv_log_file, TEST_LOG_ERROR,do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): write file timeout\n", me); } while
(0)
519 ("\t\tProcessRequest(0x%p): write file timeout\n", me))do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): write file timeout\n", me); } while
(0)
;
520 goto aborted;
521 }
522 }
523 TEST_ASSERT(bytes > 0)((bytes > 0)?((void)0):_MY_Assert("bytes > 0","../../../pr/tests/cltsrv.c"
,523))
;
524 }
525
526 PR_Lock(server->ml);
527 server->operations += 1;
528 server->bytesTransferred += filebytes;
529 PR_Unlock(server->ml);
530
531 rv = PR_Close(file);
532 if (Aborted(rv)) {
533 goto aborted;
534 }
535 TEST_ASSERT(PR_SUCCESS == rv)((PR_SUCCESS == rv)?((void)0):_MY_Assert("PR_SUCCESS == rv","../../../pr/tests/cltsrv.c"
,535))
;
536 file = NULL((void*)0);
537
538 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\t\tProcessRequest(0x%p): opening %s\n", me, descriptor->
filename); } while (0)
539 cltsrv_log_file, TEST_LOG_VERBOSE,do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\t\tProcessRequest(0x%p): opening %s\n", me, descriptor->
filename); } while (0)
540 ("\t\tProcessRequest(0x%p): opening %s\n", me, descriptor->filename))do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\t\tProcessRequest(0x%p): opening %s\n", me, descriptor->
filename); } while (0)
;
541 file = PR_Open(descriptor->filename, PR_RDONLY0x01, 0);
542 if (NULL((void*)0) == file)
543 {
544 rv = PR_FAILURE;
545 if (Aborted(rv)) {
546 goto aborted;
547 }
548 if (PR_IO_TIMEOUT_ERROR(-5990L) == PR_GetError())
549 {
550 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): open file timeout\n", PR_GetCurrentThread
()); } while (0)
551 cltsrv_log_file, TEST_LOG_ERROR,do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): open file timeout\n", PR_GetCurrentThread
()); } while (0)
552 ("\t\tProcessRequest(0x%p): open file timeout\n",do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): open file timeout\n", PR_GetCurrentThread
()); } while (0)
553 PR_GetCurrentThread()))do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): open file timeout\n", PR_GetCurrentThread
()); } while (0)
;
554 goto aborted;
555 }
556 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): other file open error (%u, %u)\n"
, me, PR_GetError(), PR_GetOSError()); } while (0)
557 cltsrv_log_file, TEST_LOG_ERROR,do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): other file open error (%u, %u)\n"
, me, PR_GetError(), PR_GetOSError()); } while (0)
558 ("\t\tProcessRequest(0x%p): other file open error (%u, %u)\n",do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): other file open error (%u, %u)\n"
, me, PR_GetError(), PR_GetOSError()); } while (0)
559 me, PR_GetError(), PR_GetOSError()))do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): other file open error (%u, %u)\n"
, me, PR_GetError(), PR_GetOSError()); } while (0)
;
560 goto aborted;
561 }
562 TEST_ASSERT(NULL != file)((((void*)0) != file)?((void)0):_MY_Assert("NULL != file","../../../pr/tests/cltsrv.c"
,562))
;
563
564 netbytes = 0;
565 while (netbytes < descbytes)
566 {
567 filebytes = sizeof(buffer);
568 if ((descbytes - netbytes) < filebytes) {
569 filebytes = descbytes - netbytes;
570 }
571 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tProcessRequest(0x%p): read %d bytes from file\n", me, filebytes
); } while (0)
572 cltsrv_log_file, TEST_LOG_VERBOSE,do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tProcessRequest(0x%p): read %d bytes from file\n", me, filebytes
); } while (0)
573 ("\tProcessRequest(0x%p): read %d bytes from file\n", me, filebytes))do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tProcessRequest(0x%p): read %d bytes from file\n", me, filebytes
); } while (0)
;
574 bytes = PR_Read(file, buffer, filebytes);
575 if (filebytes != bytes)
576 {
577 rv = PR_FAILURE;
578 if (Aborted(rv)) {
579 goto aborted;
580 }
581 if (PR_IO_TIMEOUT_ERROR(-5990L) == PR_GetError())
582 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): read file timeout\n", me); } while
(0)
583 cltsrv_log_file, TEST_LOG_ERROR,do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): read file timeout\n", me); } while
(0)
584 ("\t\tProcessRequest(0x%p): read file timeout\n", me))do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): read file timeout\n", me); } while
(0)
;
585 else
586 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): other file error (%d, %d)\n", me
, PR_GetError(), PR_GetOSError()); } while (0)
587 cltsrv_log_file, TEST_LOG_ERROR,do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): other file error (%d, %d)\n", me
, PR_GetError(), PR_GetOSError()); } while (0)
588 ("\t\tProcessRequest(0x%p): other file error (%d, %d)\n",do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): other file error (%d, %d)\n", me
, PR_GetError(), PR_GetOSError()); } while (0)
589 me, PR_GetError(), PR_GetOSError()))do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): other file error (%d, %d)\n", me
, PR_GetError(), PR_GetOSError()); } while (0)
;
590 goto aborted;
591 }
592 TEST_ASSERT(bytes > 0)((bytes > 0)?((void)0):_MY_Assert("bytes > 0","../../../pr/tests/cltsrv.c"
,592))
;
593 netbytes += bytes;
594 filebytes = bytes;
595 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\t\tProcessRequest(0x%p): sending %d bytes\n", me, filebytes
); } while (0)
596 cltsrv_log_file, TEST_LOG_VERBOSE,do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\t\tProcessRequest(0x%p): sending %d bytes\n", me, filebytes
); } while (0)
597 ("\t\tProcessRequest(0x%p): sending %d bytes\n", me, filebytes))do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\t\tProcessRequest(0x%p): sending %d bytes\n", me, filebytes
); } while (0)
;
598 bytes = PR_Send(fd, buffer, filebytes, SEND_FLAGS0, timeout);
599 if (filebytes != bytes)
600 {
601 rv = PR_FAILURE;
602 if (Aborted(rv)) {
603 goto aborted;
604 }
605 if (PR_IO_TIMEOUT_ERROR(-5990L) == PR_GetError())
606 {
607 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): send data timeout\n", me); } while
(0)
608 cltsrv_log_file, TEST_LOG_ERROR,do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): send data timeout\n", me); } while
(0)
609 ("\t\tProcessRequest(0x%p): send data timeout\n", me))do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): send data timeout\n", me); } while
(0)
;
610 goto aborted;
611 }
612 break;
613 }
614 TEST_ASSERT(bytes > 0)((bytes > 0)?((void)0):_MY_Assert("bytes > 0","../../../pr/tests/cltsrv.c"
,614))
;
615 }
616
617 PR_Lock(server->ml);
618 server->bytesTransferred += filebytes;
619 PR_Unlock(server->ml);
620
621 rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH);
622 if (Aborted(rv)) {
623 goto aborted;
624 }
625
626 rv = PR_Close(file);
627 if (Aborted(rv)) {
628 goto aborted;
629 }
630 TEST_ASSERT(PR_SUCCESS == rv)((PR_SUCCESS == rv)?((void)0):_MY_Assert("PR_SUCCESS == rv","../../../pr/tests/cltsrv.c"
,630))
;
631 file = NULL((void*)0);
632
633aborted:
634 PR_ClearInterrupt();
635 if (NULL((void*)0) != file) {
636 PR_Close(file);
637 }
638 drv = PR_Delete(descriptor->filename);
639 TEST_ASSERT(PR_SUCCESS == drv)((PR_SUCCESS == drv)?((void)0):_MY_Assert("PR_SUCCESS == drv"
,"../../../pr/tests/cltsrv.c",639))
;
640exit:
641 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\t\tProcessRequest(0x%p): Finished\n", me); } while (0)
642 cltsrv_log_file, TEST_LOG_VERBOSE,do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\t\tProcessRequest(0x%p): Finished\n", me); } while (0)
643 ("\t\tProcessRequest(0x%p): Finished\n", me))do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\t\tProcessRequest(0x%p): Finished\n", me); } while (0)
;
644
645 PR_DELETE(descriptor){ PR_Free(descriptor); (descriptor) = ((void*)0); };
646
647#if defined(WIN95)
648 PR_Sleep(PR_MillisecondsToInterval(200)); /* lth. see note [1] */
649#endif
650 return rv;
651} /* ProcessRequest */
652
653static PRStatus CreateWorker(CSServer_t *server, CSPool_t *pool)
654{
655 CSWorker_t *worker = PR_NEWZAP(CSWorker_t)((CSWorker_t*)PR_Calloc(1, sizeof(CSWorker_t)));
656 worker->server = server;
657 PR_INIT_CLIST(&worker->element)do { (&worker->element)->next = (&worker->element
); (&worker->element)->prev = (&worker->element
); } while (0)
;
658 worker->thread = PR_CreateThread(
659 PR_USER_THREAD, Worker, worker,
660 DEFAULT_SERVER_PRIORITYPR_PRIORITY_HIGH, thread_scope,
661 PR_UNJOINABLE_THREAD, 0);
662 if (NULL((void*)0) == worker->thread)
663 {
664 PR_DELETE(worker){ PR_Free(worker); (worker) = ((void*)0); };
665 return PR_FAILURE;
666 }
667
668 TEST_LOG(cltsrv_log_file, TEST_LOG_STATUS,do { if (debug_mode || (TEST_LOG_STATUS <= verbosity)) printf
("\tCreateWorker(0x%p): create new worker (0x%p)\n", PR_GetCurrentThread
(), worker->thread); } while (0)
669 ("\tCreateWorker(0x%p): create new worker (0x%p)\n",do { if (debug_mode || (TEST_LOG_STATUS <= verbosity)) printf
("\tCreateWorker(0x%p): create new worker (0x%p)\n", PR_GetCurrentThread
(), worker->thread); } while (0)
670 PR_GetCurrentThread(), worker->thread))do { if (debug_mode || (TEST_LOG_STATUS <= verbosity)) printf
("\tCreateWorker(0x%p): create new worker (0x%p)\n", PR_GetCurrentThread
(), worker->thread); } while (0)
;
671
672 return PR_SUCCESS;
673} /* CreateWorker */
674
675static void PR_CALLBACK Worker(void *arg)
676{
677 PRStatus rv;
678 PRNetAddr from;
679 PRFileDesc *fd = NULL((void*)0);
680 PRThread *me = PR_GetCurrentThread();
681 CSWorker_t *worker = (CSWorker_t*)arg;
682 CSServer_t *server = worker->server;
683 CSPool_t *pool = &server->pool;
684
685 TEST_LOG(do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("\t\tWorker(0x%p): started [%u]\n", me, pool->workers + 1
); } while (0)
686 cltsrv_log_file, TEST_LOG_NOTICE,do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("\t\tWorker(0x%p): started [%u]\n", me, pool->workers + 1
); } while (0)
687 ("\t\tWorker(0x%p): started [%u]\n", me, pool->workers + 1))do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("\t\tWorker(0x%p): started [%u]\n", me, pool->workers + 1
); } while (0)
;
688
689 PR_Lock(server->ml);
690 PR_APPEND_LINK(&worker->element, &server->list)do { (&worker->element)->next = (&server->list
); (&worker->element)->prev = (&server->list
)->prev; (&server->list)->prev->next = (&
worker->element); (&server->list)->prev = (&
worker->element); } while (0)
;
691 pool->workers += 1; /* define our existance */
692
693 while (cs_run == server->state)
694 {
695 while (pool->accepting >= server->workers.accepting)
696 {
697 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\t\tWorker(0x%p): waiting for accept slot[%d]\n", me, pool
->accepting); } while (0)
698 cltsrv_log_file, TEST_LOG_VERBOSE,do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\t\tWorker(0x%p): waiting for accept slot[%d]\n", me, pool
->accepting); } while (0)
699 ("\t\tWorker(0x%p): waiting for accept slot[%d]\n",do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\t\tWorker(0x%p): waiting for accept slot[%d]\n", me, pool
->accepting); } while (0)
700 me, pool->accepting))do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\t\tWorker(0x%p): waiting for accept slot[%d]\n", me, pool
->accepting); } while (0)
;
701 rv = PR_WaitCondVar(pool->acceptComplete, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
702 if (Aborted(rv) || (cs_run != server->state))
703 {
704 TEST_LOG(do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("\tWorker(0x%p): has been %s\n", me, (Aborted(rv) ? "interrupted"
: "stopped")); } while (0)
705 cltsrv_log_file, TEST_LOG_NOTICE,do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("\tWorker(0x%p): has been %s\n", me, (Aborted(rv) ? "interrupted"
: "stopped")); } while (0)
706 ("\tWorker(0x%p): has been %s\n",do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("\tWorker(0x%p): has been %s\n", me, (Aborted(rv) ? "interrupted"
: "stopped")); } while (0)
707 me, (Aborted(rv) ? "interrupted" : "stopped")))do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("\tWorker(0x%p): has been %s\n", me, (Aborted(rv) ? "interrupted"
: "stopped")); } while (0)
;
708 goto exit;
709 }
710 }
711 pool->accepting += 1; /* how many are really in accept */
712 PR_Unlock(server->ml);
713
714 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\t\tWorker(0x%p): calling accept\n", me); } while (0)
715 cltsrv_log_file, TEST_LOG_VERBOSE,do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\t\tWorker(0x%p): calling accept\n", me); } while (0)
716 ("\t\tWorker(0x%p): calling accept\n", me))do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\t\tWorker(0x%p): calling accept\n", me); } while (0)
;
717 fd = PR_Accept(server->listener, &from, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
718
719 PR_Lock(server->ml);
720 pool->accepting -= 1;
721 PR_NotifyCondVar(pool->acceptComplete);
722
723 if ((NULL((void*)0) == fd) && Aborted(PR_FAILURE))
724 {
725 if (NULL((void*)0) != server->listener)
726 {
727 PR_Close(server->listener);
728 server->listener = NULL((void*)0);
729 }
730 goto exit;
731 }
732
733 if (NULL((void*)0) != fd)
734 {
735 /*
736 ** Create another worker of the total number of workers is
737 ** less than the minimum specified or we have none left in
738 ** accept() AND we're not over the maximum.
739 ** This sort of presumes that the number allowed in accept
740 ** is at least as many as the minimum. Otherwise we'll keep
741 ** creating new threads and deleting them soon after.
742 */
743 PRBool another =
744 ((pool->workers < server->workers.minimum) ||
745 ((0 == pool->accepting)
746 && (pool->workers < server->workers.maximum))) ?
747 PR_TRUE1 : PR_FALSE0;
748 pool->active += 1;
749 PR_Unlock(server->ml);
750
751 if (another) {
752 (void)CreateWorker(server, pool);
753 }
754
755 rv = ProcessRequest(fd, server);
756 if (PR_SUCCESS != rv)
757 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tWorker(0x%p): server process ended abnormally\n", me);
} while (0)
758 cltsrv_log_file, TEST_LOG_ERROR,do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tWorker(0x%p): server process ended abnormally\n", me);
} while (0)
759 ("\t\tWorker(0x%p): server process ended abnormally\n", me))do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tWorker(0x%p): server process ended abnormally\n", me);
} while (0)
;
760 (void)PR_Close(fd); fd = NULL((void*)0);
761
762 PR_Lock(server->ml);
763 pool->active -= 1;
764 }
765 }
766
767exit:
768 PR_ClearInterrupt();
769 PR_Unlock(server->ml);
770
771 if (NULL((void*)0) != fd)
772 {
773 (void)PR_Shutdown(fd, PR_SHUTDOWN_BOTH);
774 (void)PR_Close(fd);
775 }
776
777 TEST_LOG(do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("\t\tWorker(0x%p): exiting [%u]\n", PR_GetCurrentThread(), pool
->workers); } while (0)
778 cltsrv_log_file, TEST_LOG_NOTICE,do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("\t\tWorker(0x%p): exiting [%u]\n", PR_GetCurrentThread(), pool
->workers); } while (0)
779 ("\t\tWorker(0x%p): exiting [%u]\n", PR_GetCurrentThread(), pool->workers))do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("\t\tWorker(0x%p): exiting [%u]\n", PR_GetCurrentThread(), pool
->workers); } while (0)
;
780
781 PR_Lock(server->ml);
782 pool->workers -= 1; /* undefine our existance */
783 PR_REMOVE_AND_INIT_LINK(&worker->element)do { (&worker->element)->prev->next = (&worker
->element)->next; (&worker->element)->next->
prev = (&worker->element)->prev; (&worker->element
)->next = (&worker->element); (&worker->element
)->prev = (&worker->element); } while (0)
;
784 PR_NotifyCondVar(pool->exiting);
785 PR_Unlock(server->ml);
786
787 PR_DELETE(worker){ PR_Free(worker); (worker) = ((void*)0); }; /* destruction of the "worker" object */
788
789} /* Worker */
790
791static void PR_CALLBACK Server(void *arg)
792{
793 PRStatus rv;
794 PRNetAddr serverAddress;
795 PRThread *me = PR_GetCurrentThread();
796 CSServer_t *server = (CSServer_t*)arg;
797 PRSocketOptionData sockOpt;
798
799 server->listener = PR_Socket(domain, SOCK_STREAMSOCK_STREAM, protocol);
800
801 sockOpt.option = PR_SockOpt_Reuseaddr;
802 sockOpt.value.reuse_addr = PR_TRUE1;
803 rv = PR_SetSocketOption(server->listener, &sockOpt);
804 TEST_ASSERT(PR_SUCCESS == rv)((PR_SUCCESS == rv)?((void)0):_MY_Assert("PR_SUCCESS == rv","../../../pr/tests/cltsrv.c"
,804))
;
805
806 memset(&serverAddress, 0, sizeof(serverAddress));
807 if (PR_AF_INET610 != domain) {
808 TEST_LOG(cltsrv_log_file, TEST_LOG_ALWAYS,do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("server binding to ip port %s\n", 12849 +100 +200); } while
(0)
809 ("server binding to ip port %s\n", DEFAULT_PORT))do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("server binding to ip port %s\n", 12849 +100 +200); } while
(0)
;
810 rv = PR_InitializeNetAddr(PR_IpAddrAny, DEFAULT_PORT12849 +100 +200, &serverAddress);
811 }
812 else {
813 TEST_LOG(cltsrv_log_file, TEST_LOG_ALWAYS,do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("server binding to ipv6 port %s\n", 12849 +100 +200); } while
(0)
814 ("server binding to ipv6 port %s\n", DEFAULT_PORT))do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("server binding to ipv6 port %s\n", 12849 +100 +200); } while
(0)
;
815 rv = PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET610, DEFAULT_PORT12849 +100 +200,
816 &serverAddress);
817 }
818 rv = PR_Bind(server->listener, &serverAddress);
819 TEST_ASSERT(PR_SUCCESS == rv)((PR_SUCCESS == rv)?((void)0):_MY_Assert("PR_SUCCESS == rv","../../../pr/tests/cltsrv.c"
,819))
;
820
821 rv = PR_Listen(server->listener, server->backlog);
822 TEST_ASSERT(PR_SUCCESS == rv)((PR_SUCCESS == rv)?((void)0):_MY_Assert("PR_SUCCESS == rv","../../../pr/tests/cltsrv.c"
,822))
;
823
824 server->started = PR_IntervalNow();
825 TimeOfDayMessage("Server started at", me);
826
827 PR_Lock(server->ml);
828 server->state = cs_run;
829 PR_NotifyCondVar(server->stateChange);
830 PR_Unlock(server->ml);
831
832 /*
833 ** Create the first worker (actually, a thread that accepts
834 ** connections and then processes the work load as needed).
835 ** From this point on, additional worker threads are created
836 ** as they are needed by existing worker threads.
837 */
838 rv = CreateWorker(server, &server->pool);
839 TEST_ASSERT(PR_SUCCESS == rv)((PR_SUCCESS == rv)?((void)0):_MY_Assert("PR_SUCCESS == rv","../../../pr/tests/cltsrv.c"
,839))
;
840
841 /*
842 ** From here on this thread is merely hanging around as the contact
843 ** point for the main test driver. It's just waiting for the driver
844 ** to declare the test complete.
845 */
846 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tServer(0x%p): waiting for state change\n", me); } while (
0)
847 cltsrv_log_file, TEST_LOG_VERBOSE,do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tServer(0x%p): waiting for state change\n", me); } while (
0)
848 ("\tServer(0x%p): waiting for state change\n", me))do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tServer(0x%p): waiting for state change\n", me); } while (
0)
;
849
850 PR_Lock(server->ml);
851 while ((cs_run == server->state) && !Aborted(rv))
852 {
853 rv = PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
854 }
855 PR_Unlock(server->ml);
856 PR_ClearInterrupt();
857
858 TEST_LOG(do { if (debug_mode || (TEST_LOG_INFO <= verbosity)) printf
("\tServer(0x%p): shutting down workers\n", me); } while (0)
859 cltsrv_log_file, TEST_LOG_INFO,do { if (debug_mode || (TEST_LOG_INFO <= verbosity)) printf
("\tServer(0x%p): shutting down workers\n", me); } while (0)
860 ("\tServer(0x%p): shutting down workers\n", me))do { if (debug_mode || (TEST_LOG_INFO <= verbosity)) printf
("\tServer(0x%p): shutting down workers\n", me); } while (0)
;
861
862 /*
863 ** Get all the worker threads to exit. They know how to
864 ** clean up after themselves, so this is just a matter of
865 ** waiting for clorine in the pool to take effect. During
866 ** this stage we're ignoring interrupts.
867 */
868 server->workers.minimum = server->workers.maximum = 0;
869
870 PR_Lock(server->ml);
871 while (!PR_CLIST_IS_EMPTY(&server->list)((&server->list)->next == (&server->list)))
872 {
873 PRCList *head = PR_LIST_HEAD(&server->list)(&server->list)->next;
874 CSWorker_t *worker = (CSWorker_t*)head;
875 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tServer(0x%p): interrupting worker(0x%p)\n", me, worker);
} while (0)
876 cltsrv_log_file, TEST_LOG_VERBOSE,do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tServer(0x%p): interrupting worker(0x%p)\n", me, worker);
} while (0)
877 ("\tServer(0x%p): interrupting worker(0x%p)\n", me, worker))do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tServer(0x%p): interrupting worker(0x%p)\n", me, worker);
} while (0)
;
878 rv = PR_Interrupt(worker->thread);
879 TEST_ASSERT(PR_SUCCESS == rv)((PR_SUCCESS == rv)?((void)0):_MY_Assert("PR_SUCCESS == rv","../../../pr/tests/cltsrv.c"
,879))
;
880 PR_REMOVE_AND_INIT_LINK(head)do { (head)->prev->next = (head)->next; (head)->next
->prev = (head)->prev; (head)->next = (head); (head)
->prev = (head); } while (0)
;
881 }
882
883 while (server->pool.workers > 0)
884 {
885 TEST_LOG(do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("\tServer(0x%p): waiting for %u workers to exit\n", me, server
->pool.workers); } while (0)
886 cltsrv_log_file, TEST_LOG_NOTICE,do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("\tServer(0x%p): waiting for %u workers to exit\n", me, server
->pool.workers); } while (0)
887 ("\tServer(0x%p): waiting for %u workers to exit\n",do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("\tServer(0x%p): waiting for %u workers to exit\n", me, server
->pool.workers); } while (0)
888 me, server->pool.workers))do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("\tServer(0x%p): waiting for %u workers to exit\n", me, server
->pool.workers); } while (0)
;
889 (void)PR_WaitCondVar(server->pool.exiting, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
890 }
891
892 server->state = cs_exit;
893 PR_NotifyCondVar(server->stateChange);
894 PR_Unlock(server->ml);
895
896 TEST_LOG(do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("\tServer(0x%p): stopped after %u operations and %u bytes\n"
, me, server->operations, server->bytesTransferred); } while
(0)
897 cltsrv_log_file, TEST_LOG_ALWAYS,do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("\tServer(0x%p): stopped after %u operations and %u bytes\n"
, me, server->operations, server->bytesTransferred); } while
(0)
898 ("\tServer(0x%p): stopped after %u operations and %u bytes\n",do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("\tServer(0x%p): stopped after %u operations and %u bytes\n"
, me, server->operations, server->bytesTransferred); } while
(0)
899 me, server->operations, server->bytesTransferred))do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("\tServer(0x%p): stopped after %u operations and %u bytes\n"
, me, server->operations, server->bytesTransferred); } while
(0)
;
900
901 if (NULL((void*)0) != server->listener) {
902 PR_Close(server->listener);
903 }
904 server->stopped = PR_IntervalNow();
905
906} /* Server */
907
908static void WaitForCompletion(PRIntn execution)
909{
910 while (execution > 0)
911 {
912 PRIntn dally = (execution > 30) ? 30 : execution;
913 PR_Sleep(PR_SecondsToInterval(dally));
914 if (pthread_stats) {
915 PT_FPrintStats(debug_out, "\nPThread Statistics\n");
916 }
917 execution -= dally;
918 }
919} /* WaitForCompletion */
920
921static void Help(void)
922{
923 PR_fprintf(debug_out, "cltsrv test program usage:\n");
924 PR_fprintf(debug_out, "\t-a <n> threads allowed in accept (5)\n");
925 PR_fprintf(debug_out, "\t-b <n> backlock for listen (5)\n");
926 PR_fprintf(debug_out, "\t-c <threads> number of clients to create (1)\n");
927 PR_fprintf(debug_out, "\t-f <low> low water mark for fd caching (0)\n");
928 PR_fprintf(debug_out, "\t-F <high> high water mark for fd caching (0)\n");
929 PR_fprintf(debug_out, "\t-w <threads> minimal number of server threads (1)\n");
930 PR_fprintf(debug_out, "\t-W <threads> maximum number of server threads (1)\n");
931 PR_fprintf(debug_out, "\t-e <seconds> duration of the test in seconds (10)\n");
932 PR_fprintf(debug_out, "\t-s <string> dsn name of server (localhost)\n");
933 PR_fprintf(debug_out, "\t-G use GLOBAL threads (LOCAL)\n");
934 PR_fprintf(debug_out, "\t-X use XTP as transport (TCP)\n");
935 PR_fprintf(debug_out, "\t-6 Use IPv6 (IPv4)\n");
936 PR_fprintf(debug_out, "\t-v verbosity (accumulative) (0)\n");
937 PR_fprintf(debug_out, "\t-p pthread statistics (FALSE)\n");
938 PR_fprintf(debug_out, "\t-d debug mode (FALSE)\n");
939 PR_fprintf(debug_out, "\t-h this message\n");
940} /* Help */
941
942static Verbosity IncrementVerbosity(void)
943{
944 PRIntn verboge = (PRIntn)verbosity + 1;
945 return (Verbosity)verboge;
946} /* IncrementVerbosity */
947
948int main(int argc, char** argv)
949{
950 PRUintn index;
951 PRBool boolean;
952 CSClient_t *client;
953 PRStatus rv, joinStatus;
954 CSServer_t *server = NULL((void*)0);
955
956 PRUintn backlog = DEFAULT_BACKLOG5;
957 PRUintn clients = DEFAULT_CLIENTS1;
958 const char *serverName = DEFAULT_SERVER"localhost";
959 PRBool serverIsLocal = PR_TRUE1;
960 PRUintn accepting = ALLOWED_IN_ACCEPT1;
961 PRUintn workersMin = DEFAULT_WORKERS_MIN1;
962 PRUintn workersMax = DEFAULT_WORKERS_MAX1;
963 PRIntn execution = DEFAULT_EXECUTION_TIME10;
964 PRIntn low = DEFAULT_LOW0, high = DEFAULT_HIGH0;
965
966 /*
967 * -G use global threads
968 * -a <n> threads allowed in accept
969 * -b <n> backlock for listen
970 * -c <threads> number of clients to create
971 * -f <low> low water mark for caching FDs
972 * -F <high> high water mark for caching FDs
973 * -w <threads> minimal number of server threads
974 * -W <threads> maximum number of server threads
975 * -e <seconds> duration of the test in seconds
976 * -s <string> dsn name of server (implies no server here)
977 * -v verbosity
978 */
979
980 PLOptStatus os;
981 PLOptState *opt = PL_CreateOptState(argc, argv, "GX6b:a:c:f:F:w:W:e:s:vdhp");
982
983 debug_out = PR_GetSpecialFD(PR_StandardError);
984
985 while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
986 {
987 if (PL_OPT_BAD == os) {
988 continue;
989 }
990 switch (opt->option)
991 {
992 case 'G': /* use global threads */
993 thread_scope = PR_GLOBAL_THREAD;
994 break;
995 case 'X': /* use XTP as transport */
996 protocol = 36;
997 break;
998 case '6': /* Use IPv6 */
999 domain = PR_AF_INET610;
1000 break;
1001 case 'a': /* the value for accepting */
1002 accepting = atoi(opt->value);
1003 break;
1004 case 'b': /* the value for backlock */
1005 backlog = atoi(opt->value);
1006 break;
1007 case 'c': /* number of client threads */
1008 clients = atoi(opt->value);
1009 break;
1010 case 'f': /* low water fd cache */
1011 low = atoi(opt->value);
1012 break;
1013 case 'F': /* low water fd cache */
1014 high = atoi(opt->value);
1015 break;
1016 case 'w': /* minimum server worker threads */
1017 workersMin = atoi(opt->value);
1018 break;
1019 case 'W': /* maximum server worker threads */
1020 workersMax = atoi(opt->value);
1021 break;
1022 case 'e': /* program execution time in seconds */
1023 execution = atoi(opt->value);
1024 break;
1025 case 's': /* server's address */
1026 serverName = opt->value;
1027 break;
1028 case 'v': /* verbosity */
1029 verbosity = IncrementVerbosity();
1030 break;
1031 case 'd': /* debug mode */
1032 debug_mode = PR_TRUE1;
1033 break;
1034 case 'p': /* pthread mode */
1035 pthread_stats = PR_TRUE1;
1036 break;
1037 case 'h':
1038 default:
1039 Help();
1040 return 2;
1041 }
1042 }
1043 PL_DestroyOptState(opt);
1044
1045 if (0 != PL_strcmp(serverName, DEFAULT_SERVER"localhost")) {
1046 serverIsLocal = PR_FALSE0;
1047 }
1048 if (0 == execution) {
1049 execution = DEFAULT_EXECUTION_TIME10;
1050 }
1051 if (0 == workersMax) {
1052 workersMax = DEFAULT_WORKERS_MAX1;
1053 }
1054 if (0 == workersMin) {
1055 workersMin = DEFAULT_WORKERS_MIN1;
1056 }
1057 if (0 == accepting) {
1058 accepting = ALLOWED_IN_ACCEPT1;
1059 }
1060 if (0 == backlog) {
1061 backlog = DEFAULT_BACKLOG5;
1062 }
1063
1064 if (workersMin > accepting) {
1065 accepting = workersMin;
1066 }
1067
1068 PR_STDIO_INIT();
1069 TimeOfDayMessage("Client/Server started at", PR_GetCurrentThread());
1070
1071 cltsrv_log_file = PR_NewLogModule("cltsrv_log");
1072 MY_ASSERT(NULL != cltsrv_log_file)((((void*)0) != cltsrv_log_file)?((void)0):_MY_Assert("NULL != cltsrv_log_file"
,"../../../pr/tests/cltsrv.c",1072))
;
1073 boolean = PR_SetLogFile("cltsrv.log");
1074 MY_ASSERT(boolean)((boolean)?((void)0):_MY_Assert("boolean","../../../pr/tests/cltsrv.c"
,1074))
;
1075
1076 rv = PR_SetFDCacheSize(low, high);
1077 PR_ASSERT(PR_SUCCESS == rv)((PR_SUCCESS == rv)?((void)0):PR_Assert("PR_SUCCESS == rv","../../../pr/tests/cltsrv.c"
,1077))
;
1078
1079 if (serverIsLocal)
1080 {
1081 /* Establish the server */
1082 TEST_LOG(do { if (debug_mode || (TEST_LOG_INFO <= verbosity)) printf
("main(0x%p): starting server\n", PR_GetCurrentThread()); } while
(0)
1083 cltsrv_log_file, TEST_LOG_INFO,do { if (debug_mode || (TEST_LOG_INFO <= verbosity)) printf
("main(0x%p): starting server\n", PR_GetCurrentThread()); } while
(0)
1084 ("main(0x%p): starting server\n", PR_GetCurrentThread()))do { if (debug_mode || (TEST_LOG_INFO <= verbosity)) printf
("main(0x%p): starting server\n", PR_GetCurrentThread()); } while
(0)
;
1085
1086 server = PR_NEWZAP(CSServer_t)((CSServer_t*)PR_Calloc(1, sizeof(CSServer_t)));
1087 PR_INIT_CLIST(&server->list)do { (&server->list)->next = (&server->list)
; (&server->list)->prev = (&server->list); }
while (0)
;
1088 server->state = cs_init;
1089 server->ml = PR_NewLock();
1090 server->backlog = backlog;
1091 server->port = DEFAULT_PORT12849 +100 +200;
1092 server->workers.minimum = workersMin;
1093 server->workers.maximum = workersMax;
1094 server->workers.accepting = accepting;
1095 server->stateChange = PR_NewCondVar(server->ml);
1096 server->pool.exiting = PR_NewCondVar(server->ml);
1097 server->pool.acceptComplete = PR_NewCondVar(server->ml);
1098
1099 TEST_LOG(do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("main(0x%p): creating server thread\n", PR_GetCurrentThread
()); } while (0)
1100 cltsrv_log_file, TEST_LOG_NOTICE,do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("main(0x%p): creating server thread\n", PR_GetCurrentThread
()); } while (0)
1101 ("main(0x%p): creating server thread\n", PR_GetCurrentThread()))do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("main(0x%p): creating server thread\n", PR_GetCurrentThread
()); } while (0)
;
1102
1103 server->thread = PR_CreateThread(
1104 PR_USER_THREAD, Server, server, PR_PRIORITY_HIGH,
1105 thread_scope, PR_JOINABLE_THREAD, 0);
1106 TEST_ASSERT(NULL != server->thread)((((void*)0) != server->thread)?((void)0):_MY_Assert("NULL != server->thread"
,"../../../pr/tests/cltsrv.c",1106))
;
1107
1108 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("main(0x%p): waiting for server init\n", PR_GetCurrentThread
()); } while (0)
1109 cltsrv_log_file, TEST_LOG_VERBOSE,do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("main(0x%p): waiting for server init\n", PR_GetCurrentThread
()); } while (0)
1110 ("main(0x%p): waiting for server init\n", PR_GetCurrentThread()))do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("main(0x%p): waiting for server init\n", PR_GetCurrentThread
()); } while (0)
;
1111
1112 PR_Lock(server->ml);
1113 while (server->state == cs_init) {
1114 PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
1115 }
1116 PR_Unlock(server->ml);
1117
1118 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("main(0x%p): server init complete (port #%d)\n", PR_GetCurrentThread
(), server->port); } while (0)
1119 cltsrv_log_file, TEST_LOG_VERBOSE,do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("main(0x%p): server init complete (port #%d)\n", PR_GetCurrentThread
(), server->port); } while (0)
1120 ("main(0x%p): server init complete (port #%d)\n",do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("main(0x%p): server init complete (port #%d)\n", PR_GetCurrentThread
(), server->port); } while (0)
1121 PR_GetCurrentThread(), server->port))do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("main(0x%p): server init complete (port #%d)\n", PR_GetCurrentThread
(), server->port); } while (0)
;
1122 }
1123
1124 if (clients != 0)
1125 {
1126 /* Create all of the clients */
1127 PRHostEnt host;
1128 char buffer[BUFFER_SIZE1024];
1129 client = (CSClient_t*)PR_CALLOC(clients * sizeof(CSClient_t))(PR_Calloc(1, (clients * sizeof(CSClient_t))));
1130
1131 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("main(0x%p): creating %d client threads\n", PR_GetCurrentThread
(), clients); } while (0)
1132 cltsrv_log_file, TEST_LOG_VERBOSE,do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("main(0x%p): creating %d client threads\n", PR_GetCurrentThread
(), clients); } while (0)
1133 ("main(0x%p): creating %d client threads\n",do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("main(0x%p): creating %d client threads\n", PR_GetCurrentThread
(), clients); } while (0)
1134 PR_GetCurrentThread(), clients))do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("main(0x%p): creating %d client threads\n", PR_GetCurrentThread
(), clients); } while (0)
;
1135
1136 if (!serverIsLocal)
1137 {
1138 rv = PR_GetHostByName(serverName, buffer, BUFFER_SIZE1024, &host);
1139 if (PR_SUCCESS != rv)
1140 {
1141 PL_FPrintError(PR_STDERRPR_GetSpecialFD(PR_StandardError), "PR_GetHostByName");
1142 return 2;
1143 }
1144 }
1145
1146 for (index = 0; index < clients; ++index)
1147 {
1148 client[index].state = cs_init;
1149 client[index].ml = PR_NewLock();
1150 if (serverIsLocal)
1151 {
1152 if (PR_AF_INET610 != domain) {
1153 TEST_LOG(cltsrv_log_file, TEST_LOG_ALWAYS,do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("loopback client ip port %s\n", 12849 +100 +200); } while (
0)
1154 ("loopback client ip port %s\n", DEFAULT_PORT))do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("loopback client ip port %s\n", 12849 +100 +200); } while (
0)
;
1155 (void)PR_InitializeNetAddr(
1156 PR_IpAddrLoopback, DEFAULT_PORT12849 +100 +200,
1157 &client[index].serverAddress);
1158 }
1159 else {
1160 TEST_LOG(cltsrv_log_file, TEST_LOG_ALWAYS,do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("loopback client ipv6 port %s\n", 12849 +100 +200); } while
(0)
1161 ("loopback client ipv6 port %s\n", DEFAULT_PORT))do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("loopback client ipv6 port %s\n", 12849 +100 +200); } while
(0)
;
1162 rv = PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET610,
Value stored to 'rv' is never read
1163 DEFAULT_PORT12849 +100 +200, &client[index].serverAddress);
1164 }
1165 }
1166 else
1167 {
1168 TEST_LOG(cltsrv_log_file, TEST_LOG_ALWAYS,do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("client enumerate port %s\n", 12849 +100 +200); } while (0)
1169 ("client enumerate port %s\n", DEFAULT_PORT))do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("client enumerate port %s\n", 12849 +100 +200); } while (0)
;
1170 (void)PR_EnumerateHostEnt(
1171 0, &host, DEFAULT_PORT12849 +100 +200, &client[index].serverAddress);
1172 }
1173 client[index].stateChange = PR_NewCondVar(client[index].ml);
1174 TEST_LOG(do { if (debug_mode || (TEST_LOG_INFO <= verbosity)) printf
("main(0x%p): creating client threads\n", PR_GetCurrentThread
()); } while (0)
1175 cltsrv_log_file, TEST_LOG_INFO,do { if (debug_mode || (TEST_LOG_INFO <= verbosity)) printf
("main(0x%p): creating client threads\n", PR_GetCurrentThread
()); } while (0)
1176 ("main(0x%p): creating client threads\n", PR_GetCurrentThread()))do { if (debug_mode || (TEST_LOG_INFO <= verbosity)) printf
("main(0x%p): creating client threads\n", PR_GetCurrentThread
()); } while (0)
;
1177 client[index].thread = PR_CreateThread(
1178 PR_USER_THREAD, Client, &client[index], PR_PRIORITY_NORMAL,
1179 thread_scope, PR_JOINABLE_THREAD, 0);
1180 TEST_ASSERT(NULL != client[index].thread)((((void*)0) != client[index].thread)?((void)0):_MY_Assert("NULL != client[index].thread"
,"../../../pr/tests/cltsrv.c",1180))
;
1181 PR_Lock(client[index].ml);
1182 while (cs_init == client[index].state) {
1183 PR_WaitCondVar(client[index].stateChange, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
1184 }
1185 PR_Unlock(client[index].ml);
1186 }
1187 }
1188
1189 /* Then just let them go at it for a bit */
1190 TEST_LOG(do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("main(0x%p): waiting for execution interval (%d seconds)\n"
, PR_GetCurrentThread(), execution); } while (0)
1191 cltsrv_log_file, TEST_LOG_ALWAYS,do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("main(0x%p): waiting for execution interval (%d seconds)\n"
, PR_GetCurrentThread(), execution); } while (0)
1192 ("main(0x%p): waiting for execution interval (%d seconds)\n",do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("main(0x%p): waiting for execution interval (%d seconds)\n"
, PR_GetCurrentThread(), execution); } while (0)
1193 PR_GetCurrentThread(), execution))do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("main(0x%p): waiting for execution interval (%d seconds)\n"
, PR_GetCurrentThread(), execution); } while (0)
;
1194
1195 WaitForCompletion(execution);
1196
1197 TimeOfDayMessage("Shutting down", PR_GetCurrentThread());
1198
1199 if (clients != 0)
1200 {
1201 for (index = 0; index < clients; ++index)
1202 {
1203 TEST_LOG(cltsrv_log_file, TEST_LOG_STATUS,do { if (debug_mode || (TEST_LOG_STATUS <= verbosity)) printf
("main(0x%p): notifying client(0x%p) to stop\n", PR_GetCurrentThread
(), client[index].thread); } while (0)
1204 ("main(0x%p): notifying client(0x%p) to stop\n",do { if (debug_mode || (TEST_LOG_STATUS <= verbosity)) printf
("main(0x%p): notifying client(0x%p) to stop\n", PR_GetCurrentThread
(), client[index].thread); } while (0)
1205 PR_GetCurrentThread(), client[index].thread))do { if (debug_mode || (TEST_LOG_STATUS <= verbosity)) printf
("main(0x%p): notifying client(0x%p) to stop\n", PR_GetCurrentThread
(), client[index].thread); } while (0)
;
1206
1207 PR_Lock(client[index].ml);
1208 if (cs_run == client[index].state)
1209 {
1210 client[index].state = cs_stop;
1211 PR_Interrupt(client[index].thread);
1212 while (cs_stop == client[index].state)
1213 PR_WaitCondVar(
1214 client[index].stateChange, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
1215 }
1216 PR_Unlock(client[index].ml);
1217
1218 TEST_LOG(cltsrv_log_file, TEST_LOG_VERBOSE,do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("main(0x%p): joining client(0x%p)\n", PR_GetCurrentThread()
, client[index].thread); } while (0)
1219 ("main(0x%p): joining client(0x%p)\n",do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("main(0x%p): joining client(0x%p)\n", PR_GetCurrentThread()
, client[index].thread); } while (0)
1220 PR_GetCurrentThread(), client[index].thread))do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("main(0x%p): joining client(0x%p)\n", PR_GetCurrentThread()
, client[index].thread); } while (0)
;
1221
1222 joinStatus = PR_JoinThread(client[index].thread);
1223 TEST_ASSERT(PR_SUCCESS == joinStatus)((PR_SUCCESS == joinStatus)?((void)0):_MY_Assert("PR_SUCCESS == joinStatus"
,"../../../pr/tests/cltsrv.c",1223))
;
1224 PR_DestroyCondVar(client[index].stateChange);
1225 PR_DestroyLock(client[index].ml);
1226 }
1227 PR_DELETE(client){ PR_Free(client); (client) = ((void*)0); };
1228 }
1229
1230 if (NULL((void*)0) != server)
1231 {
1232 /* All clients joined - retrieve the server */
1233 TEST_LOG(do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("main(0x%p): notifying server(0x%p) to stop\n", PR_GetCurrentThread
(), server->thread); } while (0)
1234 cltsrv_log_file, TEST_LOG_NOTICE,do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("main(0x%p): notifying server(0x%p) to stop\n", PR_GetCurrentThread
(), server->thread); } while (0)
1235 ("main(0x%p): notifying server(0x%p) to stop\n",do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("main(0x%p): notifying server(0x%p) to stop\n", PR_GetCurrentThread
(), server->thread); } while (0)
1236 PR_GetCurrentThread(), server->thread))do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("main(0x%p): notifying server(0x%p) to stop\n", PR_GetCurrentThread
(), server->thread); } while (0)
;
1237
1238 PR_Lock(server->ml);
1239 server->state = cs_stop;
1240 PR_Interrupt(server->thread);
1241 while (cs_exit != server->state) {
1242 PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
1243 }
1244 PR_Unlock(server->ml);
1245
1246 TEST_LOG(do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("main(0x%p): joining server(0x%p)\n", PR_GetCurrentThread()
, server->thread); } while (0)
1247 cltsrv_log_file, TEST_LOG_NOTICE,do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("main(0x%p): joining server(0x%p)\n", PR_GetCurrentThread()
, server->thread); } while (0)
1248 ("main(0x%p): joining server(0x%p)\n",do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("main(0x%p): joining server(0x%p)\n", PR_GetCurrentThread()
, server->thread); } while (0)
1249 PR_GetCurrentThread(), server->thread))do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("main(0x%p): joining server(0x%p)\n", PR_GetCurrentThread()
, server->thread); } while (0)
;
1250 joinStatus = PR_JoinThread(server->thread);
1251 TEST_ASSERT(PR_SUCCESS == joinStatus)((PR_SUCCESS == joinStatus)?((void)0):_MY_Assert("PR_SUCCESS == joinStatus"
,"../../../pr/tests/cltsrv.c",1251))
;
1252
1253 PR_DestroyCondVar(server->stateChange);
1254 PR_DestroyCondVar(server->pool.exiting);
1255 PR_DestroyCondVar(server->pool.acceptComplete);
1256 PR_DestroyLock(server->ml);
1257 PR_DELETE(server){ PR_Free(server); (server) = ((void*)0); };
1258 }
1259
1260 TEST_LOG(do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("main(0x%p): test complete\n", PR_GetCurrentThread()); } while
(0)
1261 cltsrv_log_file, TEST_LOG_ALWAYS,do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("main(0x%p): test complete\n", PR_GetCurrentThread()); } while
(0)
1262 ("main(0x%p): test complete\n", PR_GetCurrentThread()))do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("main(0x%p): test complete\n", PR_GetCurrentThread()); } while
(0)
;
1263
1264 PT_FPrintStats(debug_out, "\nPThread Statistics\n");
1265
1266 TimeOfDayMessage("Test exiting at", PR_GetCurrentThread());
1267 PR_Cleanup();
1268 return 0;
1269} /* main */
1270
1271/* cltsrv.c */