int main (int argc, char **argv) { printf ("stop here in main.\n"); int num_times = wait_a_while (argc * 1000); printf ("Done, took %d times.\n", num_times); return 0; }
/*ARGSUSED*/ void * fcal_leds_thread(void *args) { led_dtls_t *dtls = g_led_dtls; int c, v; int err = 0; int events = 0; int fd_bkplane; i2c_port_t port; int lastVal = I2C_IOCTL_INIT; int ws; int mask; /* * generate a mask for presence and fault status bits */ mask = 0; for (c = 0; c < dtls->n_disks; c++) { mask |= dtls->presence[c]; mask |= dtls->faults[c]; } /* * enter poll loop */ for (;;) { /* * see if a LED-test timer has expired */ for (c = 0; c < dtls->n_disks; c++) { if (dtls->led_test_end[c] > 0) { if (!dtls->polling) { /* poll thread failure, end led-test */ dtls->led_test_end[c] = 0; } else if ((events & FCAL_EV_POLL) != 0) { dtls->led_test_end[c]--; } if (dtls->led_test_end[c] == 0) { /* * clear blue and amber leds */ end_led_test(dtls, c); /* treat any status as a change */ lastVal = I2C_IOCTL_INIT; } } } fd_bkplane = open(dtls->fcal_status, O_RDONLY); if (fd_bkplane < 0) { SYSLOG(LOG_ERR, EM_CANT_OPEN, dtls->fcal_status); err = errno; break; } port.value = 0; /* * the direction and dir_mask fields are ignored, * so one can only guess at their possible use */ port.direction = DIR_INPUT; port.dir_mask = (uint8_t)mask; c = ioctl(fd_bkplane, I2C_GET_PORT, &port); if (c < 0) { err = errno; (void) close(fd_bkplane); if (lastVal != I2C_IOCTL_FAIL) { SYSLOG(LOG_ERR, EM_I2C_GET_PORT, mystrerror(err)); lastVal = I2C_IOCTL_FAIL; events |= FCAL_EV_CONFIG; } } else { (void) close(fd_bkplane); ws = port.value & mask; } if ((c == 0) && (ws != lastVal)) { events |= FCAL_EV_CONFIG; lastVal = ws; for (c = 0; c < dtls->n_disks; c++) { /* * first get the value of the relevant * presence bit (as 0 or 1) */ v = ((lastVal & dtls->presence[c]) != 0); /* hold previous presence value */ ws = dtls->disk_detected[c]; /* * the disk is present if the backplane * status bit for this disk is equal to the * configured assert_presence value */ dtls->disk_detected[c] = (v == dtls->assert_presence); /* * Don't add disk-unit node here for * newly arrived disks. While the led * test is running (and beyond) * libdevinfo is locked out and we * can't get port or target info. */ if ((!ws) && dtls->disk_detected[c]) { /* * disk has just come on-line */ start_led_test(dtls, c); } /* * clear leds and ready status * for disks which have been removed */ if (ws && (!dtls->disk_detected[c])) { clr_led(c, FCAL_REMOK_LED, dtls); clr_led(c, FCAL_FAULT_LED, dtls); clr_led(c, FCAL_READY_LED, dtls); dtls->disk_ready[c] = NO_MINORS; dtls->disk_prev[c] = NO_MINORS; v = update_picl(dtls, c); /* * set or clear retry flag */ dtls->picl_retry[c] = (v == EAGAIN); } /* * for present disks which are not doing a * led test, adjust fault LED */ if ((dtls->led_test_end[c] != 0) || (!dtls->disk_detected[c])) continue; v = ((lastVal & dtls->faults[c]) != 0); if (v == dtls->assert_fault) set_led(c, FCAL_FAULT_LED, dtls); else clr_led(c, FCAL_FAULT_LED, dtls); } } /* * For detected disks whose status has changed, choose between * ready and ok to remove. * libdevinfo can be locked out for the entire duration of a * disk spin-up. So it is best not to seek this info while * a led-test is in progress. Otherwise the leds can be stuck * on for about 40 seconds. * Note that chk_minors() returns 0 unless a status change * has occurred. */ if (!is_led_test(dtls) && chk_minors(dtls) != 0) { events = FCAL_EV_CONFIG; for (c = 0; c < dtls->n_disks; c++) { if (!dtls->disk_detected[c]) continue; /* * When disk_ready changes, disk_prev is set * to its previous value. This allows the * direction of the last transistion to be * determined. */ if ((dtls->disk_prev[c] == HAS_MINORS) && (dtls->disk_ready[c] == NO_MINORS)) { clr_led(c, FCAL_READY_LED, dtls); set_led(c, FCAL_REMOK_LED, dtls); } else { set_led(c, FCAL_READY_LED, dtls); clr_led(c, FCAL_REMOK_LED, dtls); } } } /* * Update PICL (disk-unit) for newly attached disks * ** see note in header file for significance * of disk_prev and disk_ready flags. */ for (c = 0; c < dtls->n_disks; c++) { if ((dtls->disk_prev[c] == NO_MINORS) && (dtls->disk_ready[c] == HAS_MINORS)) { dtls->disk_prev[c] = HAS_MINORS; v = update_picl(dtls, c); /* * set or clear retry flag */ dtls->picl_retry[c] = (v == EAGAIN); } } if ((events & FCAL_EV_CONFIG) != 0) { /* * set fast polling */ dtls->fast_poll_end = dtls->relax_time_ticks; } /* * if updating a led failed (e.g. I2C busy), try again */ if (dtls->led_retry) retry_led(dtls); events = wait_a_while(); /* * when picl is recycled, wait_a_while sleeps until the * init routine has been called again. * This is the moment when dtls may have become stale. */ if (dtls != g_led_dtls) { dtls = g_led_dtls; lastVal = I2C_IOCTL_INIT; /* * re-generate the presence and fault status mask * in case the .conf file has changed */ mask = 0; for (c = 0; c < dtls->n_disks; c++) { mask |= dtls->presence[c]; mask |= dtls->faults[c]; } } /* * count down relaxation time counter if a poll event */ if ((events & FCAL_EV_POLL) != 0) { if (dtls->fast_poll_end > 0) dtls->fast_poll_end--; } /* * if updating PICL needs retrying, try it now */ for (c = 0; c < dtls->n_disks; c++) { if (dtls->picl_retry[c]) { v = update_picl(dtls, c); dtls->picl_retry[c] = (v == EAGAIN); } } } return ((void *)err); }
int main(int argc, char **argv) { int itmp, y; if (argc > 1 && atol(argv[1])) nap_msec = atol(argv[1]); #ifdef XCURSES Xinitscr(argc, argv); #else initscr(); #endif backfill(); for (y = 0; y < 5; y++) { p1 = mkpanel(10, 10, 0, 0); set_panel_userptr(p1, "p1"); p2 = mkpanel(14, 14, 5, 5); set_panel_userptr(p2, "p2"); p3 = mkpanel(6, 8, 12, 12); set_panel_userptr(p3, "p3"); p4 = mkpanel(10, 10, 10, 30); w4 = panel_window(p4); set_panel_userptr(p4, "p4"); p5 = mkpanel(10, 10, 13, 37); w5 = panel_window(p5); set_panel_userptr(p5, "p5"); fill_panel(p1); fill_panel(p2); fill_panel(p3); fill_panel(p4); fill_panel(p5); hide_panel(p4); hide_panel(p5); pflush(); wait_a_while(nap_msec); saywhat("h3 s1 s2 s4 s5;"); move_panel(p1, 0, 0); hide_panel(p3); show_panel(p1); show_panel(p2); show_panel(p4); show_panel(p5); pflush(); wait_a_while(nap_msec); saywhat("s1;"); show_panel(p1); pflush(); wait_a_while(nap_msec); saywhat("s2;"); show_panel(p2); pflush(); wait_a_while(nap_msec); saywhat("m2;"); move_panel(p2, 10, 10); pflush(); wait_a_while(nap_msec); saywhat("s3;"); show_panel(p3); pflush(); wait_a_while(nap_msec); saywhat("m3;"); move_panel(p3, 5, 5); pflush(); wait_a_while(nap_msec); saywhat("b3;"); bottom_panel(p3); pflush(); wait_a_while(nap_msec); saywhat("s4;"); show_panel(p4); pflush(); wait_a_while(nap_msec); saywhat("s5;"); show_panel(p5); pflush(); wait_a_while(nap_msec); saywhat("t3;"); top_panel(p3); pflush(); wait_a_while(nap_msec); saywhat("t1;"); top_panel(p1); pflush(); wait_a_while(nap_msec); saywhat("t2;"); top_panel(p2); pflush(); wait_a_while(nap_msec); saywhat("t3;"); top_panel(p3); pflush(); wait_a_while(nap_msec); saywhat("t4;"); top_panel(p4); pflush(); wait_a_while(nap_msec); for (itmp = 0; itmp < 6; itmp++) { saywhat("m4;"); mvwaddstr(w4, 3, 1, mod[itmp]); move_panel(p4, 4, itmp * 10); mvwaddstr(w5, 4, 1, mod[itmp]); pflush(); wait_a_while(nap_msec); saywhat("m5;"); mvwaddstr(w4, 4, 1, mod[itmp]); move_panel(p5, 7, itmp * 10 + 6); mvwaddstr(w5, 3, 1, mod[itmp]); pflush(); wait_a_while(nap_msec); } saywhat("m4;"); move_panel(p4, 4, itmp * 10); pflush(); wait_a_while(nap_msec); saywhat("t5;"); top_panel(p5); pflush(); wait_a_while(nap_msec); saywhat("t2;"); top_panel(p2); pflush(); wait_a_while(nap_msec); saywhat("t1;"); top_panel(p1); pflush(); wait_a_while(nap_msec); saywhat("d2;"); rmpanel(p2); pflush(); wait_a_while(nap_msec); saywhat("h3;"); hide_panel(p3); pflush(); wait_a_while(nap_msec); saywhat("d1;"); rmpanel(p1); pflush(); wait_a_while(nap_msec); saywhat("d4; "); rmpanel(p4); pflush(); wait_a_while(nap_msec); saywhat("d5; "); rmpanel(p5); pflush(); wait_a_while(nap_msec); if (nap_msec == 1) break; nap_msec = 100L; } endwin(); return 0; } /* end of main */
/**************************************************************************** * child() : hold signals, notify parent and wait for parent to send signals. * If none were caught (sighold worked), release the signals one at a time * and wait for them to be caught. Send results back to parent * for processing. ***************************************************************************/ static void child() { int rv; /* return value from sighold() and sigrelse() */ int sig; /* signal value */ int exit_val; /* exit value to send to parent */ char note[MAXMESG]; /* message buffer for pipe */ char *str; phase = 1; /* tell handler that we do not want to catch signals */ /* set note to READY and if an error occurs, overwrite it */ (void)strcpy(note, READY); /* set alarm in case something hangs */ if (set_timeout() < 0) { /* an error occured - put mesg in note and send it back to parent */ (void)strcpy(note, mesg); } else if (setup_sigs() < 0) { /* an error occured - put mesg in note and send it back to parent */ (void)strcpy(note, mesg); } else { /* all set up to catch signals, now hold them */ for (sig = 1; sig < NUMSIGS; sig++) { if (choose_sig(sig)) { if ((rv = sighold(sig)) != 0) { /* THEY say sighold ALWAYS returns 0 */ (void)sprintf(note, "sighold did not return 0. rv:%d", rv); break; } } } } /* * send note to parent (if not READY, parent will BROK) and * wait for parent to send signals. The timeout clock is set so * that we will not wait forever - if sighold() did its job, we * will not receive the signals. If sighold() blew it we will * catch a signal and the interrupt handler will exit with a * value of SIG_CAUGHT. */ if (write_pipe(pipe_fd[1], note) < 0) { /* * write_pipe() failed. Set exit value to WRITE_BROK to let * parent know what happened */ clear_timeout(); exit(WRITE_BROK); } /* * if we get to this point, all signals have been held and the * timer has expired. Now what we want to do is release each * signal and see if we catch it. If we catch all signals, * sigrelse passed, else it failed. */ phase = 2; /* let handler know we are now expecting signals */ #if DEBUG > 0 printf("child: PHASE II\n"); #endif /* assume success and overwrite exit_val if an error occurs */ exit_val = EXIT_OK; #if DEBUG > 0 printf("child: pid=%d waiting for parent's ready...\n", getpid()); #endif /* * wait for parent to tell us that sigals were all sent */ /* wait for "ready" message from parent */ if ((str = read_pipe(pipe_fd2[0])) == NULL) { /* read_pipe() failed. */ printf(" child: read_pipe failed\n"); exit(TBROK); } if (strcmp(str, READY) != 0) { /* parent/pipe problem */ printf("child: didn't proper ready message\n"); exit(TBROK); } for (sig = 1; sig < NUMSIGS; sig++) { if (choose_sig(sig)) { /* all set up, release and catch a signal */ sig_caught = FALSE; /* handler sets it to TRUE when caught */ #if DEBUG > 1 printf("child: releasing sig %d...\n", sig); #endif if ((rv = sigrelse(sig)) != 0) { /* THEY say sigrelse ALWAYS returns 0 */ (void)sprintf(note, "sigrelse did not return 0. rv:%d", rv); exit_val = TBROK; break; } /* give signal handler some time to process signal */ wait_a_while (); } } /* endfor */ /* * If we are error free so far... * check the sig_array array for one occurence of * each of the catchable signals. If this is true, * then PASS, otherwise FAIL. */ if (exit_val == EXIT_OK) { (void)memcpy(note, (char *)sig_array, sizeof(sig_array)); } /* send note to parent and exit */ if (write_pipe(pipe_fd[1], note) < 0) { /* * write_pipe() failed. Set exit value to WRITE_BROK to let * parent know what happened */ exit(WRITE_BROK); } exit(exit_val); } /* end of child */