📄 servr_uu.c
字号:
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;}/* The main server loop */voidServerThreadFunc(void *unused){ PRFileDesc *listenSocket; /* Do setup */ listenSocket = ServerSetup(); if (!listenSocket) { SetServerState(SERVER, SERVER_STATE_DEAD); } else { if (debug_mode) DPRINTF("\tServer up\n"); /* Tell clients they can start now. */ SetServerState(SERVER, SERVER_STATE_READY); /* Now wait for server death signal */ WaitServerState(SERVER, SERVER_STATE_DYING); /* Cleanup */ SetServerState(SERVER, SERVER_STATE_DEAD); }}/* --- Client Functions ------------------------------------------- */PRInt32 numRequests;PRInt32 numClients;PRMonitor *clientMonitor;voidClientThreadFunc(void *unused){ PRNetAddr serverAddr; PRFileDesc *clientSocket; char *sendBuf; char *recvBuf; PRInt32 rv; PRInt32 bytesNeeded; sendBuf = (char *)PR_MALLOC(_client_data * sizeof(char)); if (!sendBuf) if (debug_mode) printf("\tClient could not malloc space!?\n"); recvBuf = (char *)PR_MALLOC(_server_data * sizeof(char)); if (!recvBuf) if (debug_mode) printf("\tClient could not malloc space!?\n"); memset(&serverAddr, 0, sizeof(PRNetAddr)); serverAddr.inet.family = PR_AF_INET; serverAddr.inet.port = PR_htons(PORT); serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); while(numRequests > 0) { if ( (numRequests % 10) == 0 ) if (debug_mode) printf("."); if (debug_mode) DPRINTF("\tClient starting request %d\n", numRequests); clientSocket = PR_NewTCPSocket(); if (!clientSocket) { if (debug_mode) printf("Client error creating socket: OS error %d\n", PR_GetOSError()); continue; } if (debug_mode) DPRINTF("\tClient connecting\n"); rv = PR_Connect(clientSocket, &serverAddr, PR_INTERVAL_NO_TIMEOUT); if (!clientSocket) { if (debug_mode) printf("\tClient error connecting\n"); continue; } if (debug_mode) DPRINTF("\tClient connected\n"); rv = PR_Send(clientSocket, sendBuf, _client_data, 0, PR_INTERVAL_NO_TIMEOUT); if (rv != _client_data) { if (debug_mode) printf("Client error sending data (%d)\n", rv); PR_Close(clientSocket); continue; } if (debug_mode) DPRINTF("\tClient sent %d bytes\n", rv); bytesNeeded = _server_data; while(bytesNeeded) { rv = PR_Recv(clientSocket, recvBuf, bytesNeeded, 0, PR_INTERVAL_NO_TIMEOUT); if (rv <= 0) { if (debug_mode) printf("Client error receiving data (%d) (%d/%d)\n", rv, (_server_data - bytesNeeded), _server_data); break; } if (debug_mode) DPRINTF("\tClient received %d bytes; need %d more\n", rv, bytesNeeded - rv); bytesNeeded -= rv; } PR_Close(clientSocket); PR_AtomicDecrement(&numRequests); } PR_EnterMonitor(clientMonitor); --numClients; PR_Notify(clientMonitor); PR_ExitMonitor(clientMonitor); PR_DELETE(sendBuf); PR_DELETE(recvBuf);}voidRunClients(void){ PRInt32 index; numRequests = _iterations; numClients = _clients; clientMonitor = PR_NewMonitor(); for (index=0; index<_clients; index++) { PRThread *clientThread; clientThread = PR_CreateThread( PR_USER_THREAD, ClientThreadFunc, NULL, PR_PRIORITY_NORMAL, ClientScope, PR_UNJOINABLE_THREAD, STACKSIZE); if (!clientThread) { if (debug_mode) printf("\terror creating client thread %d\n", index); } else if (debug_mode) DPRINTF("\tMain created client %d/%d\n", index+1, _clients); } PR_EnterMonitor(clientMonitor); while(numClients) PR_Wait(clientMonitor, PR_INTERVAL_NO_TIMEOUT); PR_ExitMonitor(clientMonitor);}/* --- Main Function ---------------------------------------------- */staticvoid do_work(){ PRThread *ServerThread; PRInt32 state; SetServerState(MAIN, SERVER_STATE_STARTUP); ServerThread = PR_CreateThread( PR_USER_THREAD, ServerThreadFunc, NULL, PR_PRIORITY_NORMAL, ServerScope, PR_JOINABLE_THREAD, STACKSIZE); if (!ServerThread) { if (debug_mode) printf("error creating main server thread\n"); return; } /* Wait for server to be ready */ state = WaitServerState(MAIN, SERVER_STATE_READY|SERVER_STATE_DEAD); if (!(state & SERVER_STATE_DEAD)) { /* Run Test Clients */ RunClients(); /* Send death signal to server */ SetServerState(MAIN, SERVER_STATE_DYING); } PR_JoinThread(ServerThread);}static void do_workUU(void){ ServerScope = PR_LOCAL_THREAD; ClientScope = PR_LOCAL_THREAD; do_work();}static void Measure(void (*func)(void), const char *msg){ PRIntervalTime start, stop; double d; start = PR_IntervalNow(); (*func)(); stop = PR_IntervalNow(); d = (double)PR_IntervalToMicroseconds(stop - start); if (debug_mode) printf("\n%40s: %6.2f usec\n", msg, d / _iterations);}main(int argc, char **argv){ /* The command line argument: -d is used to determine if the test is being run in debug mode. The regress tool requires only one line output:PASS or FAIL. All of the printfs associated with this test has been handled with a if (debug_mode) test. Usage: test_name -d */ PLOptStatus os; PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { if (PL_OPT_BAD == os) continue; switch (opt->option) { case 'd': /* debug mode */ debug_mode = 1; break; default: break; } } PL_DestroyOptState(opt); /* main test */ if (debug_mode) { printf("Enter number of iterations: \n"); scanf("%d", &_iterations); printf("Enter number of clients : \n"); scanf("%d", &_clients); printf("Enter size of client data : \n"); scanf("%d", &_client_data); printf("Enter size of server data : \n"); scanf("%d", &_server_data); } else { _iterations = 7; _clients = 7; _client_data = 100; _server_data = 100; } if (debug_mode) { printf("\n\n%d iterations with %d client threads.\n", _iterations, _clients); printf("Sending %d bytes of client data and %d bytes of server data\n", _client_data, _server_data); } PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); PR_STDIO_INIT(); PR_SetThreadRecycleMode(64); ServerStateCVLock = PR_NewLock(); ServerStateCV = PR_NewCondVar(ServerStateCVLock); Measure(do_workUU, "server loop user/user"); PR_Cleanup(); if(failed_already) return 1; else return 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -