Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | #include "prio.h" |
michael@0 | 7 | #include "prprf.h" |
michael@0 | 8 | #include "prlog.h" |
michael@0 | 9 | #include "prnetdb.h" |
michael@0 | 10 | #include "prthread.h" |
michael@0 | 11 | |
michael@0 | 12 | #include "plerror.h" |
michael@0 | 13 | #include "plgetopt.h" |
michael@0 | 14 | #include "prwin16.h" |
michael@0 | 15 | |
michael@0 | 16 | #include <stdlib.h> |
michael@0 | 17 | #include <string.h> |
michael@0 | 18 | |
michael@0 | 19 | /* |
michael@0 | 20 | ** Testing layering of I/O |
michael@0 | 21 | ** |
michael@0 | 22 | ** The layered server |
michael@0 | 23 | ** A thread that acts as a server. It creates a TCP listener with a dummy |
michael@0 | 24 | ** layer pushed on top. Then listens for incoming connections. Each connection |
michael@0 | 25 | ** request for connection will be layered as well, accept one request, echo |
michael@0 | 26 | ** it back and close. |
michael@0 | 27 | ** |
michael@0 | 28 | ** The layered client |
michael@0 | 29 | ** Pretty much what you'd expect. |
michael@0 | 30 | */ |
michael@0 | 31 | |
michael@0 | 32 | static PRFileDesc *logFile; |
michael@0 | 33 | static PRDescIdentity identity; |
michael@0 | 34 | static PRNetAddr server_address; |
michael@0 | 35 | |
michael@0 | 36 | static PRIOMethods myMethods; |
michael@0 | 37 | |
michael@0 | 38 | typedef enum Verbosity {silent, quiet, chatty, noisy} Verbosity; |
michael@0 | 39 | |
michael@0 | 40 | static PRIntn minor_iterations = 5; |
michael@0 | 41 | static PRIntn major_iterations = 1; |
michael@0 | 42 | static Verbosity verbosity = quiet; |
michael@0 | 43 | static PRUint16 default_port = 12273; |
michael@0 | 44 | |
michael@0 | 45 | static PRFileDesc *PushLayer(PRFileDesc *stack) |
michael@0 | 46 | { |
michael@0 | 47 | PRFileDesc *layer = PR_CreateIOLayerStub(identity, &myMethods); |
michael@0 | 48 | PRStatus rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); |
michael@0 | 49 | if (verbosity > quiet) |
michael@0 | 50 | PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack); |
michael@0 | 51 | PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 52 | return stack; |
michael@0 | 53 | } /* PushLayer */ |
michael@0 | 54 | |
michael@0 | 55 | static PRFileDesc *PushNewLayers(PRFileDesc *stack) |
michael@0 | 56 | { |
michael@0 | 57 | PRDescIdentity tmp_identity; |
michael@0 | 58 | PRFileDesc *layer; |
michael@0 | 59 | PRStatus rv; |
michael@0 | 60 | |
michael@0 | 61 | /* push a dummy layer */ |
michael@0 | 62 | tmp_identity = PR_GetUniqueIdentity("Dummy 1"); |
michael@0 | 63 | layer = PR_CreateIOLayerStub(tmp_identity, PR_GetDefaultIOMethods()); |
michael@0 | 64 | rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); |
michael@0 | 65 | if (verbosity > quiet) |
michael@0 | 66 | PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, |
michael@0 | 67 | stack); |
michael@0 | 68 | PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 69 | |
michael@0 | 70 | /* push a data procesing layer */ |
michael@0 | 71 | layer = PR_CreateIOLayerStub(identity, &myMethods); |
michael@0 | 72 | rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); |
michael@0 | 73 | if (verbosity > quiet) |
michael@0 | 74 | PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, |
michael@0 | 75 | stack); |
michael@0 | 76 | PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 77 | |
michael@0 | 78 | /* push another dummy layer */ |
michael@0 | 79 | tmp_identity = PR_GetUniqueIdentity("Dummy 2"); |
michael@0 | 80 | layer = PR_CreateIOLayerStub(tmp_identity, PR_GetDefaultIOMethods()); |
michael@0 | 81 | rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); |
michael@0 | 82 | if (verbosity > quiet) |
michael@0 | 83 | PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, |
michael@0 | 84 | stack); |
michael@0 | 85 | PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 86 | return stack; |
michael@0 | 87 | } /* PushLayer */ |
michael@0 | 88 | |
michael@0 | 89 | #if 0 |
michael@0 | 90 | static PRFileDesc *PopLayer(PRFileDesc *stack) |
michael@0 | 91 | { |
michael@0 | 92 | PRFileDesc *popped = PR_PopIOLayer(stack, identity); |
michael@0 | 93 | if (verbosity > quiet) |
michael@0 | 94 | PR_fprintf(logFile, "Popped layer(0x%x) from stack(0x%x)\n", popped, stack); |
michael@0 | 95 | popped->dtor(popped); |
michael@0 | 96 | |
michael@0 | 97 | return stack; |
michael@0 | 98 | } /* PopLayer */ |
michael@0 | 99 | #endif |
michael@0 | 100 | |
michael@0 | 101 | static void PR_CALLBACK Client(void *arg) |
michael@0 | 102 | { |
michael@0 | 103 | PRStatus rv; |
michael@0 | 104 | PRUint8 buffer[100]; |
michael@0 | 105 | PRIntn empty_flags = 0; |
michael@0 | 106 | PRIntn bytes_read, bytes_sent; |
michael@0 | 107 | PRFileDesc *stack = (PRFileDesc*)arg; |
michael@0 | 108 | |
michael@0 | 109 | /* Initialize the buffer so that Purify won't complain */ |
michael@0 | 110 | memset(buffer, 0, sizeof(buffer)); |
michael@0 | 111 | |
michael@0 | 112 | rv = PR_Connect(stack, &server_address, PR_INTERVAL_NO_TIMEOUT); |
michael@0 | 113 | PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 114 | while (minor_iterations-- > 0) |
michael@0 | 115 | { |
michael@0 | 116 | bytes_sent = PR_Send( |
michael@0 | 117 | stack, buffer, sizeof(buffer), empty_flags, PR_INTERVAL_NO_TIMEOUT); |
michael@0 | 118 | PR_ASSERT(sizeof(buffer) == bytes_sent); |
michael@0 | 119 | if (verbosity > chatty) |
michael@0 | 120 | PR_fprintf(logFile, "Client sending %d bytes\n", bytes_sent); |
michael@0 | 121 | bytes_read = PR_Recv( |
michael@0 | 122 | stack, buffer, bytes_sent, empty_flags, PR_INTERVAL_NO_TIMEOUT); |
michael@0 | 123 | if (verbosity > chatty) |
michael@0 | 124 | PR_fprintf(logFile, "Client receiving %d bytes\n", bytes_read); |
michael@0 | 125 | PR_ASSERT(bytes_read == bytes_sent); |
michael@0 | 126 | } |
michael@0 | 127 | |
michael@0 | 128 | if (verbosity > quiet) |
michael@0 | 129 | PR_fprintf(logFile, "Client shutting down stack\n"); |
michael@0 | 130 | |
michael@0 | 131 | rv = PR_Shutdown(stack, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 132 | } /* Client */ |
michael@0 | 133 | |
michael@0 | 134 | static void PR_CALLBACK Server(void *arg) |
michael@0 | 135 | { |
michael@0 | 136 | PRStatus rv; |
michael@0 | 137 | PRUint8 buffer[100]; |
michael@0 | 138 | PRFileDesc *service; |
michael@0 | 139 | PRUintn empty_flags = 0; |
michael@0 | 140 | PRIntn bytes_read, bytes_sent; |
michael@0 | 141 | PRFileDesc *stack = (PRFileDesc*)arg; |
michael@0 | 142 | PRNetAddr client_address; |
michael@0 | 143 | |
michael@0 | 144 | service = PR_Accept(stack, &client_address, PR_INTERVAL_NO_TIMEOUT); |
michael@0 | 145 | if (verbosity > quiet) |
michael@0 | 146 | PR_fprintf(logFile, "Server accepting connection\n"); |
michael@0 | 147 | |
michael@0 | 148 | do |
michael@0 | 149 | { |
michael@0 | 150 | bytes_read = PR_Recv( |
michael@0 | 151 | service, buffer, sizeof(buffer), empty_flags, PR_INTERVAL_NO_TIMEOUT); |
michael@0 | 152 | if (0 != bytes_read) |
michael@0 | 153 | { |
michael@0 | 154 | if (verbosity > chatty) |
michael@0 | 155 | PR_fprintf(logFile, "Server receiving %d bytes\n", bytes_read); |
michael@0 | 156 | PR_ASSERT(bytes_read > 0); |
michael@0 | 157 | bytes_sent = PR_Send( |
michael@0 | 158 | service, buffer, bytes_read, empty_flags, PR_INTERVAL_NO_TIMEOUT); |
michael@0 | 159 | if (verbosity > chatty) |
michael@0 | 160 | PR_fprintf(logFile, "Server sending %d bytes\n", bytes_sent); |
michael@0 | 161 | PR_ASSERT(bytes_read == bytes_sent); |
michael@0 | 162 | } |
michael@0 | 163 | |
michael@0 | 164 | } while (0 != bytes_read); |
michael@0 | 165 | |
michael@0 | 166 | if (verbosity > quiet) |
michael@0 | 167 | PR_fprintf(logFile, "Server shutting down and closing stack\n"); |
michael@0 | 168 | rv = PR_Shutdown(service, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 169 | rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 170 | |
michael@0 | 171 | } /* Server */ |
michael@0 | 172 | |
michael@0 | 173 | static PRInt32 PR_CALLBACK MyRecv( |
michael@0 | 174 | PRFileDesc *fd, void *buf, PRInt32 amount, |
michael@0 | 175 | PRIntn flags, PRIntervalTime timeout) |
michael@0 | 176 | { |
michael@0 | 177 | char *b = (char*)buf; |
michael@0 | 178 | PRFileDesc *lo = fd->lower; |
michael@0 | 179 | PRInt32 rv, readin = 0, request = 0; |
michael@0 | 180 | rv = lo->methods->recv(lo, &request, sizeof(request), flags, timeout); |
michael@0 | 181 | if (verbosity > chatty) PR_fprintf( |
michael@0 | 182 | logFile, "MyRecv sending permission for %d bytes\n", request); |
michael@0 | 183 | if (0 < rv) |
michael@0 | 184 | { |
michael@0 | 185 | if (verbosity > chatty) PR_fprintf( |
michael@0 | 186 | logFile, "MyRecv received permission request for %d bytes\n", request); |
michael@0 | 187 | rv = lo->methods->send( |
michael@0 | 188 | lo, &request, sizeof(request), flags, timeout); |
michael@0 | 189 | if (0 < rv) |
michael@0 | 190 | { |
michael@0 | 191 | if (verbosity > chatty) PR_fprintf( |
michael@0 | 192 | logFile, "MyRecv sending permission for %d bytes\n", request); |
michael@0 | 193 | while (readin < request) |
michael@0 | 194 | { |
michael@0 | 195 | rv = lo->methods->recv( |
michael@0 | 196 | lo, b + readin, amount - readin, flags, timeout); |
michael@0 | 197 | if (rv <= 0) break; |
michael@0 | 198 | if (verbosity > chatty) PR_fprintf( |
michael@0 | 199 | logFile, "MyRecv received %d bytes\n", rv); |
michael@0 | 200 | readin += rv; |
michael@0 | 201 | } |
michael@0 | 202 | rv = readin; |
michael@0 | 203 | } |
michael@0 | 204 | } |
michael@0 | 205 | return rv; |
michael@0 | 206 | } /* MyRecv */ |
michael@0 | 207 | |
michael@0 | 208 | static PRInt32 PR_CALLBACK MySend( |
michael@0 | 209 | PRFileDesc *fd, const void *buf, PRInt32 amount, |
michael@0 | 210 | PRIntn flags, PRIntervalTime timeout) |
michael@0 | 211 | { |
michael@0 | 212 | PRFileDesc *lo = fd->lower; |
michael@0 | 213 | const char *b = (const char*)buf; |
michael@0 | 214 | PRInt32 rv, wroteout = 0, request; |
michael@0 | 215 | if (verbosity > chatty) PR_fprintf( |
michael@0 | 216 | logFile, "MySend asking permission to send %d bytes\n", amount); |
michael@0 | 217 | rv = lo->methods->send(lo, &amount, sizeof(amount), flags, timeout); |
michael@0 | 218 | if (0 < rv) |
michael@0 | 219 | { |
michael@0 | 220 | rv = lo->methods->recv( |
michael@0 | 221 | lo, &request, sizeof(request), flags, timeout); |
michael@0 | 222 | if (0 < rv) |
michael@0 | 223 | { |
michael@0 | 224 | PR_ASSERT(request == amount); |
michael@0 | 225 | if (verbosity > chatty) PR_fprintf( |
michael@0 | 226 | logFile, "MySend got permission to send %d bytes\n", request); |
michael@0 | 227 | while (wroteout < request) |
michael@0 | 228 | { |
michael@0 | 229 | rv = lo->methods->send( |
michael@0 | 230 | lo, b + wroteout, request - wroteout, flags, timeout); |
michael@0 | 231 | if (rv <= 0) break; |
michael@0 | 232 | if (verbosity > chatty) PR_fprintf( |
michael@0 | 233 | logFile, "MySend wrote %d bytes\n", rv); |
michael@0 | 234 | wroteout += rv; |
michael@0 | 235 | } |
michael@0 | 236 | rv = amount; |
michael@0 | 237 | } |
michael@0 | 238 | } |
michael@0 | 239 | return rv; |
michael@0 | 240 | } /* MySend */ |
michael@0 | 241 | |
michael@0 | 242 | static Verbosity ChangeVerbosity(Verbosity verbosity, PRIntn delta) |
michael@0 | 243 | { |
michael@0 | 244 | PRIntn verbage = (PRIntn)verbosity + delta; |
michael@0 | 245 | if (verbage < (PRIntn)silent) verbage = (PRIntn)silent; |
michael@0 | 246 | else if (verbage > (PRIntn)noisy) verbage = (PRIntn)noisy; |
michael@0 | 247 | return (Verbosity)verbage; |
michael@0 | 248 | } /* ChangeVerbosity */ |
michael@0 | 249 | |
michael@0 | 250 | int main(int argc, char **argv) |
michael@0 | 251 | { |
michael@0 | 252 | PRStatus rv; |
michael@0 | 253 | PRIntn mits; |
michael@0 | 254 | PLOptStatus os; |
michael@0 | 255 | PRFileDesc *client, *service; |
michael@0 | 256 | PRFileDesc *client_stack, *service_stack; |
michael@0 | 257 | PRNetAddr any_address; |
michael@0 | 258 | const char *server_name = NULL; |
michael@0 | 259 | const PRIOMethods *stubMethods; |
michael@0 | 260 | PRThread *client_thread, *server_thread; |
michael@0 | 261 | PRThreadScope thread_scope = PR_LOCAL_THREAD; |
michael@0 | 262 | PLOptState *opt = PL_CreateOptState(argc, argv, "dqGC:c:p:"); |
michael@0 | 263 | while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) |
michael@0 | 264 | { |
michael@0 | 265 | if (PL_OPT_BAD == os) continue; |
michael@0 | 266 | switch (opt->option) |
michael@0 | 267 | { |
michael@0 | 268 | case 0: |
michael@0 | 269 | server_name = opt->value; |
michael@0 | 270 | break; |
michael@0 | 271 | case 'd': /* debug mode */ |
michael@0 | 272 | if (verbosity < noisy) |
michael@0 | 273 | verbosity = ChangeVerbosity(verbosity, 1); |
michael@0 | 274 | break; |
michael@0 | 275 | case 'q': /* debug mode */ |
michael@0 | 276 | if (verbosity > silent) |
michael@0 | 277 | verbosity = ChangeVerbosity(verbosity, -1); |
michael@0 | 278 | break; |
michael@0 | 279 | case 'G': /* use global threads */ |
michael@0 | 280 | thread_scope = PR_GLOBAL_THREAD; |
michael@0 | 281 | break; |
michael@0 | 282 | case 'C': /* number of threads waiting */ |
michael@0 | 283 | major_iterations = atoi(opt->value); |
michael@0 | 284 | break; |
michael@0 | 285 | case 'c': /* number of client threads */ |
michael@0 | 286 | minor_iterations = atoi(opt->value); |
michael@0 | 287 | break; |
michael@0 | 288 | case 'p': /* default port */ |
michael@0 | 289 | default_port = atoi(opt->value); |
michael@0 | 290 | break; |
michael@0 | 291 | default: |
michael@0 | 292 | break; |
michael@0 | 293 | } |
michael@0 | 294 | } |
michael@0 | 295 | PL_DestroyOptState(opt); |
michael@0 | 296 | PR_STDIO_INIT(); |
michael@0 | 297 | |
michael@0 | 298 | logFile = PR_GetSpecialFD(PR_StandardError); |
michael@0 | 299 | |
michael@0 | 300 | identity = PR_GetUniqueIdentity("Dummy"); |
michael@0 | 301 | stubMethods = PR_GetDefaultIOMethods(); |
michael@0 | 302 | |
michael@0 | 303 | /* |
michael@0 | 304 | ** The protocol we're going to implement is one where in order to initiate |
michael@0 | 305 | ** a send, the sender must first solicit permission. Therefore, every |
michael@0 | 306 | ** send is really a send - receive - send sequence. |
michael@0 | 307 | */ |
michael@0 | 308 | myMethods = *stubMethods; /* first get the entire batch */ |
michael@0 | 309 | myMethods.recv = MyRecv; /* then override the ones we care about */ |
michael@0 | 310 | myMethods.send = MySend; /* then override the ones we care about */ |
michael@0 | 311 | |
michael@0 | 312 | if (NULL == server_name) |
michael@0 | 313 | rv = PR_InitializeNetAddr( |
michael@0 | 314 | PR_IpAddrLoopback, default_port, &server_address); |
michael@0 | 315 | else |
michael@0 | 316 | { |
michael@0 | 317 | rv = PR_StringToNetAddr(server_name, &server_address); |
michael@0 | 318 | PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 319 | rv = PR_InitializeNetAddr( |
michael@0 | 320 | PR_IpAddrNull, default_port, &server_address); |
michael@0 | 321 | } |
michael@0 | 322 | PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 323 | |
michael@0 | 324 | /* one type w/o layering */ |
michael@0 | 325 | |
michael@0 | 326 | mits = minor_iterations; |
michael@0 | 327 | while (major_iterations-- > 0) |
michael@0 | 328 | { |
michael@0 | 329 | if (verbosity > silent) |
michael@0 | 330 | PR_fprintf(logFile, "Beginning non-layered test\n"); |
michael@0 | 331 | client = PR_NewTCPSocket(); PR_ASSERT(NULL != client); |
michael@0 | 332 | service = PR_NewTCPSocket(); PR_ASSERT(NULL != service); |
michael@0 | 333 | rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address); |
michael@0 | 334 | PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 335 | rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 336 | rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 337 | |
michael@0 | 338 | minor_iterations = mits; |
michael@0 | 339 | server_thread = PR_CreateThread( |
michael@0 | 340 | PR_USER_THREAD, Server, service, |
michael@0 | 341 | PR_PRIORITY_HIGH, thread_scope, |
michael@0 | 342 | PR_JOINABLE_THREAD, 16 * 1024); |
michael@0 | 343 | PR_ASSERT(NULL != server_thread); |
michael@0 | 344 | |
michael@0 | 345 | client_thread = PR_CreateThread( |
michael@0 | 346 | PR_USER_THREAD, Client, client, |
michael@0 | 347 | PR_PRIORITY_NORMAL, thread_scope, |
michael@0 | 348 | PR_JOINABLE_THREAD, 16 * 1024); |
michael@0 | 349 | PR_ASSERT(NULL != client_thread); |
michael@0 | 350 | |
michael@0 | 351 | rv = PR_JoinThread(client_thread); |
michael@0 | 352 | PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 353 | rv = PR_JoinThread(server_thread); |
michael@0 | 354 | PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 355 | |
michael@0 | 356 | rv = PR_Close(client); PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 357 | rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 358 | if (verbosity > silent) |
michael@0 | 359 | PR_fprintf(logFile, "Ending non-layered test\n"); |
michael@0 | 360 | |
michael@0 | 361 | /* with layering */ |
michael@0 | 362 | if (verbosity > silent) |
michael@0 | 363 | PR_fprintf(logFile, "Beginning layered test\n"); |
michael@0 | 364 | client = PR_NewTCPSocket(); PR_ASSERT(NULL != client); |
michael@0 | 365 | PushLayer(client); |
michael@0 | 366 | service = PR_NewTCPSocket(); PR_ASSERT(NULL != service); |
michael@0 | 367 | PushLayer(service); |
michael@0 | 368 | rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address); |
michael@0 | 369 | PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 370 | rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 371 | rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 372 | |
michael@0 | 373 | minor_iterations = mits; |
michael@0 | 374 | server_thread = PR_CreateThread( |
michael@0 | 375 | PR_USER_THREAD, Server, service, |
michael@0 | 376 | PR_PRIORITY_HIGH, thread_scope, |
michael@0 | 377 | PR_JOINABLE_THREAD, 16 * 1024); |
michael@0 | 378 | PR_ASSERT(NULL != server_thread); |
michael@0 | 379 | |
michael@0 | 380 | client_thread = PR_CreateThread( |
michael@0 | 381 | PR_USER_THREAD, Client, client, |
michael@0 | 382 | PR_PRIORITY_NORMAL, thread_scope, |
michael@0 | 383 | PR_JOINABLE_THREAD, 16 * 1024); |
michael@0 | 384 | PR_ASSERT(NULL != client_thread); |
michael@0 | 385 | |
michael@0 | 386 | rv = PR_JoinThread(client_thread); |
michael@0 | 387 | PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 388 | rv = PR_JoinThread(server_thread); |
michael@0 | 389 | PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 390 | |
michael@0 | 391 | rv = PR_Close(client); PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 392 | rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 393 | /* with layering, using new style stack */ |
michael@0 | 394 | if (verbosity > silent) |
michael@0 | 395 | PR_fprintf(logFile, |
michael@0 | 396 | "Beginning layered test with new style stack\n"); |
michael@0 | 397 | client = PR_NewTCPSocket(); PR_ASSERT(NULL != client); |
michael@0 | 398 | client_stack = PR_CreateIOLayer(client); |
michael@0 | 399 | PushNewLayers(client_stack); |
michael@0 | 400 | service = PR_NewTCPSocket(); PR_ASSERT(NULL != service); |
michael@0 | 401 | service_stack = PR_CreateIOLayer(service); |
michael@0 | 402 | PushNewLayers(service_stack); |
michael@0 | 403 | rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address); |
michael@0 | 404 | PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 405 | rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 406 | rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 407 | |
michael@0 | 408 | minor_iterations = mits; |
michael@0 | 409 | server_thread = PR_CreateThread( |
michael@0 | 410 | PR_USER_THREAD, Server, service_stack, |
michael@0 | 411 | PR_PRIORITY_HIGH, thread_scope, |
michael@0 | 412 | PR_JOINABLE_THREAD, 16 * 1024); |
michael@0 | 413 | PR_ASSERT(NULL != server_thread); |
michael@0 | 414 | |
michael@0 | 415 | client_thread = PR_CreateThread( |
michael@0 | 416 | PR_USER_THREAD, Client, client_stack, |
michael@0 | 417 | PR_PRIORITY_NORMAL, thread_scope, |
michael@0 | 418 | PR_JOINABLE_THREAD, 16 * 1024); |
michael@0 | 419 | PR_ASSERT(NULL != client_thread); |
michael@0 | 420 | |
michael@0 | 421 | rv = PR_JoinThread(client_thread); |
michael@0 | 422 | PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 423 | rv = PR_JoinThread(server_thread); |
michael@0 | 424 | PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 425 | |
michael@0 | 426 | rv = PR_Close(client_stack); PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 427 | rv = PR_Close(service_stack); PR_ASSERT(PR_SUCCESS == rv); |
michael@0 | 428 | if (verbosity > silent) |
michael@0 | 429 | PR_fprintf(logFile, "Ending layered test\n"); |
michael@0 | 430 | } |
michael@0 | 431 | return 0; |
michael@0 | 432 | } /* main */ |
michael@0 | 433 | |
michael@0 | 434 | /* layer.c */ |