// 1. Extract arguments // 2. Initialize modules // 3. Launch candy-factory threads // 4. Launch kid threads // 5. Wait for requested time // 6. Stop candy-factory threads // 7. Wait until no more candy // 8. Stop kid threads // 9. Print statistics // 10. Cleanup any allocated memory int main(int argc, char* argv[]) { //1. Extract Arguments int factories = 0, kids = 0, seconds = 0; int* array[3] = {&factories, &kids, &seconds}; if(invalid_args(argc, argv)) { printf(INVALID_ARG_ERR); exit(1); } for(int i=1; i<=ARG_COUNT; i++){ sscanf(argv[i], "%d", array[i-1]); } //2. Initialize Modules srand(time(NULL)); bbuff_init(); stats_init(factories); //3. Launch candy-factory threads pthread_t* factory_thread_IDs = malloc(factories *(sizeof(pthread_t))); launch_threads(factories, factory_thread_IDs, (void*)factory_thread); //4. Launch kid threads pthread_t* kid_thread_IDs = malloc(kids *(sizeof(pthread_t))); launch_threads(kids, kid_thread_IDs, (void*)kid_thread); //5. Wait for requested time for(int i=0; i<seconds; i++) { sleep(1); printf("Time: %ds\n", i+1); } //6. Stop candy-factory threads stop_thread = true; for(int i=0; i<factories; i++) { pthread_join(factory_thread_IDs[i], NULL); } //7. Wait until no more candy while(!bbuff_is_empty()) { sleep(1); } //8. Stop kid threads for(int i=0; i<kids; i++) { pthread_cancel(kid_thread_IDs[i]); pthread_join(kid_thread_IDs[i], NULL); } //9. Print statistics stats_display(); //10. Cleanup any allocated memory stats_cleanup(); free(factory_thread_IDs); free(kid_thread_IDs); printf("Exiting program!\n"); return 0; }
int main(int argc, char **argv) { char * progName = NULL; const char * pidFile = NULL; char * tmp; PRFileDesc * listen_sock; int optionsFound = 0; unsigned short port = 0; SECStatus rv; PRStatus prStatus; PRBool bindOnly = PR_FALSE; PRBool useLocalThreads = PR_FALSE; PLOptState *optstate; PLOptStatus status; tmp = strrchr(argv[0], '/'); tmp = tmp ? tmp + 1 : argv[0]; progName = strrchr(tmp, '\\'); progName = progName ? progName + 1 : tmp; PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); /* please keep this list of options in ASCII collating sequence. ** numbers, then capital letters, then lower case, alphabetical. */ optstate = PL_CreateOptState(argc, argv, "Dbhi:p:t:v"); while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) { ++optionsFound; switch(optstate->option) { case 'D': noDelay = PR_TRUE; break; case 'b': bindOnly = PR_TRUE; break; case 'h': Usage(progName); exit(0); break; case 'i': pidFile = optstate->value; break; case 'p': port = PORT_Atoi(optstate->value); break; case 't': maxThreads = PORT_Atoi(optstate->value); if ( maxThreads > MAX_THREADS ) maxThreads = MAX_THREADS; if ( maxThreads < MIN_THREADS ) maxThreads = MIN_THREADS; break; case 'v': verbose++; break; default: case '?': fprintf(stderr, "Unrecognized or bad option specified.\n"); fprintf(stderr, "Run '%s -h' for usage information.\n", progName); exit(4); break; } } PL_DestroyOptState(optstate); if (status == PL_OPT_BAD) { fprintf(stderr, "Unrecognized or bad option specified.\n"); fprintf(stderr, "Run '%s -h' for usage information.\n", progName); exit(5); } if (!optionsFound) { Usage(progName); exit(51); } /* The -b (bindOnly) option is only used by the ssl.sh test * script on Linux to determine whether a previous selfserv * process has fully died and freed the port. (Bug 129701) */ if (bindOnly) { listen_sock = getBoundListenSocket(port); if (!listen_sock) { exit(1); } if (listen_sock) { PR_Close(listen_sock); } exit(0); } if (port == 0) { fprintf(stderr, "Required argument 'port' must be non-zero value\n"); exit(7); } if (pidFile) { FILE *tmpfile=fopen(pidFile,"w+"); if (tmpfile) { fprintf(tmpfile,"%d",getpid()); fclose(tmpfile); } } tmp = getenv("TMP"); if (!tmp) tmp = getenv("TMPDIR"); if (!tmp) tmp = getenv("TEMP"); /* we're an ordinary single process server. */ listen_sock = getBoundListenSocket(port); prStatus = PR_SetFDInheritable(listen_sock, PR_FALSE); if (prStatus != PR_SUCCESS) errExit("PR_SetFDInheritable"); lm = PR_NewLogModule("TestCase"); /* allocate the array of thread slots, and launch the worker threads. */ rv = launch_threads(&jobLoop, 0, 0, 0, useLocalThreads); if (rv == SECSuccess) { server_main(listen_sock, 0, 0, 0, 0); } VLOG(("selfserv: server_thread: exiting")); if (failedToNegotiateName) { fprintf(stderr, "selfserv: Failed properly negotiate server name\n"); exit(1); } PR_Cleanup(); printf("selfserv: normal termination\n"); return 0; }
/* ========================================================================= */ int HTTPDStart(struct httpdsrv *h) { char gaistr[128]; struct addrinfo hint; struct addrinfo *ailist, *aiuse; int err; int hc; /* Start the worker threads */ if(launch_threads(h)) return(1); assert(NULL != h); memset(&hint, 0, sizeof(struct addrinfo)); hint.ai_flags = AI_PASSIVE; hint.ai_family = AF_INET; hint.ai_socktype = SOCK_STREAM; hint.ai_protocol = IPPROTO_TCP; hint.ai_addrlen = 0; hint.ai_canonname = NULL; hint.ai_addr = NULL; hint.ai_next = NULL; if (0 != ( err = getaddrinfo(h->o->cf_host, h->o->cf_port, &hint, &ailist) )) { error_msg("ERROR: Failed call to getaddrinfo() for local connection info."); strcpy(gaistr, gai_strerror(err)); chomp(gaistr); error_msg(" %s", gaistr); return(1); } if ( NULL == (aiuse = ailist) ) { error_msg("ERROR: Empty list from getaddrinfo."); return(1); } /* Set up the socket */ if ( 0 > (h->lsock = socket(aiuse->ai_family, aiuse->ai_socktype , aiuse->ai_protocol)) ) { error_msg("ERROR: Failed to establish a socket."); return(1); } if ( 0 > bind(h->lsock, aiuse->ai_addr, aiuse->ai_addrlen) ) { error_msg("ERROR: Failed to bind to established address."); return(1); } if ( 0 > listen(h->lsock, 0) ) { error_msg("ERROR: HTTPd server failed to listen()."); return(1); } while ( h->trun ) { if ( 0 < ( hc = accept(h->lsock, NULL, NULL) ) ) { /* This is a potential logging point. Why we do NOT log here: - Even though it is a non-contensious point (in the parent thread with no locking issues), it does have the potential to hold up connections with slow I/O to a file. - There is no request data - only the remote connection data that we can get elsewhere. - There is no timing data (how long it took to handle the request) as we have not determined what the requestor wants. - There is no status of the completed request. */ request_assign_thread(h, hc); } } close(h->lsock); return(0); }
bool SelLum::doFeather() { mp_nameCurProcess = GetString(IDS_PROCESS_FEATHER); // NOTE: there is _alot_ of room for optimization in this function // compute normalized radii mask for feathered pixels if (m_normRadMaskW != 2*m_feathRad + 1) { if (m_normRadMask) delete[] m_normRadMask; m_normRadMaskW = m_normRadMaskH = 2*m_feathRad + 1; m_normRadMask = new float[m_normRadMaskW*m_normRadMaskH]; int index = -1; float x_dist, y_dist; for (int i=0; i<m_normRadMaskW; i++) { for (int j=0; j<m_normRadMaskH; j++) { x_dist = (float)i-m_feathRad; y_dist = (float)j-m_feathRad; m_normRadMask[++index] = (float)(sqrt(sqr(x_dist)+sqr(y_dist)) / (float)m_feathRad); m_normRadMask[index] = (m_normRadMask[index] > 1.0f) ? 1.0f : m_normRadMask[index]; } } } // find feathered pixels //int index, normRadIdx; int interval = 3*m_imageW; // Introduce Window threading SYSTEM_INFO si; int num_processors; GetSystemInfo(&si); num_processors = ( GetCOREInterface()->GetRendMultiThread() ? si.dwNumberOfProcessors : 1 ); HANDLE *hThreads = new HANDLE[num_processors]; HANDLE *numDoneEvent = new HANDLE[num_processors]; struct ThreadParams *threadParams = new struct ThreadParams[num_processors]; int startv = -m_feathRad; int inc = (2*m_feathRad+1)/num_processors; for(int i = 0; i < num_processors; i++){ threadParams[i].m_feathRad = m_feathRad; threadParams[i].m_imageW = m_imageW; threadParams[i].m_imageH = m_imageH; threadParams[i].m_normRadMaskW = m_normRadMaskW; threadParams[i].mp_radMap = mp_radMap; threadParams[i].m_normRadMask = m_normRadMask; threadParams[i].num = i; threadParams[i].step = 1; threadParams[i].startv = startv; if(i == num_processors - 1) threadParams[i].Maxv = m_feathRad; else threadParams[i].Maxv = startv + inc - 1; startv = startv + inc; } launch_threads(num_processors, hThreads,numDoneEvent, threadParams); bool returnValue = true; for (int mapIndex =0; mapIndex < m_imageSz; mapIndex++){ if (mp_radMap[mapIndex] == 0.0f){ // a selected pixel int y = mapIndex / m_imageW; int x = mapIndex % m_imageW; // skip pixel if surrounded by other selected pixels if ( ( ( x>0 ) && (mp_radMap[mapIndex-1] == 0.0f) ) && ( ( x<m_imageW-1 ) && (mp_radMap[mapIndex+1] == 0.0f) ) && ( ( y>0 ) && (mp_radMap[mapIndex-m_imageW] == 0.0f) ) && ( ( y<m_imageH-1 ) && (mp_radMap[mapIndex+m_imageW] == 0.0f) ) ) continue; // set offset and weight of the feathered pixels // spit the works among the threads for(int i= 0; i < num_processors; i++){ threadParams[i].x = x; threadParams[i].y = y; threadParams[i].mapIndex = mapIndex; SetEvent(threadParams[i].startEvent); } WaitForMultipleObjects(num_processors, numDoneEvent, TRUE,INFINITE); } // if (mp_radMap[mapIndex] == 0.0f) if ( ( (mapIndex%interval) == 0 ) && mp_blurMgr->progress(mp_nameCurProcess, mapIndex, m_imageSz) ) { returnValue = false; break; } } // for mapIndex loop // Signal the threads to terminate. for(i = 0; i < num_processors; i++){ threadParams[i].terminateThread = true; SetEvent(threadParams[i].startEvent); } // Wait for them to finish. DWORD wait = WaitForMultipleObjects(num_processors, hThreads, true, 5000); DbgAssert(wait != WAIT_TIMEOUT); // Close everything, terminate threads that hung. for(i = 0; i < num_processors; i++){ CloseHandle(threadParams[i].startEvent); CloseHandle(threadParams[i].numDoneEvent); TerminateThread(hThreads[i],0); CloseHandle(hThreads[i]); hThreads[i] = NULL; } delete []hThreads; delete []numDoneEvent; delete []threadParams; return returnValue; }