static void run_master(void) { unsigned id; size_t running = worker_processes; master_selfwake = mog_selfwake_new(); siginit(master_wakeup_handler); for (id = 0; id < worker_processes; id++) fork_worker(id); while (running > 0) { mog_selfwake_wait(master_selfwake); if (sigchld_hit) sigchld_handler(); if (do_upgrade) upgrade_handler(); if (do_exit) running = mog_kill_each_worker(SIGQUIT); } }
static void main_worker_loop(const pid_t parent) { mog_cancel_disable(); /* mog_idleq_wait() now relies on this */ while (parent == 0 || parent == getppid()) { mog_notify_wait(have_mgmt); if (sigchld_hit) sigchld_handler(); if (do_upgrade) upgrade_handler(); if (do_exit) cmogstored_exit(); if (have_mgmt) mog_mnt_refresh(); else if (have_mgmt && !iostat_running && !do_exit) /* * maybe iostat was not installed/available/usable at * startup, but became usable later */ iostat_running = mog_iostat_respawn(0); } syslog(LOG_INFO, "parent=%d abandoned us, dying", parent); cmogstored_exit(); }
int main(int argc, char *argv[]) { sem_t *sem_mutex; //Binary semaphore to use a mutex int *stateptr; //Shared memory global int to store active button state int hit_count = 0, rows, cols; WINDOW *mainwin = NULL; int nextch; MEVENT event; struct sigaction act; //Create a binary semaphore to use as a mutex: //(will be inerited by children) if ((sem_mutex = sem_open("/mutex", O_CREAT|O_EXCL, 0600, 1)) == SEM_FAILED) { perror("Semaphore creation failed"); return EXIT_FAILURE; } //Now unlink semaphore so it will be deleted in case of ^-C or crash: sem_unlink("/mutex"); //Setup anonymous, shared memory for global int: if ((stateptr = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0)) == MAP_FAILED) { perror("Shared memory creation failed"); return EXIT_FAILURE; } //Initialize button state (no active buttons): *stateptr = 0; //Initialize and setup the curses window: if ((mainwin = initscr()) == NULL) { fprintf(stderr,"Failed to initialize curses window\n"); return EXIT_FAILURE; } getmaxyx(mainwin,rows,cols); mvprintw(rows/2,cols/2-18,"Click on the Corner Buttons to Score!",rows,cols); mvprintw(rows/2+2,cols/2-10,"(rows: %d cols: %d)",rows,cols); refresh(); //Setup signal handler for SIGCHLD signals: memset(&act,0,sizeof(act)); act.sa_handler = sigchld_handler; sigemptyset(&act.sa_mask); sigaction(SIGCHLD,&act,NULL); //Create children: //**************** for (int i=0; i < running; i++){//memory problem??? switch(fork()){ case -1: perror("fork failed"); sigchld_handler(EXIT_FAILURE); endwin();//put this in here since failures don't close the window apparently. exit(EXIT_FAILURE); case 0: child_func(1+i, rows, cols,sem_mutex,stateptr);//1+processcount allows for proper numbering. sigchld_handler(EXIT_SUCCESS); exit(EXIT_SUCCESS); default: break;//no break leads to error apparently. //I got it now the switch statement will determine the parent function follows the default. } } //Setup curses to get mouse events: keypad(mainwin, TRUE); mousemask(ALL_MOUSE_EVENTS, NULL); //Loop catching mouse clicks while children are running: while (running > 0) { //nextch = wgetch(mainwin); if ((nextch = getch()) == KEY_MOUSE && getmouse(&event) == OK && (event.bstate & BUTTON1_PRESSED)) { //Check if user clicked on a label: if (check_click(*stateptr, event.x, event.y, rows, cols)) { //Clicked on current label: hit_count++; mvprintw(rows/2+5,cols/2-11,"Got #%d at (%3d,%3d)",*stateptr,event.x,event.y); wrefresh(curscr); //Need this to ensure entire screen is redrawn despite child changes. } } } //Close curses window so terminal settings are restored to normal: endwin(); //Print out results: printf("\nYour hit count was: %d\n\n",hit_count); //Collect all the children: //************************* //return exit success if child successfully exited. int status; int tempcount = 0;//made a temp count since I think running will be 0 by now. while(tempcount<4){ wait(&status);// wait for children shouldn't all return status if(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS){ tempcount++;//increment temp count. }else exit(EXIT_FAILURE);//return exit failure according to lecture. } exit(EXIT_SUCCESS);//completes while loop so returns exit success. }