void PR_CALLBACK Level_1_Thread(void *arg) { PRUint32 tmp = (PRUint32)arg; PRThreadScope scope = (PRThreadScope) tmp; PRThread *thr; thr = PR_CreateThreadGCAble(PR_USER_THREAD, Level_2_Thread, NULL, PR_PRIORITY_HIGH, scope, PR_JOINABLE_THREAD, 0); if (!thr) { printf("Could not create thread!\n"); } else { printf("Level_1_Thread[0x%lx] created %15s thread 0x%lx\n", PR_GetCurrentThread(), (scope == PR_GLOBAL_THREAD) ? "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD", thr); PR_JoinThread(thr); } PR_EnterMonitor(mon); alive--; PR_Notify(mon); PR_ExitMonitor(mon); printf("Thread[0x%lx] exiting\n",PR_GetCurrentThread()); }
void nsToolkit::RunPump(void* arg) { int32 code; char portname[64]; ThreadInterfaceData id; #ifdef DEBUG printf("TK-RunPump\n"); #endif ThreadInitInfo *info = (ThreadInitInfo*)arg; PR_EnterMonitor(info->monitor); gThreadState = PR_TRUE; PR_Notify(info->monitor); PR_ExitMonitor(info->monitor); delete info; // system wide unique names PR_snprintf(portname, sizeof(portname), "event%lx", (long unsigned) PR_GetCurrentThread()); port_id event = create_port(200, portname); while(read_port_etc(event, &code, &id, sizeof(id), B_TIMEOUT, 1000) >= 0) { MethodInfo *mInfo = (MethodInfo *)id.data; mInfo->Invoke(); if(id.waitingThread != 0) resume_thread(id.waitingThread); delete mInfo; } }
void nsDNSSyncRequest::OnLookupComplete(nsHostResolver *resolver, nsHostRecord *hostRecord, nsresult status) { // store results, and wake up nsDNSService::Resolve to process results. PR_EnterMonitor(mMonitor); mDone = PR_TRUE; mStatus = status; mHostRecord = hostRecord; PR_Notify(mMonitor); PR_ExitMonitor(mMonitor); }
static void PR_CALLBACK CXWriter(void *arg) { CircBuf *cbp = (CircBuf *)arg; PRInt32 i, n; n = count / 2; for (i = 0; i < n; i++) PutCBData(cbp, (void *)i); PR_EnterMonitor(mon); --alive; PR_Notify(mon); PR_ExitMonitor(mon); }
static void PR_CALLBACK T3Mon(void *arg) { PRStatus rv; MonShared *shared = (MonShared*)arg; PR_EnterMonitor(shared->o2); LogNow("T3 waiting 5 seconds on o2", PR_SUCCESS); rv = PR_Wait(shared->o2, PR_SecondsToInterval(5)); if (PR_SUCCESS == rv) LogNow("T3 resuming on o2", rv); else LogNow("T3 wait failed on o2", rv); rv = PR_Notify(shared->o2); LogNow("T3 notify on o2", rv); PR_ExitMonitor(shared->o2); } /* T3Mon */
void nsToolkit::RunPump(void* arg) { int32 code; char portname[64]; ThreadInterfaceData id; ThreadInitInfo *info = (ThreadInitInfo*)arg; PR_EnterMonitor(info->monitor); gThreadState = PR_TRUE; PR_Notify(info->monitor); PR_ExitMonitor(info->monitor); delete info; // system wide unique names PR_snprintf(portname, sizeof(portname), "event%lx", (long unsigned) PR_GetCurrentThread()); port_id event = create_port(100, portname); while(read_port(event, &code, &id, sizeof(id)) >= 0) { switch(code) { case WM_CALLMETHOD : { MethodInfo *mInfo = (MethodInfo *)id.data; mInfo->Invoke(); if(id.waitingThread != 0) resume_thread(id.waitingThread); delete mInfo; } break; case 'natv' : // native queue PLEvent { PREventQueue *queue = (PREventQueue *)id.data; PR_ProcessPendingEvents(queue); } break; default : printf("nsToolkit::RunPump - UNKNOWN EVENT\n"); break; } } }
static void serve_client_write(void *arg) { Session *sp = (Session *) arg; int bytes; PRFileDesc *sockfd; char *buf; PRJob *jobp; sockfd = sp->iod.socket; buf = sp->in_buf->data; PR_ASSERT(sp->msg_num < num_tcp_mesgs_per_connection); bytes = PR_Send(sockfd, buf, sp->bytes, 0, PR_INTERVAL_NO_TIMEOUT); PR_ASSERT(bytes == sp->bytes); if (bytes < 0) { return; } DPRINTF(("serve_client: write complete, msg(%d) \n", sp->msg_num)); sp->msg_num++; if (sp->msg_num < num_tcp_mesgs_per_connection) { sp->bytes_read = 0; sp->iod.timeout = PR_SecondsToInterval(60); jobp = PR_QueueJob_Read(sp->tp, &sp->iod, serve_client_read, sp, PR_FALSE); PR_ASSERT(NULL != jobp); return; } DPRINTF(("serve_client: read/write complete, msg(%d) \n", sp->msg_num)); if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) { fprintf(stderr,"%s: ERROR - PR_Shutdown\n", program_name); } PR_Close(sockfd); PR_EnterMonitor(sp->exit_mon); --(*sp->job_counterp); PR_Notify(sp->exit_mon); PR_ExitMonitor(sp->exit_mon); PR_DELETE(sp->in_buf); PR_DELETE(sp); return; }
static void PR_CALLBACK CXReader(void *arg) { CircBuf *cbp = (CircBuf *)arg; PRInt32 i, n; void *data; n = count / 2; for (i = 0; i < n; i++) { data = GetCBData(cbp); if ((int)data != i) if (debug_mode) printf("data mismatch at for i = %d usec\n", i); } PR_EnterMonitor(mon); --alive; PR_Notify(mon); PR_ExitMonitor(mon); }
/* ** StressThread() ** A bunch of these beat on individual arenas ** This tests the free_list protection. ** */ static void PR_CALLBACK StressThread( void *arg ) { PLArenaPool ap; PRIntn i; PRIntn sz; void *ptr; PRThread *tp = PR_GetCurrentThread(); PR_LOG( tLM, PR_LOG_DEBUG, ("Stress Thread %p started\n", PR_GetCurrentThread())); PL_InitArenaPool( &ap, "TheArena", RandSize( poolMin, poolMax), sizeof(double)); for ( i = 0; i < stressIterations; i++ ) { PRIntn allocated = 0; while ( allocated < maxAlloc ) { sz = RandSize( arenaMin, arenaMax ); PL_ARENA_ALLOCATE( ptr, &ap, sz ); if ( ptr == NULL ) { PR_LOG( tLM, PR_LOG_ERROR, ("ARENA_ALLOCATE() returned NULL\n\tAllocated: %d\n", allocated)); break; } allocated += sz; } PR_LOG( tLM, PR_LOG_DEBUG, ("Stress thread %p finished one iteration\n", tp)); PL_FreeArenaPool( &ap ); } PR_LOG( tLM, PR_LOG_DEBUG, ("Stress thread %p finished all iteration\n", tp)); PL_FinishArenaPool( &ap ); PR_LOG( tLM, PR_LOG_DEBUG, ("Stress thread %p after FinishArenaPool()\n", tp)); /* That's all folks! let's quit */ PR_EnterMonitor(tMon); threadCount--; PR_Notify(tMon); PR_ExitMonitor(tMon); return; }
void nsToolkit::RunPump(void* arg) { int32 code; char portname[64]; ThreadInterfaceData id; ThreadInitInfo *info = (ThreadInitInfo*)arg; PR_EnterMonitor(info->monitor); gThreadState = PR_TRUE; PR_Notify(info->monitor); PR_ExitMonitor(info->monitor); delete info; // system wide unique names int32 cookie = 0; image_info iinfo; char *leaf = NULL; do { if (get_next_image_info(0, &cookie, &iinfo) == B_OK && strlen(iinfo.name) > 0 && (leaf = strrchr(iinfo.name, '/')) != NULL) { leaf++; PR_snprintf(portname, sizeof(portname), "event%lx", (long unsigned) find_thread(leaf)); } else { PR_snprintf(portname, sizeof(portname), "event%lx", (long unsigned) find_thread(0)); } } while(iinfo.type != B_APP_IMAGE); port_id event = create_port(200, portname); while(read_port(event, &code, &id, sizeof(id)) >= 0) { switch(code) { case WM_CALLMETHOD : { MethodInfo *mInfo = (MethodInfo *)id.data; mInfo->Invoke(); if(id.waitingThread != 0) resume_thread(id.waitingThread); delete mInfo; } break; case 'natv' : // native queue PLEvent { PREventQueue *queue = (PREventQueue *)id.data; PR_ProcessPendingEvents(queue); } break; default : printf("nsToolkit::RunPump - UNKNOWN EVENT\n"); break; } } }
/* * TransmitFile Server * Server Thread * Bind an address to a socket and listen for incoming connections * Create worker threads to service clients */ static void TransmitFile_Server(void *arg) { PRThread **t = NULL; /* an array of PRThread pointers */ Server_Param *sp = (Server_Param *) arg; Serve_Client_Param *scp; PRFileDesc *sockfd = NULL, *newsockfd; PRNetAddr netaddr; PRInt32 i; PRThreadScope scope; t = (PRThread**)PR_MALLOC(num_transmitfile_clients * sizeof(PRThread *)); if (t == NULL) { fprintf(stderr, "prsocket_test: run out of memory\n"); failed_already=1; goto exit; } /* * Create a tcp socket */ if ((sockfd = PR_NewTCPSocket()) == NULL) { fprintf(stderr,"prsocket_test: PR_NewTCPSocket failed\n"); failed_already=1; goto exit; } memset(&netaddr, 0 , sizeof(netaddr)); netaddr.inet.family = AF_INET; netaddr.inet.port = PR_htons(TCP_SERVER_PORT); netaddr.inet.ip = PR_htonl(INADDR_ANY); /* * try a few times to bind server's address, if addresses are in * use */ i = 0; while (PR_Bind(sockfd, &netaddr) < 0) { if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) { netaddr.inet.port += 2; if (i++ < SERVER_MAX_BIND_COUNT) continue; } fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n"); failed_already=1; perror("PR_Bind"); goto exit; } if (PR_Listen(sockfd, 32) < 0) { fprintf(stderr,"prsocket_test: ERROR - PR_Listen failed\n"); failed_already=1; goto exit; } if (PR_GetSockName(sockfd, &netaddr) < 0) { fprintf(stderr, "prsocket_test: ERROR - PR_GetSockName failed\n"); failed_already=1; goto exit; } DPRINTF(("TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n", netaddr.inet.ip, netaddr.inet.port)); tcp_server_addr.inet.family = netaddr.inet.family; tcp_server_addr.inet.port = netaddr.inet.port; tcp_server_addr.inet.ip = netaddr.inet.ip; /* * Wake up parent thread because server address is bound and made * available in the global variable 'tcp_server_addr' */ PR_PostSem(sp->addr_sem); for (i = 0; i < num_transmitfile_clients ; i++) { if ((newsockfd = PR_Accept(sockfd, &netaddr, PR_INTERVAL_NO_TIMEOUT)) == NULL) { fprintf(stderr, "prsocket_test: ERROR - PR_Accept failed\n"); failed_already=1; goto exit; } scp = PR_NEW(Serve_Client_Param); if (scp == NULL) { fprintf(stderr,"prsocket_test: PR_NEW failed\n"); failed_already=1; goto exit; } /* * Start a Serve_Client thread for each incoming connection */ scp->sockfd = newsockfd; scp->datalen = sp->datalen; /* * create LOCAL and GLOBAL threads alternately */ if (i & 1) scope = PR_LOCAL_THREAD; else scope = PR_GLOBAL_THREAD; t[i] = PR_CreateThread(PR_USER_THREAD, Serve_TransmitFile_Client, (void *)scp, PR_PRIORITY_NORMAL, scope, PR_JOINABLE_THREAD, 0); if (t[i] == NULL) { fprintf(stderr, "prsocket_test: PR_CreateThread failed\n"); failed_already=1; goto exit; } DPRINTF(("TransmitFile_Server: Created Serve_TransmitFile_Client = 0x%lx\n", t)); } /* * Wait for all the worker threads to end, so that we know * they are no longer using the small and large file fd's. */ for (i = 0; i < num_transmitfile_clients; i++) { PR_JoinThread(t[i]); } exit: if (t) { PR_DELETE(t); } if (sockfd) { PR_Close(sockfd); } /* * Decrement exit_counter and notify parent thread */ PR_EnterMonitor(sp->exit_mon); --(*sp->exit_counter); PR_Notify(sp->exit_mon); PR_ExitMonitor(sp->exit_mon); DPRINTF(("TransmitFile_Server [0x%lx] exiting\n", PR_GetCurrentThread())); }
/* * TransmitFile_Client * Client Thread */ static void TransmitFile_Client(void *arg) { PRFileDesc *sockfd; union PRNetAddr netaddr; char *small_buf, *large_buf; Client_Param *cp = (Client_Param *) arg; small_buf = (char*)PR_Malloc(SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE); if (small_buf == NULL) { fprintf(stderr,"prsocket_test: failed to alloc buffer\n"); failed_already=1; return; } large_buf = (char*)PR_Malloc(LARGE_FILE_SIZE); if (large_buf == NULL) { fprintf(stderr,"prsocket_test: failed to alloc buffer\n"); failed_already=1; return; } netaddr.inet.family = cp->server_addr.inet.family; netaddr.inet.port = cp->server_addr.inet.port; netaddr.inet.ip = cp->server_addr.inet.ip; if ((sockfd = PR_NewTCPSocket()) == NULL) { fprintf(stderr,"prsocket_test: PR_NewTCPSocket failed\n"); failed_already=1; return; } if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){ fprintf(stderr,"prsocket_test: PR_Connect failed\n"); failed_already=1; return; } /* * read the small file and verify the data */ if (readn(sockfd, small_buf, SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE) != (SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE)) { fprintf(stderr, "prsocket_test: TransmitFile_Client failed to receive file\n"); failed_already=1; return; } #ifdef XP_UNIX if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0){ fprintf(stderr, "prsocket_test: TransmitFile_Client ERROR - small file header data corruption\n"); failed_already=1; return; } if (memcmp(small_file_addr, small_buf + SMALL_FILE_HEADER_SIZE, SMALL_FILE_SIZE) != 0) { fprintf(stderr, "prsocket_test: TransmitFile_Client ERROR - small file data corruption\n"); failed_already=1; return; } #endif /* * read the large file and verify the data */ if (readn(sockfd, large_buf, LARGE_FILE_SIZE) != LARGE_FILE_SIZE) { fprintf(stderr, "prsocket_test: TransmitFile_Client failed to receive file\n"); failed_already=1; return; } #ifdef XP_UNIX if (memcmp(large_file_addr, large_buf, LARGE_FILE_SIZE) != 0) { fprintf(stderr, "prsocket_test: TransmitFile_Client ERROR - large file data corruption\n"); failed_already=1; return; } #endif PR_DELETE(small_buf); PR_DELETE(large_buf); PR_Close(sockfd); /* * Decrement exit_counter and notify parent thread */ PR_EnterMonitor(cp->exit_mon); --(*cp->exit_counter); PR_Notify(cp->exit_mon); PR_ExitMonitor(cp->exit_mon); DPRINTF(("TransmitFile_Client [0x%lx] exiting\n", PR_GetCurrentThread())); }
void monitor_set(monitor_t monitor) { PR_Notify((PRMonitor*)monitor); }
/* * UDP_Client * Client Thread * Create a socket and bind an address * Communicate with the server at the address specified in the argument. * Fill in a buffer, write data to server, read it back and check * for data corruption. * Close the socket */ static void PR_CALLBACK UDP_Client(void *arg) { Client_Param *cp = (Client_Param *) arg; PRFileDesc *sockfd; buffer *in_buf, *out_buf; union PRNetAddr netaddr; PRInt32 bytes, i, rv; bytes = cp->datalen; out_buf = PR_NEW(buffer); if (out_buf == NULL) { fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); failed_already=1; return; } in_buf = PR_NEW(buffer); if (in_buf == NULL) { fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); failed_already=1; return; } if ((sockfd = PR_NewUDPSocket()) == NULL) { fprintf(stderr,"prsocket_test: PR_NewUDPSocket failed\n"); failed_already=1; return; } /* * bind an address for the client, let the system chose the port * number */ memset(&netaddr, 0 , sizeof(netaddr)); netaddr.inet.family = AF_INET; netaddr.inet.ip = PR_htonl(INADDR_ANY); netaddr.inet.port = PR_htons(0); if (PR_Bind(sockfd, &netaddr) < 0) { fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n"); perror("PR_Bind"); return; } if (PR_GetSockName(sockfd, &netaddr) < 0) { fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n"); failed_already=1; return; } DPRINTF(("PR_Bind: UDP Client netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n", netaddr.inet.ip, netaddr.inet.port)); netaddr.inet.family = cp->server_addr.inet.family; netaddr.inet.port = cp->server_addr.inet.port; netaddr.inet.ip = cp->server_addr.inet.ip; if (cp->udp_connect) { if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){ fprintf(stderr,"prsocket_test: PR_Connect failed\n"); failed_already=1; return; } } for (i = 0; i < num_udp_datagrams_per_client; i++) { /* * fill in random data */ DPRINTF(("UDP_Client [0x%lx]: out_buf = 0x%lx bytes = 0x%lx\n", PR_GetCurrentThread(), out_buf->data, bytes)); memset(out_buf->data, ((PRInt32) (&netaddr)) + i, bytes); /* * write to server */ if (cp->udp_connect) rv = PR_Send(sockfd, out_buf->data, bytes, 0, PR_INTERVAL_NO_TIMEOUT); else rv = PR_SendTo(sockfd, out_buf->data, bytes, 0, &netaddr, PR_INTERVAL_NO_TIMEOUT); if (rv != bytes) { return; } DPRINTF(("UDP_Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n", PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data)))); if (cp->udp_connect) rv = PR_Recv(sockfd, in_buf->data, bytes, 0, PR_INTERVAL_NO_TIMEOUT); else rv = PR_RecvFrom(sockfd, in_buf->data, bytes, 0, &netaddr, PR_INTERVAL_NO_TIMEOUT); if (rv != bytes) { return; } DPRINTF(("UDP_Client [0x%lx]: in_buf = 0x%lx in_buf[0] = 0x%lx\n", PR_GetCurrentThread(), in_buf, (*((int *) in_buf->data)))); /* * verify the data read */ if (memcmp(in_buf->data, out_buf->data, bytes) != 0) { fprintf(stderr,"prsocket_test: ERROR - UDP data corruption\n"); failed_already=1; return; } } PR_Close(sockfd); PR_DELETE(in_buf); PR_DELETE(out_buf); /* * Decrement exit_counter and notify parent thread */ PR_EnterMonitor(cp->exit_mon); --(*cp->exit_counter); PR_Notify(cp->exit_mon); PR_ExitMonitor(cp->exit_mon); PR_DELETE(cp); DPRINTF(("UDP_Client [0x%x] exiting\n", PR_GetCurrentThread())); }
/* * TCP_Client * Client Thread * Connect to the server at the address specified in the argument. * Fill in a buffer, write data to server, read it back and check * for data corruption. * Close the socket for server connection */ static void PR_CALLBACK TCP_Client(void *arg) { Client_Param *cp = (Client_Param *) arg; PRFileDesc *sockfd; buffer *in_buf, *out_buf; union PRNetAddr netaddr; PRInt32 bytes, i, j; bytes = cp->datalen; out_buf = PR_NEW(buffer); if (out_buf == NULL) { fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); failed_already=1; return; } in_buf = PR_NEW(buffer); if (in_buf == NULL) { fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); failed_already=1; return; } netaddr.inet.family = cp->server_addr.inet.family; netaddr.inet.port = cp->server_addr.inet.port; netaddr.inet.ip = cp->server_addr.inet.ip; for (i = 0; i < num_tcp_connections_per_client; i++) { if ((sockfd = PR_NewTCPSocket()) == NULL) { fprintf(stderr,"prsocket_test: PR_NewTCPSocket failed\n"); failed_already=1; return; } if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){ fprintf(stderr,"prsocket_test: PR_Connect failed\n"); failed_already=1; return; } for (j = 0; j < num_tcp_mesgs_per_connection; j++) { /* * fill in random data */ memset(out_buf->data, ((PRInt32) (&netaddr)) + i + j, bytes); /* * write to server */ if (writen(sockfd, out_buf->data, bytes) < bytes) { fprintf(stderr,"prsocket_test: ERROR - TCP_Client:writen\n"); failed_already=1; return; } DPRINTF(("TCP Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n", PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data)))); if (readn(sockfd, in_buf->data, bytes) < bytes) { fprintf(stderr,"prsocket_test: ERROR - TCP_Client:readn\n"); failed_already=1; return; } /* * verify the data read */ if (memcmp(in_buf->data, out_buf->data, bytes) != 0) { fprintf(stderr,"prsocket_test: ERROR - data corruption\n"); failed_already=1; return; } } /* * shutdown reads and writes */ if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) { fprintf(stderr,"prsocket_test: ERROR - PR_Shutdown\n"); failed_already=1; } PR_Close(sockfd); } PR_DELETE(out_buf); PR_DELETE(in_buf); /* * Decrement exit_counter and notify parent thread */ PR_EnterMonitor(cp->exit_mon); --(*cp->exit_counter); PR_Notify(cp->exit_mon); PR_ExitMonitor(cp->exit_mon); DPRINTF(("TCP_Client [0x%x] exiting\n", PR_GetCurrentThread())); }
/* * UDP Server * Server Thread * Bind an address to a socket, read data from clients and send data * back to clients */ static void PR_CALLBACK UDP_Server(void *arg) { Server_Param *sp = (Server_Param *) arg; PRFileDesc *sockfd; buffer *in_buf; PRNetAddr netaddr; PRInt32 bytes, i, rv; bytes = sp->datalen; /* * Create a udp socket */ if ((sockfd = PR_NewUDPSocket()) == NULL) { fprintf(stderr,"prsocket_test: PR_NewUDPSocket failed\n"); failed_already=1; return; } memset(&netaddr, 0 , sizeof(netaddr)); netaddr.inet.family = AF_INET; netaddr.inet.port = PR_htons(UDP_SERVER_PORT); netaddr.inet.ip = PR_htonl(INADDR_ANY); /* * try a few times to bind server's address, if addresses are in * use */ i = 0; while (PR_Bind(sockfd, &netaddr) < 0) { if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) { netaddr.inet.port += 2; if (i++ < SERVER_MAX_BIND_COUNT) continue; } fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n"); perror("PR_Bind"); failed_already=1; return; } if (PR_GetSockName(sockfd, &netaddr) < 0) { fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n"); failed_already=1; return; } if (netaddr.inet.port != PR_htons(UDP_SERVER_PORT)) { fprintf(stderr,"prsocket_test: ERROR - tried to bind to UDP " "port %hu, but was bound to port %hu\n", UDP_SERVER_PORT, PR_ntohs(netaddr.inet.port)); failed_already=1; return; } DPRINTF(("PR_Bind: UDP Server netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n", netaddr.inet.ip, netaddr.inet.port)); udp_server_addr = netaddr; /* * We can't use the IP address returned by PR_GetSockName in * netaddr.inet.ip because netaddr.inet.ip is returned * as 0 (= INADDR_ANY). */ udp_server_addr.inet.ip = PR_htonl(INADDR_LOOPBACK); /* * Wake up parent thread because server address is bound and made * available in the global variable 'udp_server_addr' */ PR_PostSem(sp->addr_sem); bytes = sp->datalen; in_buf = PR_NEW(buffer); if (in_buf == NULL) { fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); failed_already=1; return; } /* * Receive datagrams from clients and send them back, unmodified, to the * clients */ memset(&netaddr, 0 , sizeof(netaddr)); for (i = 0; i < (num_udp_clients * num_udp_datagrams_per_client); i++) { DPRINTF(("UDP_Server: calling PR_RecvFrom client - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n", netaddr.inet.ip, netaddr.inet.port, rv, in_buf->data, in_buf->data[0])); rv = PR_RecvFrom(sockfd, in_buf->data, bytes, 0, &netaddr, PR_INTERVAL_NO_TIMEOUT); DPRINTF(("UDP_Server: PR_RecvFrom client - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n", netaddr.inet.ip, netaddr.inet.port, rv, in_buf->data, in_buf->data[0])); if (rv != bytes) { return; } rv = PR_SendTo(sockfd, in_buf->data, bytes, 0, &netaddr, PR_INTERVAL_NO_TIMEOUT); if (rv != bytes) { return; } } PR_DELETE(in_buf); /* * Decrement exit_counter and notify parent thread */ PR_EnterMonitor(sp->exit_mon); --(*sp->exit_counter); PR_Notify(sp->exit_mon); PR_ExitMonitor(sp->exit_mon); DPRINTF(("UDP_Server [0x%x] exiting\n", PR_GetCurrentThread())); }
/* * TCP Server * Server Thread * Bind an address to a socket and listen for incoming connections * Start a Serve_Client thread for each incoming connection. */ static void PR_CALLBACK TCP_Server(void *arg) { PRThread *t; Server_Param *sp = (Server_Param *) arg; Serve_Client_Param *scp; PRFileDesc *sockfd, *newsockfd; PRNetAddr netaddr; PRInt32 i; /* * Create a tcp socket */ if ((sockfd = PR_NewTCPSocket()) == NULL) { fprintf(stderr,"prsocket_test: PR_NewTCPSocket failed\n"); goto exit; } memset(&netaddr, 0 , sizeof(netaddr)); netaddr.inet.family = AF_INET; netaddr.inet.port = PR_htons(TCP_SERVER_PORT); netaddr.inet.ip = PR_htonl(INADDR_ANY); /* * try a few times to bind server's address, if addresses are in * use */ i = 0; while (PR_Bind(sockfd, &netaddr) < 0) { if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) { netaddr.inet.port += 2; if (i++ < SERVER_MAX_BIND_COUNT) continue; } fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n"); perror("PR_Bind"); failed_already=1; goto exit; } if (PR_Listen(sockfd, 32) < 0) { fprintf(stderr,"prsocket_test: ERROR - PR_Listen failed\n"); failed_already=1; goto exit; } if (PR_GetSockName(sockfd, &netaddr) < 0) { fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n"); failed_already=1; goto exit; } DPRINTF(("TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n", netaddr.inet.ip, netaddr.inet.port)); tcp_server_addr.inet.family = netaddr.inet.family; tcp_server_addr.inet.port = netaddr.inet.port; tcp_server_addr.inet.ip = netaddr.inet.ip; /* * Wake up parent thread because server address is bound and made * available in the global variable 'tcp_server_addr' */ PR_PostSem(sp->addr_sem); for (i = 0; i < (num_tcp_clients * num_tcp_connections_per_client); i++) { if ((newsockfd = PR_Accept(sockfd, &netaddr, PR_INTERVAL_NO_TIMEOUT)) == NULL) { fprintf(stderr,"prsocket_test: ERROR - PR_Accept failed\n"); goto exit; } scp = PR_NEW(Serve_Client_Param); if (scp == NULL) { fprintf(stderr,"prsocket_test: PR_NEW failed\n"); goto exit; } /* * Start a Serve_Client thread for each incoming connection */ scp->sockfd = newsockfd; scp->datalen = sp->datalen; t = PR_CreateThread(PR_USER_THREAD, Serve_Client, (void *)scp, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0); if (t == NULL) { fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); failed_already=1; goto exit; } DPRINTF(("TCP_Server: Created Serve_Client = 0x%lx\n", t)); } exit: if (sockfd) { PR_Close(sockfd); } /* * Decrement exit_counter and notify parent thread */ PR_EnterMonitor(sp->exit_mon); --(*sp->exit_counter); PR_Notify(sp->exit_mon); PR_ExitMonitor(sp->exit_mon); DPRINTF(("TCP_Server [0x%lx] exiting\n", PR_GetCurrentThread())); }
void ClientThreadFunc(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); }