Bug Summary

File:pr/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/pr/tests/../../../pr/tests/provider.c
Warning:line 946, column 5
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 provider.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/provider.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#ifdef DEBUG1
62#define PORT_INC_DO+100 +100
63#else
64#define PORT_INC_DO+100
65#endif
66#ifdef IS_64
67#define PORT_INC_3264+200 +200
68#else
69#define PORT_INC_3264+200
70#endif
71
72#define RECV_FLAGS0 0
73#define SEND_FLAGS0 0
74#define BUFFER_SIZE1024 1024
75#define DEFAULT_BACKLOG5 5
76#define DEFAULT_PORT13000 +100 +200 13000 PORT_INC_DO+100 PORT_INC_3264+200
77#define DEFAULT_CLIENTS1 1
78#define ALLOWED_IN_ACCEPT1 1
79#define DEFAULT_CLIPPING1000 1000
80#define DEFAULT_WORKERS_MIN1 1
81#define DEFAULT_WORKERS_MAX1 1
82#define DEFAULT_SERVER"localhost" "localhost"
83#define DEFAULT_EXECUTION_TIME10 10
84#define DEFAULT_CLIENT_TIMEOUT4000 4000
85#define DEFAULT_SERVER_TIMEOUT4000 4000
86#define DEFAULT_SERVER_PRIORITYPR_PRIORITY_HIGH PR_PRIORITY_HIGH
87
88typedef enum CSState_e {cs_init, cs_run, cs_stop, cs_exit} CSState_t;
89
90static void PR_CALLBACK Worker(void *arg);
91typedef struct CSPool_s CSPool_t;
92typedef struct CSWorker_s CSWorker_t;
93typedef struct CSServer_s CSServer_t;
94typedef enum Verbosity
95{
96 TEST_LOG_ALWAYS,
97 TEST_LOG_ERROR,
98 TEST_LOG_WARNING,
99 TEST_LOG_NOTICE,
100 TEST_LOG_INFO,
101 TEST_LOG_STATUS,
102 TEST_LOG_VERBOSE
103} Verbosity;
104
105static enum {
106 thread_nspr, thread_pthread, thread_sproc, thread_win32
107} thread_provider;
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/provider.c"
,183))
\
184 ((_expr)?((void)0):_MY_Assert(# _expr,__FILE__"../../../pr/tests/provider.c",__LINE__184))
185
186#define TEST_ASSERT(_expr)((_expr)?((void)0):_MY_Assert("_expr","../../../pr/tests/provider.c"
,186))
\
187 ((_expr)?((void)0):_MY_Assert(# _expr,__FILE__"../../../pr/tests/provider.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 CSClient_t *client = (CSClient_t*)arg;
222 PRThread *me = client->thread = PR_GetCurrentThread();
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/provider.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\n", me); } while (0)
254 cltsrv_log_file, TEST_LOG_ERROR,do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tClient(0x%p): conection failed\n", me); } while (0)
255 ("\tClient(0x%p): conection failed\n", me))do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tClient(0x%p): conection failed\n", me); } while (0)
;
256 goto aborted;
257 }
258
259 memset(descriptor, 0, sizeof(*descriptor));
260 descriptor->size = PR_htonl(descbytes = rand() % clipping);
261 PR_snprintf(
262 descriptor->filename, sizeof(descriptor->filename),
263 "CS%p%p-%p.dat", client->started, me, client->operations);
264 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tClient(0x%p): sending descriptor for %u bytes\n", me, descbytes
); } while (0)
265 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)
266 ("\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)
;
267 bytes = PR_Send(
268 fd, descriptor, sizeof(*descriptor), SEND_FLAGS0, timeout);
269 if (sizeof(CSDescriptor_t) != bytes)
270 {
271 if (Aborted(PR_FAILURE)) {
272 goto aborted;
273 }
274 if (PR_IO_TIMEOUT_ERROR(-5990L) == PR_GetError())
275 {
276 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tClient(0x%p): send descriptor timeout\n", me); } while (
0)
277 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)
278 ("\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)
;
279 goto retry;
280 }
281 }
282 TEST_ASSERT(sizeof(*descriptor) == bytes)((sizeof(*descriptor) == bytes)?((void)0):_MY_Assert("sizeof(*descriptor) == bytes"
,"../../../pr/tests/provider.c",282))
;
283
284 netbytes = 0;
285 while (netbytes < descbytes)
286 {
287 filebytes = sizeof(buffer);
288 if ((descbytes - netbytes) < filebytes) {
289 filebytes = descbytes - netbytes;
290 }
291 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tClient(0x%p): sending %d bytes\n", me, filebytes); } while
(0)
292 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)
293 ("\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)
;
294 bytes = PR_Send(fd, buffer, filebytes, SEND_FLAGS0, timeout);
295 if (filebytes != bytes)
296 {
297 if (Aborted(PR_FAILURE)) {
298 goto aborted;
299 }
300 if (PR_IO_TIMEOUT_ERROR(-5990L) == PR_GetError())
301 {
302 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tClient(0x%p): send data timeout\n", me); } while (0)
303 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)
304 ("\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)
;
305 goto retry;
306 }
307 }
308 TEST_ASSERT(bytes == filebytes)((bytes == filebytes)?((void)0):_MY_Assert("bytes == filebytes"
,"../../../pr/tests/provider.c",308))
;
309 netbytes += bytes;
310 }
311 filebytes = 0;
312 while (filebytes < descbytes)
313 {
314 netbytes = sizeof(buffer);
315 if ((descbytes - filebytes) < netbytes) {
316 netbytes = descbytes - filebytes;
317 }
318 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tClient(0x%p): receiving %d bytes\n", me, netbytes); } while
(0)
319 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)
320 ("\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)
;
321 bytes = PR_Recv(fd, buffer, netbytes, RECV_FLAGS0, timeout);
322 if (-1 == bytes)
323 {
324 if (Aborted(PR_FAILURE))
325 {
326 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tClient(0x%p): receive data aborted\n", me); } while (0)
327 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)
328 ("\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)
;
329 goto aborted;
330 }
331 else if (PR_IO_TIMEOUT_ERROR(-5990L) == PR_GetError())
332 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tClient(0x%p): receive data timeout\n", me); } while (0)
333 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)
334 ("\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)
;
335 else
336 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)
337 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)
338 ("\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)
339 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)
;
340 goto retry;
341 }
342 if (0 == bytes)
343 {
344 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tClient(0x%p): unexpected end of stream\n", PR_GetCurrentThread
()); } while (0)
345 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)
346 ("\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)
347 PR_GetCurrentThread()))do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tClient(0x%p): unexpected end of stream\n", PR_GetCurrentThread
()); } while (0)
;
348 break;
349 }
350 filebytes += bytes;
351 }
352
353 rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH);
354 if (Aborted(rv)) {
355 goto aborted;
356 }
357 TEST_ASSERT(PR_SUCCESS == rv)((PR_SUCCESS == rv)?((void)0):_MY_Assert("PR_SUCCESS == rv","../../../pr/tests/provider.c"
,357))
;
358retry:
359 (void)PR_Close(fd); fd = NULL((void*)0);
360 TEST_LOG(do { if (debug_mode || (TEST_LOG_INFO <= verbosity)) printf
("\tClient(0x%p): disconnected from server\n", me); } while (
0)
361 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)
362 ("\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)
;
363
364 PR_Lock(client->ml);
365 client->operations += 1;
366 client->bytesTransferred += 2 * descbytes;
367 rv = PR_WaitCondVar(client->stateChange, rand() % clipping);
368 PR_Unlock(client->ml);
369 if (Aborted(rv)) {
370 break;
371 }
372 }
373
374aborted:
375 client->stopped = PR_IntervalNow();
376
377 PR_ClearInterrupt();
378 if (NULL((void*)0) != fd) {
379 rv = PR_Close(fd);
380 }
381
382 PR_Lock(client->ml);
383 client->state = cs_exit;
384 PR_NotifyCondVar(client->stateChange);
385 PR_Unlock(client->ml);
386 PR_DELETE(descriptor){ PR_Free(descriptor); (descriptor) = ((void*)0); };
387 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)
388 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)
389 ("\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)
390 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)
;
391
392} /* Client */
393
394static PRStatus ProcessRequest(PRFileDesc *fd, CSServer_t *server)
395{
396 PRStatus drv, rv;
397 char buffer[1024];
398 PRFileDesc *file = NULL((void*)0);
399 PRThread * me = PR_GetCurrentThread();
400 PRInt32 bytes, descbytes, netbytes, filebytes = 0;
401 CSDescriptor_t *descriptor = PR_NEW(CSDescriptor_t)((CSDescriptor_t *) (PR_Malloc((sizeof(CSDescriptor_t)))));
402 PRIntervalTime timeout = PR_MillisecondsToInterval(DEFAULT_SERVER_TIMEOUT4000);
403
404 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tProcessRequest(0x%p): receiving desciptor\n", me); } while
(0)
405 cltsrv_log_file, TEST_LOG_VERBOSE,do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tProcessRequest(0x%p): receiving desciptor\n", me); } while
(0)
406 ("\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)
;
407 bytes = PR_Recv(
408 fd, descriptor, sizeof(*descriptor), RECV_FLAGS0, timeout);
409 if (-1 == bytes)
410 {
411 rv = PR_FAILURE;
412 if (Aborted(rv)) {
413 goto exit;
414 }
415 if (PR_IO_TIMEOUT_ERROR(-5990L) == PR_GetError())
416 {
417 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tProcessRequest(0x%p): receive timeout\n", me); } while (
0)
418 cltsrv_log_file, TEST_LOG_ERROR,do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tProcessRequest(0x%p): receive timeout\n", me); } while (
0)
419 ("\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)
;
420 }
421 goto exit;
422 }
423 if (0 == bytes)
424 {
425 rv = PR_FAILURE;
426 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tProcessRequest(0x%p): unexpected end of file\n", me); } while
(0)
427 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)
428 ("\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)
;
429 goto exit;
430 }
431 descbytes = PR_ntohl(descriptor->size);
432 TEST_ASSERT(sizeof(*descriptor) == bytes)((sizeof(*descriptor) == bytes)?((void)0):_MY_Assert("sizeof(*descriptor) == bytes"
,"../../../pr/tests/provider.c",432))
;
433
434 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)
435 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)
436 ("\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)
437 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)
;
438
439 file = PR_Open(
440 descriptor->filename, (PR_CREATE_FILE0x08 | PR_WRONLY0x02), 0666);
441 if (NULL((void*)0) == file)
442 {
443 rv = PR_FAILURE;
444 if (Aborted(rv)) {
445 goto aborted;
446 }
447 if (PR_IO_TIMEOUT_ERROR(-5990L) == PR_GetError())
448 {
449 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\tProcessRequest(0x%p): open file timeout\n", me); } while
(0)
450 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)
451 ("\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)
;
452 goto aborted;
453 }
454 }
455 TEST_ASSERT(NULL != file)((((void*)0) != file)?((void)0):_MY_Assert("NULL != file","../../../pr/tests/provider.c"
,455))
;
456
457 filebytes = 0;
458 while (filebytes < descbytes)
459 {
460 netbytes = sizeof(buffer);
461 if ((descbytes - filebytes) < netbytes) {
462 netbytes = descbytes - filebytes;
463 }
464 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tProcessRequest(0x%p): receive %d bytes\n", me, netbytes)
; } while (0)
465 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)
466 ("\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)
;
467 bytes = PR_Recv(fd, buffer, netbytes, RECV_FLAGS0, timeout);
468 if (-1 == bytes)
469 {
470 rv = PR_FAILURE;
471 if (Aborted(rv)) {
472 goto aborted;
473 }
474 if (PR_IO_TIMEOUT_ERROR(-5990L) == PR_GetError())
475 {
476 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): receive data timeout\n", me); } while
(0)
477 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)
478 ("\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)
;
479 goto aborted;
480 }
481 /*
482 * XXX: I got (PR_CONNECT_RESET_ERROR, ERROR_NETNAME_DELETED)
483 * on NT here. This is equivalent to ECONNRESET on Unix.
484 * -wtc
485 */
486 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)
487 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)
488 ("\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)
489 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)
;
490 goto aborted;
491 }
492 if(0 == bytes)
493 {
494 TEST_LOG(do { if (debug_mode || (TEST_LOG_WARNING <= verbosity)) printf
("\t\tProcessRequest(0x%p): unexpected end of stream\n", me)
; } while (0)
495 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)
496 ("\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)
;
497 rv = PR_FAILURE;
498 goto aborted;
499 }
500 filebytes += bytes;
501 netbytes = bytes;
502 /* The byte count for PR_Write should be positive */
503 MY_ASSERT(netbytes > 0)((netbytes > 0)?((void)0):_MY_Assert("netbytes > 0","../../../pr/tests/provider.c"
,503))
;
504 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tProcessRequest(0x%p): write %d bytes to file\n", me, netbytes
); } while (0)
505 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)
506 ("\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)
;
507 bytes = PR_Write(file, buffer, netbytes);
508 if (netbytes != bytes)
509 {
510 rv = PR_FAILURE;
511 if (Aborted(rv)) {
512 goto aborted;
513 }
514 if (PR_IO_TIMEOUT_ERROR(-5990L) == PR_GetError())
515 {
516 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): write file timeout\n", me); } while
(0)
517 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)
518 ("\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)
;
519 goto aborted;
520 }
521 }
522 TEST_ASSERT(bytes > 0)((bytes > 0)?((void)0):_MY_Assert("bytes > 0","../../../pr/tests/provider.c"
,522))
;
523 }
524
525 PR_Lock(server->ml);
526 server->operations += 1;
527 server->bytesTransferred += filebytes;
528 PR_Unlock(server->ml);
529
530 rv = PR_Close(file); file = NULL((void*)0);
531 if (Aborted(rv)) {
532 goto aborted;
533 }
534 TEST_ASSERT(PR_SUCCESS == rv)((PR_SUCCESS == rv)?((void)0):_MY_Assert("PR_SUCCESS == rv","../../../pr/tests/provider.c"
,534))
;
535
536 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\t\tProcessRequest(0x%p): opening %s\n", me, descriptor->
filename); } while (0)
537 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)
538 ("\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)
;
539 file = PR_Open(descriptor->filename, PR_RDONLY0x01, 0);
540 if (NULL((void*)0) == file)
541 {
542 rv = PR_FAILURE;
543 if (Aborted(rv)) {
544 goto aborted;
545 }
546 if (PR_IO_TIMEOUT_ERROR(-5990L) == PR_GetError())
547 {
548 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): open file timeout\n", PR_GetCurrentThread
()); } while (0)
549 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)
550 ("\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)
551 PR_GetCurrentThread()))do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): open file timeout\n", PR_GetCurrentThread
()); } while (0)
;
552 goto aborted;
553 }
554 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)
555 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)
556 ("\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)
557 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)
;
558 goto aborted;
559 }
560 TEST_ASSERT(NULL != file)((((void*)0) != file)?((void)0):_MY_Assert("NULL != file","../../../pr/tests/provider.c"
,560))
;
561
562 netbytes = 0;
563 while (netbytes < descbytes)
564 {
565 filebytes = sizeof(buffer);
566 if ((descbytes - netbytes) < filebytes) {
567 filebytes = descbytes - netbytes;
568 }
569 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tProcessRequest(0x%p): read %d bytes from file\n", me, filebytes
); } while (0)
570 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)
571 ("\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)
;
572 bytes = PR_Read(file, buffer, filebytes);
573 if (filebytes != bytes)
574 {
575 rv = PR_FAILURE;
576 if (Aborted(rv)) {
577 goto aborted;
578 }
579 if (PR_IO_TIMEOUT_ERROR(-5990L) == PR_GetError())
580 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): read file timeout\n", me); } while
(0)
581 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)
582 ("\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)
;
583 else
584 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)
585 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)
586 ("\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)
587 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)
;
588 goto aborted;
589 }
590 TEST_ASSERT(bytes > 0)((bytes > 0)?((void)0):_MY_Assert("bytes > 0","../../../pr/tests/provider.c"
,590))
;
591 netbytes += bytes;
592 filebytes = bytes;
593 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\t\tProcessRequest(0x%p): sending %d bytes\n", me, filebytes
); } while (0)
594 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)
595 ("\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)
;
596 bytes = PR_Send(fd, buffer, filebytes, SEND_FLAGS0, timeout);
597 if (filebytes != bytes)
598 {
599 rv = PR_FAILURE;
600 if (Aborted(rv)) {
601 goto aborted;
602 }
603 if (PR_IO_TIMEOUT_ERROR(-5990L) == PR_GetError())
604 {
605 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tProcessRequest(0x%p): send data timeout\n", me); } while
(0)
606 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)
607 ("\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)
;
608 goto aborted;
609 }
610 break;
611 }
612 TEST_ASSERT(bytes > 0)((bytes > 0)?((void)0):_MY_Assert("bytes > 0","../../../pr/tests/provider.c"
,612))
;
613 }
614
615 PR_Lock(server->ml);
616 server->bytesTransferred += filebytes;
617 PR_Unlock(server->ml);
618
619 rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH);
620 if (Aborted(rv)) {
621 goto aborted;
622 }
623
624 rv = PR_Close(file); file = NULL((void*)0);
625 if (Aborted(rv)) {
626 goto aborted;
627 }
628 TEST_ASSERT(PR_SUCCESS == rv)((PR_SUCCESS == rv)?((void)0):_MY_Assert("PR_SUCCESS == rv","../../../pr/tests/provider.c"
,628))
;
629
630aborted:
631 PR_ClearInterrupt();
632 if (NULL((void*)0) != file) {
633 PR_Close(file);
634 }
635 drv = PR_Delete(descriptor->filename);
636 TEST_ASSERT(PR_SUCCESS == drv)((PR_SUCCESS == drv)?((void)0):_MY_Assert("PR_SUCCESS == drv"
,"../../../pr/tests/provider.c",636))
;
637exit:
638 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\t\tProcessRequest(0x%p): Finished\n", me); } while (0)
639 cltsrv_log_file, TEST_LOG_VERBOSE,do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\t\tProcessRequest(0x%p): Finished\n", me); } while (0)
640 ("\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)
;
641
642 PR_DELETE(descriptor){ PR_Free(descriptor); (descriptor) = ((void*)0); };
643
644#if defined(WIN95)
645 PR_Sleep(PR_MillisecondsToInterval(200)); /* lth. see note [1] */
646#endif
647 return rv;
648} /* ProcessRequest */
649
650typedef void (*StartFn)(void*);
651typedef struct StartObject
652{
653 StartFn start;
654 void *arg;
655} StartObject;
656
657#if defined(_PR_PTHREADS1)
658#include "md/_pth.h"
659#include <pthread.h>
660
661static void *pthread_start(void *arg)
662{
663 StartObject *so = (StartObject*)arg;
664 StartFn start = so->start;
665 void *data = so->arg;
666 PR_Free(so);
667 start(data);
668 return NULL((void*)0);
669} /* pthread_start */
670#endif /* defined(_PR_PTHREADS) */
671
672#if defined(WIN32)
673#include <process.h> /* for _beginthreadex() */
674
675static PRUintn __stdcall windows_start(void *arg)
676{
677 StartObject *so = (StartObject*)arg;
678 StartFn start = so->start;
679 void *data = so->arg;
680 PR_Free(so);
681 start(data);
682 return 0;
683} /* windows_start */
684#endif /* defined(WIN32) */
685
686static PRStatus JoinThread(PRThread *thread)
687{
688 PRStatus rv;
689 switch (thread_provider)
690 {
691 case thread_nspr:
692 rv = PR_JoinThread(thread);
693 break;
694 case thread_pthread:
695#if defined(_PR_PTHREADS1)
696 rv = PR_SUCCESS;
697 break;
698#endif /* defined(_PR_PTHREADS) */
699 case thread_win32:
700#if defined(WIN32)
701 rv = PR_SUCCESS;
702 break;
703#endif
704 default:
705 rv = PR_FAILURE;
706 break;
707 }
708 return rv;
709} /* JoinThread */
710
711static PRStatus NewThread(
712 StartFn start, void *arg, PRThreadPriority prio, PRThreadState state)
713{
714 PRStatus rv;
715
716 switch (thread_provider)
717 {
718 case thread_nspr:
719 {
720 PRThread *thread = PR_CreateThread(
721 PR_USER_THREAD, start, arg,
722 PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
723 PR_JOINABLE_THREAD, 0);
724 rv = (NULL((void*)0) == thread) ? PR_FAILURE : PR_SUCCESS;
725 }
726 break;
727 case thread_pthread:
728#if defined(_PR_PTHREADS1)
729 {
730 int rv;
731 pthread_t id;
732 pthread_attr_t tattr;
733 StartObject *start_object;
734 start_object = PR_NEW(StartObject)((StartObject *) (PR_Malloc((sizeof(StartObject)))));
735 PR_ASSERT(NULL != start_object)((((void*)0) != start_object)?((void)0):PR_Assert("NULL != start_object"
,"../../../pr/tests/provider.c",735))
;
736 start_object->start = start;
737 start_object->arg = arg;
738
739 rv = _PT_PTHREAD_ATTR_INITpthread_attr_init(&tattr);
740 PR_ASSERT(0 == rv)((0 == rv)?((void)0):PR_Assert("0 == rv","../../../pr/tests/provider.c"
,740))
;
741
742 rv = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHEDPTHREAD_CREATE_DETACHED);
743 PR_ASSERT(0 == rv)((0 == rv)?((void)0):PR_Assert("0 == rv","../../../pr/tests/provider.c"
,743))
;
744
745 rv = pthread_attr_setstacksize(&tattr, 64 * 1024);
746 PR_ASSERT(0 == rv)((0 == rv)?((void)0):PR_Assert("0 == rv","../../../pr/tests/provider.c"
,746))
;
747
748 rv = _PT_PTHREAD_CREATE(&id, tattr, pthread_start, start_object)pthread_create(&id, &tattr, pthread_start, start_object
)
;
749 (void)_PT_PTHREAD_ATTR_DESTROYpthread_attr_destroy(&tattr);
750 return (0 == rv) ? PR_SUCCESS : PR_FAILURE;
751 }
752#else
753 PR_SetError(PR_NOT_IMPLEMENTED_ERROR(-5992L), 0);
754 rv = PR_FAILURE;
755#endif /* defined(_PR_PTHREADS) */
756 break;
757
758 case thread_sproc:
759 PR_SetError(PR_NOT_IMPLEMENTED_ERROR(-5992L), 0);
760 rv = PR_FAILURE;
761 break;
762 case thread_win32:
763#if defined(WIN32)
764 {
765 void *th;
766 PRUintn id;
767 StartObject *start_object;
768 start_object = PR_NEW(StartObject)((StartObject *) (PR_Malloc((sizeof(StartObject)))));
769 PR_ASSERT(NULL != start_object)((((void*)0) != start_object)?((void)0):PR_Assert("NULL != start_object"
,"../../../pr/tests/provider.c",769))
;
770 start_object->start = start;
771 start_object->arg = arg;
772 th = (void*)_beginthreadex(
773 NULL((void*)0), /* LPSECURITY_ATTRIBUTES - pointer to thread security attributes */
774 0U, /* DWORD - initial thread stack size, in bytes */
775 windows_start, /* LPTHREAD_START_ROUTINE - pointer to thread function */
776 start_object, /* LPVOID - argument for new thread */
777 STACK_SIZE_PARAM_IS_A_RESERVATION, /*DWORD dwCreationFlags - creation flags */
778 &id /* LPDWORD - pointer to returned thread identifier */ );
779
780 rv = (NULL((void*)0) == th) ? PR_FAILURE : PR_SUCCESS;
781 }
782#else
783 PR_SetError(PR_NOT_IMPLEMENTED_ERROR(-5992L), 0);
784 rv = PR_FAILURE;
785#endif
786 break;
787 default:
788 PR_SetError(PR_NOT_IMPLEMENTED_ERROR(-5992L), 0);
789 rv = PR_FAILURE;
790 }
791 return rv;
792} /* NewThread */
793
794static PRStatus CreateWorker(CSServer_t *server, CSPool_t *pool)
795{
796 PRStatus rv;
797 CSWorker_t *worker = PR_NEWZAP(CSWorker_t)((CSWorker_t*)PR_Calloc(1, sizeof(CSWorker_t)));
798 worker->server = server;
799 PR_INIT_CLIST(&worker->element)do { (&worker->element)->next = (&worker->element
); (&worker->element)->prev = (&worker->element
); } while (0)
;
800 rv = NewThread(
801 Worker, worker, DEFAULT_SERVER_PRIORITYPR_PRIORITY_HIGH, PR_UNJOINABLE_THREAD);
802 if (PR_FAILURE == rv) {
803 PR_DELETE(worker){ PR_Free(worker); (worker) = ((void*)0); };
804 }
805
806 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)
807 ("\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)
808 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)
;
809
810 return rv;
811} /* CreateWorker */
812
813static void PR_CALLBACK Worker(void *arg)
814{
815 PRStatus rv;
816 PRNetAddr from;
817 PRFileDesc *fd = NULL((void*)0);
818 CSWorker_t *worker = (CSWorker_t*)arg;
819 CSServer_t *server = worker->server;
820 CSPool_t *pool = &server->pool;
821
822 PRThread *me = worker->thread = PR_GetCurrentThread();
823
824 TEST_LOG(do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("\t\tWorker(0x%p): started [%u]\n", me, pool->workers + 1
); } while (0)
825 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)
826 ("\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)
;
827
828 PR_Lock(server->ml);
829 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)
;
830 pool->workers += 1; /* define our existance */
831
832 while (cs_run == server->state)
833 {
834 while (pool->accepting >= server->workers.accepting)
835 {
836 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)
837 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)
838 ("\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)
839 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)
;
840 rv = PR_WaitCondVar(pool->acceptComplete, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
841 if (Aborted(rv) || (cs_run != server->state))
842 {
843 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)
844 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)
845 ("\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)
846 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)
;
847 goto exit;
848 }
849 }
850 pool->accepting += 1; /* how many are really in accept */
851 PR_Unlock(server->ml);
852
853 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\t\tWorker(0x%p): calling accept\n", me); } while (0)
854 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)
855 ("\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)
;
856 fd = PR_Accept(server->listener, &from, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
857
858 PR_Lock(server->ml);
859 pool->accepting -= 1;
860 PR_NotifyCondVar(pool->acceptComplete);
861
862 if ((NULL((void*)0) == fd) && Aborted(PR_FAILURE))
863 {
864 if (NULL((void*)0) != server->listener)
865 {
866 PR_Close(server->listener);
867 server->listener = NULL((void*)0);
868 }
869 goto exit;
870 }
871
872 if (NULL((void*)0) != fd)
873 {
874 /*
875 ** Create another worker of the total number of workers is
876 ** less than the minimum specified or we have none left in
877 ** accept() AND we're not over the maximum.
878 ** This sort of presumes that the number allowed in accept
879 ** is at least as many as the minimum. Otherwise we'll keep
880 ** creating new threads and deleting them soon after.
881 */
882 PRBool another =
883 ((pool->workers < server->workers.minimum) ||
884 ((0 == pool->accepting)
885 && (pool->workers < server->workers.maximum))) ?
886 PR_TRUE1 : PR_FALSE0;
887 pool->active += 1;
888 PR_Unlock(server->ml);
889
890 if (another) {
891 (void)CreateWorker(server, pool);
892 }
893
894 rv = ProcessRequest(fd, server);
895 if (PR_SUCCESS != rv)
896 TEST_LOG(do { if (debug_mode || (TEST_LOG_ERROR <= verbosity)) printf
("\t\tWorker(0x%p): server process ended abnormally\n", me);
} while (0)
897 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)
898 ("\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)
;
899 (void)PR_Close(fd); fd = NULL((void*)0);
900
901 PR_Lock(server->ml);
902 pool->active -= 1;
903 }
904 }
905
906exit:
907 PR_ClearInterrupt();
908 PR_Unlock(server->ml);
909
910 if (NULL((void*)0) != fd)
911 {
912 (void)PR_Shutdown(fd, PR_SHUTDOWN_BOTH);
913 (void)PR_Close(fd);
914 }
915
916 TEST_LOG(do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("\t\tWorker(0x%p): exiting [%u]\n", PR_GetCurrentThread(), pool
->workers); } while (0)
917 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)
918 ("\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)
;
919
920 PR_Lock(server->ml);
921 pool->workers -= 1; /* undefine our existance */
922 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)
;
923 PR_NotifyCondVar(pool->exiting);
924 PR_Unlock(server->ml);
925
926 PR_DELETE(worker){ PR_Free(worker); (worker) = ((void*)0); }; /* destruction of the "worker" object */
927
928} /* Worker */
929
930static void PR_CALLBACK Server(void *arg)
931{
932 PRStatus rv;
933 PRNetAddr serverAddress;
934 CSServer_t *server = (CSServer_t*)arg;
935 PRThread *me = server->thread = PR_GetCurrentThread();
936 PRSocketOptionData sockOpt;
937
938 server->listener = PR_Socket(domain, SOCK_STREAMSOCK_STREAM, protocol);
939
940 sockOpt.option = PR_SockOpt_Reuseaddr;
941 sockOpt.value.reuse_addr = PR_TRUE1;
942 rv = PR_SetSocketOption(server->listener, &sockOpt);
943 TEST_ASSERT(PR_SUCCESS == rv)((PR_SUCCESS == rv)?((void)0):_MY_Assert("PR_SUCCESS == rv","../../../pr/tests/provider.c"
,943))
;
944
945 memset(&serverAddress, 0, sizeof(serverAddress));
946 rv = PR_InitializeNetAddr(PR_IpAddrAny, DEFAULT_PORT13000 +100 +200, &serverAddress);
Value stored to 'rv' is never read
947
948 rv = PR_Bind(server->listener, &serverAddress);
949 TEST_ASSERT(PR_SUCCESS == rv)((PR_SUCCESS == rv)?((void)0):_MY_Assert("PR_SUCCESS == rv","../../../pr/tests/provider.c"
,949))
;
950
951 rv = PR_Listen(server->listener, server->backlog);
952 TEST_ASSERT(PR_SUCCESS == rv)((PR_SUCCESS == rv)?((void)0):_MY_Assert("PR_SUCCESS == rv","../../../pr/tests/provider.c"
,952))
;
953
954 server->started = PR_IntervalNow();
955 TimeOfDayMessage("Server started at", me);
956
957 PR_Lock(server->ml);
958 server->state = cs_run;
959 PR_NotifyCondVar(server->stateChange);
960 PR_Unlock(server->ml);
961
962 /*
963 ** Create the first worker (actually, a thread that accepts
964 ** connections and then processes the work load as needed).
965 ** From this point on, additional worker threads are created
966 ** as they are needed by existing worker threads.
967 */
968 rv = CreateWorker(server, &server->pool);
969 TEST_ASSERT(PR_SUCCESS == rv)((PR_SUCCESS == rv)?((void)0):_MY_Assert("PR_SUCCESS == rv","../../../pr/tests/provider.c"
,969))
;
970
971 /*
972 ** From here on this thread is merely hanging around as the contact
973 ** point for the main test driver. It's just waiting for the driver
974 ** to declare the test complete.
975 */
976 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tServer(0x%p): waiting for state change\n", me); } while (
0)
977 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)
978 ("\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)
;
979
980 PR_Lock(server->ml);
981 while ((cs_run == server->state) && !Aborted(rv))
982 {
983 rv = PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
984 }
985 PR_Unlock(server->ml);
986 PR_ClearInterrupt();
987
988 TEST_LOG(do { if (debug_mode || (TEST_LOG_INFO <= verbosity)) printf
("\tServer(0x%p): shutting down workers\n", me); } while (0)
989 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)
990 ("\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)
;
991
992 /*
993 ** Get all the worker threads to exit. They know how to
994 ** clean up after themselves, so this is just a matter of
995 ** waiting for clorine in the pool to take effect. During
996 ** this stage we're ignoring interrupts.
997 */
998 server->workers.minimum = server->workers.maximum = 0;
999
1000 PR_Lock(server->ml);
1001 while (!PR_CLIST_IS_EMPTY(&server->list)((&server->list)->next == (&server->list)))
1002 {
1003 PRCList *head = PR_LIST_HEAD(&server->list)(&server->list)->next;
1004 CSWorker_t *worker = (CSWorker_t*)head;
1005 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("\tServer(0x%p): interrupting worker(0x%p)\n", me, worker);
} while (0)
1006 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)
1007 ("\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)
;
1008 rv = PR_Interrupt(worker->thread);
1009 TEST_ASSERT(PR_SUCCESS == rv)((PR_SUCCESS == rv)?((void)0):_MY_Assert("PR_SUCCESS == rv","../../../pr/tests/provider.c"
,1009))
;
1010 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)
;
1011 }
1012
1013 while (server->pool.workers > 0)
1014 {
1015 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)
1016 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)
1017 ("\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)
1018 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)
;
1019 (void)PR_WaitCondVar(server->pool.exiting, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
1020 }
1021
1022 server->state = cs_exit;
1023 PR_NotifyCondVar(server->stateChange);
1024 PR_Unlock(server->ml);
1025
1026 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)
1027 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)
1028 ("\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)
1029 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)
;
1030
1031 if (NULL((void*)0) != server->listener) {
1032 PR_Close(server->listener);
1033 }
1034 server->stopped = PR_IntervalNow();
1035
1036} /* Server */
1037
1038static void WaitForCompletion(PRIntn execution)
1039{
1040 while (execution > 0)
1041 {
1042 PRIntn dally = (execution > 30) ? 30 : execution;
1043 PR_Sleep(PR_SecondsToInterval(dally));
1044 if (pthread_stats) {
1045 PT_FPrintStats(debug_out, "\nPThread Statistics\n");
1046 }
1047 execution -= dally;
1048 }
1049} /* WaitForCompletion */
1050
1051static void Help(void)
1052{
1053 PR_fprintf(debug_out, "cltsrv test program usage:\n");
1054 PR_fprintf(debug_out, "\t-a <n> threads allowed in accept (5)\n");
1055 PR_fprintf(debug_out, "\t-b <n> backlock for listen (5)\n");
1056 PR_fprintf(debug_out, "\t-c <threads> number of clients to create (1)\n");
1057 PR_fprintf(debug_out, "\t-w <threads> minimal number of server threads (1)\n");
1058 PR_fprintf(debug_out, "\t-W <threads> maximum number of server threads (1)\n");
1059 PR_fprintf(debug_out, "\t-e <seconds> duration of the test in seconds (10)\n");
1060 PR_fprintf(debug_out, "\t-s <string> dsn name of server (localhost)\n");
1061 PR_fprintf(debug_out, "\t-G use GLOBAL threads (LOCAL)\n");
1062 PR_fprintf(debug_out, "\t-T <string> thread provider ('n' | 'p' | 'w')(n)\n");
1063 PR_fprintf(debug_out, "\t-X use XTP as transport (TCP)\n");
1064 PR_fprintf(debug_out, "\t-6 Use IPv6 (IPv4)\n");
1065 PR_fprintf(debug_out, "\t-v verbosity (accumulative) (0)\n");
1066 PR_fprintf(debug_out, "\t-p pthread statistics (FALSE)\n");
1067 PR_fprintf(debug_out, "\t-d debug mode (FALSE)\n");
1068 PR_fprintf(debug_out, "\t-h this message\n");
1069} /* Help */
1070
1071static Verbosity IncrementVerbosity(void)
1072{
1073 PRIntn verboge = (PRIntn)verbosity + 1;
1074 return (Verbosity)verboge;
1075} /* IncrementVerbosity */
1076
1077int main(int argc, char **argv)
1078{
1079 PRUintn index;
1080 PRBool boolean;
1081 CSClient_t *client;
1082 PRStatus rv, joinStatus;
1083 CSServer_t *server = NULL((void*)0);
1084 char *thread_type;
1085
1086 PRUintn backlog = DEFAULT_BACKLOG5;
1087 PRUintn clients = DEFAULT_CLIENTS1;
1088 const char *serverName = DEFAULT_SERVER"localhost";
1089 PRBool serverIsLocal = PR_TRUE1;
1090 PRUintn accepting = ALLOWED_IN_ACCEPT1;
1091 PRUintn workersMin = DEFAULT_WORKERS_MIN1;
1092 PRUintn workersMax = DEFAULT_WORKERS_MAX1;
1093 PRIntn execution = DEFAULT_EXECUTION_TIME10;
1094
1095 /*
1096 * -G use global threads
1097 * -a <n> threads allowed in accept
1098 * -b <n> backlock for listen
1099 * -c <threads> number of clients to create
1100 * -w <threads> minimal number of server threads
1101 * -W <threads> maximum number of server threads
1102 * -e <seconds> duration of the test in seconds
1103 * -s <string> dsn name of server (implies no server here)
1104 * -v verbosity
1105 */
1106
1107 PLOptStatus os;
1108 PLOptState *opt = PL_CreateOptState(argc, argv, "GX6b:a:c:w:W:e:s:T:vdhp");
1109
1110#if defined(WIN32)
1111 thread_provider = thread_win32;
1112#elif defined(_PR_PTHREADS1)
1113 thread_provider = thread_pthread;
1114#else
1115 thread_provider = thread_nspr;
1116#endif
1117
1118 debug_out = PR_GetSpecialFD(PR_StandardError);
1119
1120 while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
1121 {
1122 if (PL_OPT_BAD == os) {
1123 continue;
1124 }
1125 switch (opt->option)
1126 {
1127 case 'G': /* use global threads */
1128 thread_scope = PR_GLOBAL_THREAD;
1129 break;
1130 case 'X': /* use XTP as transport */
1131 protocol = 36;
1132 break;
1133 case '6': /* Use IPv6 */
1134 domain = PR_AF_INET610;
1135 break;
1136 case 'a': /* the value for accepting */
1137 accepting = atoi(opt->value);
1138 break;
1139 case 'b': /* the value for backlock */
1140 backlog = atoi(opt->value);
1141 break;
1142 case 'T': /* the thread provider */
1143 if ('n' == *opt->value) {
1144 thread_provider = thread_nspr;
1145 }
1146 else if ('p' == *opt->value) {
1147 thread_provider = thread_pthread;
1148 }
1149 else if ('w' == *opt->value) {
1150 thread_provider = thread_win32;
1151 }
1152 else {
1153 Help();
1154 return 2;
1155 }
1156 break;
1157 case 'c': /* number of client threads */
1158 clients = atoi(opt->value);
1159 break;
1160 case 'w': /* minimum server worker threads */
1161 workersMin = atoi(opt->value);
1162 break;
1163 case 'W': /* maximum server worker threads */
1164 workersMax = atoi(opt->value);
1165 break;
1166 case 'e': /* program execution time in seconds */
1167 execution = atoi(opt->value);
1168 break;
1169 case 's': /* server's address */
1170 serverName = opt->value;
1171 break;
1172 case 'v': /* verbosity */
1173 verbosity = IncrementVerbosity();
1174 break;
1175 case 'd': /* debug mode */
1176 debug_mode = PR_TRUE1;
1177 break;
1178 case 'p': /* pthread mode */
1179 pthread_stats = PR_TRUE1;
1180 break;
1181 case 'h':
1182 default:
1183 Help();
1184 return 2;
1185 }
1186 }
1187 PL_DestroyOptState(opt);
1188
1189 if (0 != PL_strcmp(serverName, DEFAULT_SERVER"localhost")) {
1190 serverIsLocal = PR_FALSE0;
1191 }
1192 if (0 == execution) {
1193 execution = DEFAULT_EXECUTION_TIME10;
1194 }
1195 if (0 == workersMax) {
1196 workersMax = DEFAULT_WORKERS_MAX1;
1197 }
1198 if (0 == workersMin) {
1199 workersMin = DEFAULT_WORKERS_MIN1;
1200 }
1201 if (0 == accepting) {
1202 accepting = ALLOWED_IN_ACCEPT1;
1203 }
1204 if (0 == backlog) {
1205 backlog = DEFAULT_BACKLOG5;
1206 }
1207
1208 if (workersMin > accepting) {
1209 accepting = workersMin;
1210 }
1211
1212 PR_STDIO_INIT();
1213 TimeOfDayMessage("Client/Server started at", PR_GetCurrentThread());
1214
1215 cltsrv_log_file = PR_NewLogModule("cltsrv_log");
1216 MY_ASSERT(NULL != cltsrv_log_file)((((void*)0) != cltsrv_log_file)?((void)0):_MY_Assert("NULL != cltsrv_log_file"
,"../../../pr/tests/provider.c",1216))
;
1217 boolean = PR_SetLogFile("cltsrv.log");
1218 MY_ASSERT(boolean)((boolean)?((void)0):_MY_Assert("boolean","../../../pr/tests/provider.c"
,1218))
;
1219
1220 if (serverIsLocal)
1221 {
1222 /* Establish the server */
1223 TEST_LOG(do { if (debug_mode || (TEST_LOG_INFO <= verbosity)) printf
("main(0x%p): starting server\n", PR_GetCurrentThread()); } while
(0)
1224 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)
1225 ("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)
;
1226
1227 server = PR_NEWZAP(CSServer_t)((CSServer_t*)PR_Calloc(1, sizeof(CSServer_t)));
1228 PR_INIT_CLIST(&server->list)do { (&server->list)->next = (&server->list)
; (&server->list)->prev = (&server->list); }
while (0)
;
1229 server->state = cs_init;
1230 server->ml = PR_NewLock();
1231 server->backlog = backlog;
1232 server->port = DEFAULT_PORT13000 +100 +200;
1233 server->workers.minimum = workersMin;
1234 server->workers.maximum = workersMax;
1235 server->workers.accepting = accepting;
1236 server->stateChange = PR_NewCondVar(server->ml);
1237 server->pool.exiting = PR_NewCondVar(server->ml);
1238 server->pool.acceptComplete = PR_NewCondVar(server->ml);
1239
1240 TEST_LOG(do { if (debug_mode || (TEST_LOG_NOTICE <= verbosity)) printf
("main(0x%p): creating server thread\n", PR_GetCurrentThread
()); } while (0)
1241 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)
1242 ("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)
;
1243
1244 rv = NewThread(
1245 Server, server, PR_PRIORITY_HIGH, PR_JOINABLE_THREAD);
1246 TEST_ASSERT(PR_SUCCESS == rv)((PR_SUCCESS == rv)?((void)0):_MY_Assert("PR_SUCCESS == rv","../../../pr/tests/provider.c"
,1246))
;
1247
1248 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("main(0x%p): waiting for server init\n", PR_GetCurrentThread
()); } while (0)
1249 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)
1250 ("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)
;
1251
1252 PR_Lock(server->ml);
1253 while (server->state == cs_init) {
1254 PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
1255 }
1256 PR_Unlock(server->ml);
1257
1258 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)
1259 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)
1260 ("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)
1261 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)
;
1262 }
1263
1264 if (clients != 0)
1265 {
1266 /* Create all of the clients */
1267 PRHostEnt host;
1268 char buffer[BUFFER_SIZE1024];
1269 client = (CSClient_t*)PR_CALLOC(clients * sizeof(CSClient_t))(PR_Calloc(1, (clients * sizeof(CSClient_t))));
1270
1271 TEST_LOG(do { if (debug_mode || (TEST_LOG_VERBOSE <= verbosity)) printf
("main(0x%p): creating %d client threads\n", PR_GetCurrentThread
(), clients); } while (0)
1272 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)
1273 ("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)
1274 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)
;
1275
1276 if (!serverIsLocal)
1277 {
1278 rv = PR_GetHostByName(serverName, buffer, BUFFER_SIZE1024, &host);
1279 if (PR_SUCCESS != rv)
1280 {
1281 PL_FPrintError(PR_STDERRPR_GetSpecialFD(PR_StandardError), "PR_GetHostByName");
1282 return 2;
1283 }
1284 }
1285
1286 for (index = 0; index < clients; ++index)
1287 {
1288 client[index].state = cs_init;
1289 client[index].ml = PR_NewLock();
1290 if (serverIsLocal)
1291 {
1292 (void)PR_InitializeNetAddr(
1293 PR_IpAddrLoopback, DEFAULT_PORT13000 +100 +200,
1294 &client[index].serverAddress);
1295 }
1296 else
1297 {
1298 (void)PR_EnumerateHostEnt(
1299 0, &host, DEFAULT_PORT13000 +100 +200, &client[index].serverAddress);
1300 }
1301 client[index].stateChange = PR_NewCondVar(client[index].ml);
1302 TEST_LOG(do { if (debug_mode || (TEST_LOG_INFO <= verbosity)) printf
("main(0x%p): creating client threads\n", PR_GetCurrentThread
()); } while (0)
1303 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)
1304 ("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)
;
1305 rv = NewThread(
1306 Client, &client[index], PR_PRIORITY_NORMAL, PR_JOINABLE_THREAD);
1307 TEST_ASSERT(PR_SUCCESS == rv)((PR_SUCCESS == rv)?((void)0):_MY_Assert("PR_SUCCESS == rv","../../../pr/tests/provider.c"
,1307))
;
1308 PR_Lock(client[index].ml);
1309 while (cs_init == client[index].state) {
1310 PR_WaitCondVar(client[index].stateChange, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
1311 }
1312 PR_Unlock(client[index].ml);
1313 }
1314 }
1315
1316 /* Then just let them go at it for a bit */
1317 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)
1318 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)
1319 ("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)
1320 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)
;
1321
1322 WaitForCompletion(execution);
1323
1324 TimeOfDayMessage("Shutting down", PR_GetCurrentThread());
1325
1326 if (clients != 0)
1327 {
1328 for (index = 0; index < clients; ++index)
1329 {
1330 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)
1331 ("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)
1332 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)
;
1333
1334 PR_Lock(client[index].ml);
1335 if (cs_run == client[index].state)
1336 {
1337 client[index].state = cs_stop;
1338 PR_Interrupt(client[index].thread);
1339 while (cs_stop == client[index].state)
1340 PR_WaitCondVar(
1341 client[index].stateChange, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
1342 }
1343 PR_Unlock(client[index].ml);
1344
1345 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)
1346 ("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)
1347 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)
;
1348
1349 joinStatus = JoinThread(client[index].thread);
1350 TEST_ASSERT(PR_SUCCESS == joinStatus)((PR_SUCCESS == joinStatus)?((void)0):_MY_Assert("PR_SUCCESS == joinStatus"
,"../../../pr/tests/provider.c",1350))
;
1351 PR_DestroyCondVar(client[index].stateChange);
1352 PR_DestroyLock(client[index].ml);
1353 }
1354 PR_DELETE(client){ PR_Free(client); (client) = ((void*)0); };
1355 }
1356
1357 if (NULL((void*)0) != server)
1358 {
1359 /* All clients joined - retrieve the server */
1360 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)
1361 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)
1362 ("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)
1363 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)
;
1364
1365 PR_Lock(server->ml);
1366 server->state = cs_stop;
1367 PR_Interrupt(server->thread);
1368 while (cs_exit != server->state) {
1369 PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
1370 }
1371 PR_Unlock(server->ml);
1372
1373 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)
1374 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)
1375 ("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)
1376 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)
;
1377 joinStatus = JoinThread(server->thread);
1378 TEST_ASSERT(PR_SUCCESS == joinStatus)((PR_SUCCESS == joinStatus)?((void)0):_MY_Assert("PR_SUCCESS == joinStatus"
,"../../../pr/tests/provider.c",1378))
;
1379
1380 PR_DestroyCondVar(server->stateChange);
1381 PR_DestroyCondVar(server->pool.exiting);
1382 PR_DestroyCondVar(server->pool.acceptComplete);
1383 PR_DestroyLock(server->ml);
1384 PR_DELETE(server){ PR_Free(server); (server) = ((void*)0); };
1385 }
1386
1387 TEST_LOG(do { if (debug_mode || (TEST_LOG_ALWAYS <= verbosity)) printf
("main(0x%p): test complete\n", PR_GetCurrentThread()); } while
(0)
1388 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)
1389 ("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)
;
1390
1391 if (thread_provider == thread_win32) {
1392 thread_type = "\nWin32 Thread Statistics\n";
1393 }
1394 else if (thread_provider == thread_pthread) {
1395 thread_type = "\npthread Statistics\n";
1396 }
1397 else if (thread_provider == thread_sproc) {
1398 thread_type = "\nsproc Statistics\n";
1399 }
1400 else {
1401 PR_ASSERT(thread_provider == thread_nspr)((thread_provider == thread_nspr)?((void)0):PR_Assert("thread_provider == thread_nspr"
,"../../../pr/tests/provider.c",1401))
;
1402 thread_type = "\nPRThread Statistics\nn";
1403 }
1404
1405 PT_FPrintStats(debug_out, thread_type);
1406
1407 TimeOfDayMessage("Test exiting at", PR_GetCurrentThread());
1408 PR_Cleanup();
1409 return 0;
1410} /* main */
1411
1412/* cltsrv.c */