示例#1
0
extern void send_dummy_signal (void) {
  /* Activate signal handling if necessary*/
  activate_signal_handling ();
  (void) kill (getpid(), SIGDUMMY);
}
示例#2
0
extern int evt_wait (int *p_fd, boolean *p_read, timeout_t *timeout) {
  fd_set select_read_mask, select_write_mask;
  timeout_t exp_time, *timeout_ptr;
  boolean timeout_is_active;
  int start_fd;
  int n;
  ssize_t size;
  char c;

  /* Activate signal handling if necessary*/
  activate_signal_handling ();

  /* Compute exp_time = cur_time + timeout_ms */
  timeout_is_active = (timeout->tv_sec >= 0) && (timeout->tv_usec >= 0);
  if (timeout_is_active) {
    get_time (&exp_time);
    add_time (&exp_time, timeout);
    timeout_ptr = timeout;
  } else {
    timeout_ptr = NULL;
  }

  /* Init wake-up pipe */
  init_sig_and_wake_up ();

  for (;;) {

    /* Check for signal */
    if (check_signal() ) {
      *p_fd = SIG_EVENT;
      evt_time_remaining (timeout, &exp_time);
      return (WAIT_OK);
    }

    /* Copy select mask */
    memcpy (&select_read_mask,  &global_read_mask,  sizeof(fd_set));
    memcpy (&select_write_mask, &global_write_mask, sizeof(fd_set));

    /* Default result */
    *p_fd = NO_EVENT;
    *p_read = TRUE;

    /* Compute select timeout */
    if (timeout_is_active) {
      evt_time_remaining (timeout, &exp_time);
    }

    /* The select */
    n = select (last_fd + 1, &select_read_mask,
                             &select_write_mask, NULL, timeout_ptr);

    if (n > 0) {
      /* Start from 0 or from prev fd + 1 (round robin) */
      if (n == 1) {
        start_fd = 0;
      } else {
        start_fd = (prev_fd + 1) % (last_fd + 1);
      }

      /* Check read events first */
      *p_fd = check_fd (start_fd, &select_read_mask);
      if (*p_fd != NO_EVENT) {
         *p_read = TRUE;
      } else {
        /* Check write events second */
        *p_read = FALSE;
        *p_fd = check_fd (start_fd, &select_write_mask);
      }

      /* Check if p_fd is wake-up fd) */
      if (*p_fd == wake_up_fds[0] ) {
        for (;;) {
          size = read (wake_up_fds[0], &c, sizeof(c));
          if ( (size == -1) && (errno != EINTR) ) {
#ifdef DEBUG
            perror ("read");
#endif
            break;
          }
          if (size == 1) {
            break;
          }
        }
        *p_fd = WAKE_EVENT;
      } else if (*p_fd == NO_EVENT) {
#ifdef DEBUG
        fprintf (stderr, "No fd found\n");
#endif
        return (WAIT_ERR);
      }

      prev_fd = *p_fd;
      if (prev_fd < -1) {
        /* Not a fd => end of round robin */
        prev_fd = -1;
      }
      evt_time_remaining (timeout, &exp_time);
      return (WAIT_OK);

    } else if (n < 0) {
      if (errno != EINTR) {
        /* Real error */
#ifdef DEBUG
          perror ("select");
#endif
        return (WAIT_ERR);
      }
    }

    /* Check for timeout reached */
    if ( (!check_signal())
        && timeout_is_active
        && time_is_reached (&exp_time) ) {
      /* Done on timeout */
      *p_fd = NO_EVENT;
      timeout->tv_sec = 0;
      timeout->tv_usec = 0;
      return (WAIT_OK);
    }

  } /* for (;;) */
}
示例#3
0
文件: delta_time.c 项目: malaise/c
/* THE MAIN */
int main (const int argc, const char * argv[]) {

  /* Socket data */
  soc_token soc = init_soc;
  soc_host lan;
  soc_port port;
  int soc_fd, fd;

  /* Socket message */
  msg_type msg;

  /* Times and timeouts */
  timeout_t start_time, end_time, current_time;
  timeout_t wait_timeout;
  double local_time, remote_time;

  /* Dynamic list of server infos */
  dlist list;
  info_type info;

  /* Utilities */
  boolean for_read;
  char buff[256];
  int res;
  char *index;

  /*********/
  /* Start */
  /*********/
  /* Save prog name */
  strcpy (prog, argv[0]);
  strcpy (prog, basename (prog));

  /*******************/
  /* Parse arguments */
  /*******************/
  /* Check args */
  if (argc != 2) {
    error ("Invalid argument");
  }
  /* Parse IPM address and port */
  strcpy (buff, argv[1]);
  index = strstr (buff, ":");
  if (index == NULL) {
     error ("Invalid argument");
  }
  *index = '\0';
  index++;
  if (soc_str2host (buff, &lan) != SOC_OK) {
    sprintf (buff, "Invalid ipm address %s", buff);
    error (buff);
  }
  if (soc_str2port (index, &port) != SOC_OK) {
    sprintf (buff, "Invalid port num %s", index);
    error (buff);
  }

  /**************/
  /* Initialize */
  /**************/
  /* Init dynamic list */
  dlist_init (& list, sizeof(info_type));
  /* Init socket */
  if (soc_open (&soc, udp_socket) != SOC_OK) {
    perror ("opening socket");
    error ("Socket initialization failed");
  }
  if (soc_set_dest_host_port (soc, &lan, port) != SOC_OK) {
    perror ("setting destination");
    error ("Socket initialization failed");
  }
  if (soc_link_port (soc, port) != SOC_OK) {
    perror ("linking to port");
    error ("Socket initialization failed");
  }
  if (soc_get_dest_host (soc, &lan) != SOC_OK) {
    perror ("getting dest lan");
    error ("Socket initialization failed");
  }
  if (soc_get_dest_port (soc, &port) != SOC_OK) {
    perror ("getting dest port");
    error ("Socket initialization failed");
  }
  /* Add socket to waiting point */
  if (soc_get_id(soc, &soc_fd) != SOC_OK) {
    perror ("getting socket id");
    error ("Socket initialization failed");

  }
  if (evt_add_fd(soc_fd, TRUE) != WAIT_OK) {
    perror("Adding fd");
    error ("Socket initialization failed");
  }
  /* Activate signal catching */
  activate_signal_handling();
  /* Report starting */
  buff[0]='\0';
  addr_image (&lan, buff);
  printf ("%s mcasting at address %s on port %d.\n", prog, buff, (int) port);
  /* Init times */
  get_time (&start_time);
  current_time = start_time;
  end_time = start_time;
  incr_time (&end_time, DELAY_CLIENT_MS);
  /* Send initial ping request */
  msg.ping = TRUE;
  msg.time = start_time;
  if (soc_send (soc, (soc_message) &msg, sizeof(msg)) != SOC_OK) {
    perror ("sending ping");
    error ("Sending ping request failed");
  }

  /*************/
  /* Main loop */
  /*************/
  for (;;) {
    /* First step is to loop until timeout */
    if (wait_timeout.tv_sec != -1) {
      wait_timeout = end_time;
      res = sub_time (&wait_timeout, &current_time);
      if (res <= 0) {
        break;
      }
    }
    if (evt_wait (&fd, &for_read, &wait_timeout) != WAIT_OK) {
      perror ("waiting for event");
      error ("Waiting for events failed");
    }
    if (! for_read) {
      error ("Write event received");
    }
    /* Termination signal */
    if (fd == SIG_EVENT) {
      if (get_signal () == SIG_TERMINATE) {
        break;
      }
    } else if (fd == NO_EVENT) {
      /* Timeout: first step ends with a dump of servers */
      if (dlist_length(&list) != 0) {
        dlist_rewind (&list, TRUE);
        for (;;) {
          dlist_read (&list, &info);
          /* Get host name if possible, else dump address */
          res = soc_host_name_of (&info.host, buff, sizeof(buff));
          if (res != SOC_OK) {
            buff[0]='\0';
            addr_image (&info.host, buff);
          }
          /* Compute (Start_time + Reception_time) / 2 */
          local_time = (time_to_double (&start_time)
                        + time_to_double (&info.reception_time) ) / 2.0;
          remote_time = time_to_double (&info.server_time);
          printf ("Host %s is shifted by %4.03fs\n", buff, remote_time - local_time);

          /* Done when last record has been put */
          if (dlist_get_pos (&list, FALSE) == 1) {
            break;
          }
          dlist_move (&list, TRUE);
        }
      }
      /* Now entering second step: infinite timeout */
      wait_timeout.tv_sec = -1;
      wait_timeout.tv_usec = -1;
      printf ("%s ready.\n", prog);
    } else if (fd != soc_fd) {
      sprintf (buff, "Invalid fd %d received", fd);
      error (buff);
    } else {
      /* Now this is the socket, read message */
      res = soc_receive (soc, (soc_message) &msg, sizeof(msg), TRUE);
      if (res < 0) {
        perror ("reading from socket");
        error ("Reading message failed");
      } else if (res != sizeof(msg)) {
        sprintf (buff, "Invalid size received, expected %d, got %d",
                       (int)sizeof(msg), res);
        error (buff);
      }
      get_time (&current_time);
      /* Client and server different behaviours */
      if ((wait_timeout.tv_sec != -1) && !msg.ping) {
        /* First step: store the address and time of server, if pong */
        if (soc_get_dest_host (soc, &(info.host)) != SOC_OK) {
          perror ("getting dest host");
          error ("Getting server address failed");
        }
        info.server_time = msg.time;
        info.reception_time = current_time;
        dlist_insert (&list, &info, TRUE);

      } else if ( (wait_timeout.tv_sec == -1) && msg.ping) {
        /* Second step: reply pong and time to ping */
        msg.time = current_time;
        msg.ping = FALSE;
        if (soc_send (soc, (soc_message) &msg, sizeof(msg)) != SOC_OK) {
          perror ("sending pong");
          error ("Sending pong request failed");
        }
      }
    }
  } /* End of main loop */


  /* Clean - Close */
  dlist_delete_all (&list);
  (void) evt_del_fd (soc_fd, TRUE);
  (void) soc_close (&soc);
  printf ("Done.\n");
  exit (0);
}