static void AcceptThread(void *arg) { PRIntn bytesRead; char dataBuf[ACCEPT_READ_BUFSIZE]; PRFileDesc *arSock; PRNetAddr *arAddr; bytesRead = PR_AcceptRead( listenSock, &arSock, &arAddr, dataBuf, ACCEPT_READ_DATASIZE, PR_SecondsToInterval(1)); if ( bytesRead == -1 && PR_GetError() == PR_IO_TIMEOUT_ERROR ) if ( debug ) printf("AcceptRead timed out\n"); else if ( debug ) printf("Oops! read: %d, error: %d\n", bytesRead, PR_GetError()); while( state != AllDone ) { PR_Lock( ml ); while( state != RunAcceptRead ) PR_WaitCondVar( cv, PR_INTERVAL_NO_TIMEOUT ); if ( ++iCounter >= jitter ) state = AllDone; else state = RunJitter; if ( verbose ) printf("."); PR_NotifyCondVar( cv ); PR_Unlock( ml ); PR_Write( file1, ".", 1 ); } return; } /* end AcceptThread() */
static void AcceptingThread(void *arg) { PRStatus rv; PRInt32 bytes; PRSize buf_size = BUF_SIZE; PRUint8 buf[BUF_SIZE + (2 * sizeof(PRNetAddr)) + 32]; PRNetAddr *accept_addr, *listen_addr = (PRNetAddr*)arg; PRFileDesc *accept_sock, *listen_sock = PR_NewTCPSocket(); PRFileDesc *layer; PRSocketOptionData sock_opt; if (NULL == listen_sock) { PL_FPrintError(err_out, "PR_NewTCPSocket (server) failed"); PR_ProcessExit(1); } layer = PR_CreateIOLayerStub(emu_layer_ident, &emu_layer_methods); if (NULL == layer) { PL_FPrintError(err_out, "PR_CreateIOLayerStub (server) failed"); PR_ProcessExit(1); } if (PR_PushIOLayer(listen_sock, PR_TOP_IO_LAYER, layer) == PR_FAILURE) { PL_FPrintError(err_out, "PR_PushIOLayer (server) failed"); PR_ProcessExit(1); } sock_opt.option = PR_SockOpt_Reuseaddr; sock_opt.value.reuse_addr = PR_TRUE; rv = PR_SetSocketOption(listen_sock, &sock_opt); if (PR_FAILURE == rv) { PL_FPrintError(err_out, "PR_SetSocketOption (server) failed"); PR_ProcessExit(1); } rv = PR_Bind(listen_sock, listen_addr); if (PR_FAILURE == rv) { PL_FPrintError(err_out, "PR_Bind (server) failed"); PR_ProcessExit(1); } rv = PR_Listen(listen_sock, 10); if (PR_FAILURE == rv) { PL_FPrintError(err_out, "PR_Listen (server) failed"); PR_ProcessExit(1); } bytes = PR_AcceptRead( listen_sock, &accept_sock, &accept_addr, buf, buf_size, accept_timeout); if (-1 == bytes) PL_FPrintError(err_out, "PR_AcceptRead (server) failed"); else { PrintAddress(accept_addr); PR_fprintf( std_out, "(Server) read [0x%p..0x%p) %s\n", buf, &buf[BUF_SIZE], buf); bytes = PR_Write(accept_sock, buf, bytes); rv = PR_Shutdown(accept_sock, PR_SHUTDOWN_BOTH); if (PR_FAILURE == rv) PL_FPrintError(err_out, "PR_Shutdown (server) failed"); } if (-1 != bytes) { rv = PR_Close(accept_sock); if (PR_FAILURE == rv) PL_FPrintError(err_out, "PR_Close (server) failed"); } rv = PR_Close(listen_sock); if (PR_FAILURE == rv) PL_FPrintError(err_out, "PR_Close (server) failed"); } /* AcceptingThread */
void WorkerThreadFunc(void *_listenSock) { PRFileDesc *listenSock = (PRFileDesc *)_listenSock; PRInt32 bytesRead; PRInt32 bytesWritten; char *dataBuf; char *sendBuf; if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n", _client_data+(2*sizeof(PRNetAddr))+32, _client_data, (2*sizeof(PRNetAddr))+32); dataBuf = (char *)PR_MALLOC(_client_data + 2*sizeof(PRNetAddr) + 32); if (!dataBuf) if (debug_mode) printf("\tServer could not malloc space!?\n"); sendBuf = (char *)PR_MALLOC(_server_data *sizeof(char)); if (!sendBuf) if (debug_mode) printf("\tServer could not malloc space!?\n"); if (debug_mode) DPRINTF("\tServer worker thread running\n"); while(1) { PRInt32 bytesToRead = _client_data; PRInt32 bytesToWrite = _server_data; PRFileDesc *newSock; PRNetAddr *rAddr; PRInt32 loops = 0; loops++; if (debug_mode) DPRINTF("\tServer thread going into accept\n"); bytesRead = PR_AcceptRead(listenSock, &newSock, &rAddr, dataBuf, bytesToRead, PR_INTERVAL_NO_TIMEOUT); if (bytesRead < 0) { if (debug_mode) printf("\tServer error in accept (%d)\n", bytesRead); continue; } if (debug_mode) DPRINTF("\tServer accepted connection (%d bytes)\n", bytesRead); PR_AtomicIncrement(&workerThreadsBusy); #ifdef SYMBIAN if (workerThreadsBusy == workerThreads && workerThreads<1) { #else if (workerThreadsBusy == workerThreads) { #endif PR_Lock(workerThreadsLock); if (workerThreadsBusy == workerThreads) { PRThread *WorkerThread; WorkerThread = PR_CreateThread( PR_SYSTEM_THREAD, WorkerThreadFunc, listenSock, PR_PRIORITY_NORMAL, ServerScope, PR_UNJOINABLE_THREAD, THREAD_STACKSIZE); if (!WorkerThread) { if (debug_mode) printf("Error creating client thread %d\n", workerThreads); } else { PR_AtomicIncrement(&workerThreads); if (debug_mode) DPRINTF("\tServer creates worker (%d)\n", workerThreads); } } PR_Unlock(workerThreadsLock); } bytesToRead -= bytesRead; while (bytesToRead) { bytesRead = PR_Recv(newSock, dataBuf, bytesToRead, 0, PR_INTERVAL_NO_TIMEOUT); if (bytesRead < 0) { if (debug_mode) printf("\tServer error receiving data (%d)\n", bytesRead); continue; } if (debug_mode) DPRINTF("\tServer received %d bytes\n", bytesRead); } bytesWritten = PR_Send(newSock, sendBuf, bytesToWrite, 0, PR_INTERVAL_NO_TIMEOUT); if (bytesWritten != _server_data) { if (debug_mode) printf("\tError sending data to client (%d, %d)\n", bytesWritten, PR_GetOSError()); } else { if (debug_mode) DPRINTF("\tServer sent %d bytes\n", bytesWritten); } PR_Close(newSock); PR_AtomicDecrement(&workerThreadsBusy); } } PRFileDesc * ServerSetup(void) { PRFileDesc *listenSocket; PRSocketOptionData sockOpt; PRNetAddr serverAddr; PRThread *WorkerThread; if ( (listenSocket = PR_NewTCPSocket()) == NULL) { if (debug_mode) printf("\tServer error creating listen socket\n"); else failed_already=1; return NULL; } sockOpt.option = PR_SockOpt_Reuseaddr; sockOpt.value.reuse_addr = PR_TRUE; if ( PR_SetSocketOption(listenSocket, &sockOpt) == PR_FAILURE) { if (debug_mode) printf("\tServer error setting socket option: OS error %d\n", PR_GetOSError()); else failed_already=1; PR_Close(listenSocket); return NULL; } memset(&serverAddr, 0, sizeof(PRNetAddr)); serverAddr.inet.family = PR_AF_INET; serverAddr.inet.port = PR_htons(PORT); serverAddr.inet.ip = PR_htonl(PR_INADDR_ANY); if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) { if (debug_mode) printf("\tServer error binding to server address: OS error %d\n", PR_GetOSError()); else failed_already=1; PR_Close(listenSocket); return NULL; } if ( PR_Listen(listenSocket, 128) == PR_FAILURE) { if (debug_mode) printf("\tServer error listening to server socket\n"); else failed_already=1; PR_Close(listenSocket); return NULL; } /* Create Clients */ workerThreads = 0; workerThreadsBusy = 0; workerThreadsLock = PR_NewLock(); WorkerThread = PR_CreateThread( PR_SYSTEM_THREAD, WorkerThreadFunc, listenSocket, PR_PRIORITY_NORMAL, ServerScope, PR_UNJOINABLE_THREAD, THREAD_STACKSIZE); if (!WorkerThread) { if (debug_mode) printf("error creating working thread\n"); PR_Close(listenSocket); return NULL; } PR_AtomicIncrement(&workerThreads); if (debug_mode) DPRINTF("\tServer created primordial worker thread\n"); return listenSocket; }
static void RunTest(PRInt32 acceptType, PRInt32 clientAction) { /* First bind to the socket */ listenSock = PR_NewTCPSocket(); if (!listenSock) { if (!debug_mode) failed_already=1; else printf("unable to create listen socket\n"); return; } listenAddr.inet.family = AF_INET; listenAddr.inet.port = PR_htons(BASE_PORT); listenAddr.inet.ip = PR_htonl(INADDR_ANY); rv = PR_Bind(listenSock, &listenAddr); if (rv == PR_FAILURE) { if (!debug_mode) failed_already=1; else printf("unable to bind\n"); return; } rv = PR_Listen(listenSock, 100); if (rv == PR_FAILURE) { if (!debug_mode) failed_already=1; else printf("unable to listen\n"); return; } clientCommand = clientAction; clientThread = PR_CreateThread(PR_USER_THREAD, ClientThread, (void *)&clientCommand, PR_PRIORITY_NORMAL, thread_scope, PR_JOINABLE_THREAD, 0); if (!clientThread) { if (!debug_mode) failed_already=1; else printf("error creating client thread\n"); return; } iterations = count; for (;iterations--;) { switch (acceptType) { case ACCEPT_NORMAL: clientSock = PR_Accept(listenSock, &clientAddr, timeoutTime); switch(clientAction) { case CLIENT_TIMEOUT_ACCEPT: TEST_ASSERT(clientSock == 0); TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); break; case CLIENT_NORMAL: TEST_ASSERT(clientSock); bytesRead = PR_Recv(clientSock, buf, CLIENT_DATA, 0, timeoutTime); TEST_ASSERT(bytesRead == CLIENT_DATA); break; case CLIENT_TIMEOUT_SEND: TEST_ASSERT(clientSock); bytesRead = PR_Recv(clientSock, buf, CLIENT_DATA, 0, timeoutTime); TEST_ASSERT(bytesRead == -1); TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); break; } break; case ACCEPT_READ: status = PR_AcceptRead(listenSock, &clientSock, &raddr, buf, CLIENT_DATA, timeoutTime); switch(clientAction) { case CLIENT_TIMEOUT_ACCEPT: /* Invalid test case */ TEST_ASSERT(0); break; case CLIENT_NORMAL: TEST_ASSERT(clientSock); TEST_ASSERT(status == CLIENT_DATA); break; case CLIENT_TIMEOUT_SEND: TEST_ASSERT(status == -1); TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); break; } break; #ifdef WINNT case ACCEPT_FAST: clientSock = PR_NTFast_Accept(listenSock, &clientAddr, timeoutTime); switch(clientAction) { case CLIENT_TIMEOUT_ACCEPT: TEST_ASSERT(clientSock == 0); if (debug_mode) printf("PR_GetError is %ld\n", PR_GetError()); TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); break; case CLIENT_NORMAL: TEST_ASSERT(clientSock); bytesRead = PR_Recv(clientSock, buf, CLIENT_DATA, 0, timeoutTime); TEST_ASSERT(bytesRead == CLIENT_DATA); break; case CLIENT_TIMEOUT_SEND: TEST_ASSERT(clientSock); bytesRead = PR_Recv(clientSock, buf, CLIENT_DATA, 0, timeoutTime); TEST_ASSERT(bytesRead == -1); TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); break; } break; break; case ACCEPT_READ_FAST: status = PR_NTFast_AcceptRead(listenSock, &clientSock, &raddr, buf, 4096, timeoutTime); switch(clientAction) { case CLIENT_TIMEOUT_ACCEPT: /* Invalid test case */ TEST_ASSERT(0); break; case CLIENT_NORMAL: TEST_ASSERT(clientSock); TEST_ASSERT(status == CLIENT_DATA); break; case CLIENT_TIMEOUT_SEND: TEST_ASSERT(clientSock); TEST_ASSERT(status == -1); TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); break; } break; case ACCEPT_READ_FAST_CB: status = PR_NTFast_AcceptRead_WithTimeoutCallback( listenSock, &clientSock, &raddr, buf, 4096, timeoutTime, timeout_callback, (void *)CALLBACK_MAGIC); switch(clientAction) { case CLIENT_TIMEOUT_ACCEPT: /* Invalid test case */ TEST_ASSERT(0); break; case CLIENT_NORMAL: TEST_ASSERT(clientSock); TEST_ASSERT(status == CLIENT_DATA); break; case CLIENT_TIMEOUT_SEND: if (debug_mode) printf("clientSock = 0x%8.8lx\n", clientSock); TEST_ASSERT(clientSock); TEST_ASSERT(status == -1); TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); break; } break; #endif } if (clientSock != NULL) { PR_Close(clientSock); clientSock = NULL; } } PR_Close(listenSock); PR_JoinThread(clientThread); }
void WorkerThreadFunc(void *_listenSock) { PRFileDesc *listenSock = (PRFileDesc *)_listenSock; PRInt32 bytesRead; PRInt32 bytesWritten; char *dataBuf; char *sendBuf; if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n", _client_data+(2*sizeof(PRNetAddr))+32, _client_data, (2*sizeof(PRNetAddr))+32); dataBuf = (char *)PR_MALLOC(_client_data + 2*sizeof(PRNetAddr) + 32); if (!dataBuf) if (debug_mode) printf("\tServer could not malloc space!?\n"); sendBuf = (char *)PR_MALLOC(_server_data *sizeof(char)); if (!sendBuf) if (debug_mode) printf("\tServer could not malloc space!?\n"); if (debug_mode) DPRINTF("\tServer worker thread running\n"); while(1) { PRInt32 bytesToRead = _client_data; PRInt32 bytesToWrite = _server_data; PRFileDesc *newSock; PRNetAddr *rAddr; PRInt32 loops = 0; loops++; if (debug_mode) DPRINTF("\tServer thread going into accept\n"); bytesRead = PR_AcceptRead(listenSock, &newSock, &rAddr, dataBuf, bytesToRead, PR_INTERVAL_NO_TIMEOUT); if (bytesRead < 0) { if (debug_mode) printf("\tServer error in accept (%d)\n", bytesRead); continue; } if (debug_mode) DPRINTF("\tServer accepted connection (%d bytes)\n", bytesRead); PR_AtomicIncrement(&workerThreadsBusy); if (workerThreadsBusy == workerThreads) { PR_Lock(workerThreadsLock); if (workerThreadsBusy == workerThreads) { PRThread *WorkerThread; WorkerThread = PR_CreateThread( PR_SYSTEM_THREAD, WorkerThreadFunc, listenSock, PR_PRIORITY_NORMAL, ServerScope, PR_UNJOINABLE_THREAD, THREAD_STACKSIZE); if (!WorkerThread) { if (debug_mode) printf("Error creating client thread %d\n", workerThreads); } else { PR_AtomicIncrement(&workerThreads); if (debug_mode) DPRINTF("\tServer creates worker (%d)\n", workerThreads); } } PR_Unlock(workerThreadsLock); } bytesToRead -= bytesRead; while (bytesToRead) { bytesRead = PR_Recv(newSock, dataBuf, bytesToRead, 0, PR_INTERVAL_NO_TIMEOUT); if (bytesRead < 0) { if (debug_mode) printf("\tServer error receiving data (%d)\n", bytesRead); continue; } if (debug_mode) DPRINTF("\tServer received %d bytes\n", bytesRead); } bytesWritten = PR_Send(newSock, sendBuf, bytesToWrite, 0, PR_INTERVAL_NO_TIMEOUT); if (bytesWritten != _server_data) { if (debug_mode) printf("\tError sending data to client (%d, %d)\n", bytesWritten, PR_GetOSError()); } else { if (debug_mode) DPRINTF("\tServer sent %d bytes\n", bytesWritten); } PR_Close(newSock); PR_AtomicDecrement(&workerThreadsBusy); } }
static void RunTest(PRInt32 acceptType, PRInt32 clientAction) { int i; /* First bind to the socket */ listenSock = PR_NewTCPSocket(); if (!listenSock) { failed_already=1; if (debug_mode) PR_fprintf(output, "unable to create listen socket\n"); return; } memset(&listenAddr, 0 , sizeof(listenAddr)); listenAddr.inet.family = PR_AF_INET; listenAddr.inet.port = PR_htons(BASE_PORT); listenAddr.inet.ip = PR_htonl(PR_INADDR_ANY); /* * try a few times to bind server's address, if addresses are in * use */ i = 0; while (PR_Bind(listenSock, &listenAddr) == PR_FAILURE) { if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) { listenAddr.inet.port += 2; if (i++ < SERVER_MAX_BIND_COUNT) continue; } failed_already=1; if (debug_mode) PR_fprintf(output,"accept: ERROR - PR_Bind failed\n"); return; } rv = PR_Listen(listenSock, 100); if (rv == PR_FAILURE) { failed_already=1; if (debug_mode) PR_fprintf(output, "unable to listen\n"); return; } clientCommand = clientAction; clientThread = PR_CreateThread(PR_USER_THREAD, ClientThread, (void *)&clientCommand, PR_PRIORITY_NORMAL, thread_scope, PR_JOINABLE_THREAD, 0); if (!clientThread) { failed_already=1; if (debug_mode) PR_fprintf(output, "error creating client thread\n"); return; } iterations = count; for (;iterations--;) { switch (acceptType) { case ACCEPT_NORMAL: clientSock = PR_Accept(listenSock, &clientAddr, timeoutTime); switch(clientAction) { case CLIENT_TIMEOUT_ACCEPT: TEST_ASSERT(clientSock == 0); TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); break; case CLIENT_NORMAL: TEST_ASSERT(clientSock); bytesRead = PR_Recv(clientSock, buf, CLIENT_DATA, 0, timeoutTime); TEST_ASSERT(bytesRead == CLIENT_DATA); break; case CLIENT_TIMEOUT_SEND: TEST_ASSERT(clientSock); bytesRead = PR_Recv(clientSock, buf, CLIENT_DATA, 0, timeoutTime); TEST_ASSERT(bytesRead == -1); TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); break; } break; case ACCEPT_READ: status = PR_AcceptRead(listenSock, &clientSock, &raddr, buf, CLIENT_DATA, timeoutTime); switch(clientAction) { case CLIENT_TIMEOUT_ACCEPT: /* Invalid test case */ TEST_ASSERT(0); break; case CLIENT_NORMAL: TEST_ASSERT(clientSock); TEST_ASSERT(status == CLIENT_DATA); break; case CLIENT_TIMEOUT_SEND: TEST_ASSERT(status == -1); TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); break; } break; #ifdef WINNT case ACCEPT_FAST: clientSock = PR_NTFast_Accept(listenSock, &clientAddr, timeoutTime); switch(clientAction) { case CLIENT_TIMEOUT_ACCEPT: TEST_ASSERT(clientSock == 0); if (debug_mode) PR_fprintf(output, "PR_GetError is %ld\n", PR_GetError()); TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); break; case CLIENT_NORMAL: TEST_ASSERT(clientSock); bytesRead = PR_Recv(clientSock, buf, CLIENT_DATA, 0, timeoutTime); TEST_ASSERT(bytesRead == CLIENT_DATA); break; case CLIENT_TIMEOUT_SEND: TEST_ASSERT(clientSock); bytesRead = PR_Recv(clientSock, buf, CLIENT_DATA, 0, timeoutTime); TEST_ASSERT(bytesRead == -1); TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); break; } break; break; case ACCEPT_READ_FAST: status = PR_NTFast_AcceptRead(listenSock, &clientSock, &raddr, buf, 4096, timeoutTime); switch(clientAction) { case CLIENT_TIMEOUT_ACCEPT: /* Invalid test case */ TEST_ASSERT(0); break; case CLIENT_NORMAL: TEST_ASSERT(clientSock); TEST_ASSERT(status == CLIENT_DATA); break; case CLIENT_TIMEOUT_SEND: TEST_ASSERT(clientSock == NULL); TEST_ASSERT(status == -1); TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); break; } break; case ACCEPT_READ_FAST_CB: status = PR_NTFast_AcceptRead_WithTimeoutCallback( listenSock, &clientSock, &raddr, buf, 4096, timeoutTime, timeout_callback, (void *)CALLBACK_MAGIC); switch(clientAction) { case CLIENT_TIMEOUT_ACCEPT: /* Invalid test case */ TEST_ASSERT(0); break; case CLIENT_NORMAL: TEST_ASSERT(clientSock); TEST_ASSERT(status == CLIENT_DATA); break; case CLIENT_TIMEOUT_SEND: if (debug_mode) PR_fprintf(output, "clientSock = 0x%8.8lx\n", clientSock); TEST_ASSERT(clientSock == NULL); TEST_ASSERT(status == -1); TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); break; } break; #endif } if (clientSock != NULL) { PR_Close(clientSock); clientSock = NULL; } } PR_Close(listenSock); PR_JoinThread(clientThread); }