Beispiel #1
0
static void *philosopher(void *_who)
{
    unsigned int *who = (unsigned int *)_who;

    /* For simplicity, all philosophers eat for the same amount of time
       and think for a time that is simply related to their position at
       the table. The parameter who identifies the philosopher: 0,1,2,.. */
    for (;;) {
        pth_sleep((*who) + 1);
        pickup((*who));
        pth_sleep(1);
        putdown((*who));
    }
    return NULL;
}
int main(int argc, char **argv) {
    long num_threads;

    if (argc != 2) {
        fprintf(stderr, "Usage: %s num_threads\n", argv[0]);
        exit(1);
    }

    num_threads = strtol(argv[1], NULL, 10);
    printf("Using %ld threads\n", num_threads);

    pth_init();

    for (long i = 1; i <= num_threads; i++) {
        char *name = malloc(1024);
        sprintf(name, "busy%ld", i);
        pth_t t = spawn_with_attr(name, 1, 5, busy_thread, NULL);
        printf("Spawned thread #%ld with id %p\n", i, t);
        free(name);
    }

    printf("main thread now sleeping for %d seconds...\n", TEST_LENGTH);
    pth_sleep(TEST_LENGTH);

    pth_kill();

    return 0;
}
Beispiel #3
0
/* a useless ticker thread */
static void *ticker(void *_arg)
{
    time_t now;
    fprintf(stderr, "ticker: start\n");
    for (;;) {
        pth_sleep(5);
        now = time(NULL);
        fprintf(stderr, "ticker was woken up on %s", ctime(&now));
    }
    /* NOTREACHED */
    return NULL;
}
int main(void) {
    pth_init();

    pth_t t1 = spawn_with_attr("busy", 1, 2, busy_thread, NULL);
    printf("Spawned busy thread with id %p\n", t1);
    pth_t t2 = spawn_with_attr("nice", 1, 2, nice_thread, NULL);
    printf("Spawned nice thread with id %p\n", t2);

    printf("main thread now sleeping for %d seconds...\n", TEST_LENGTH);
    pth_sleep(TEST_LENGTH);

    pth_kill();

    return 0;
}
Beispiel #5
0
static void *ticker(void *_arg)
{
    time_t now;
    char *ct;
    float avload;

    for (;;) {
        pth_sleep(5);
        now = time(NULL);
        ct = ctime(&now);
        ct[strlen(ct)-1] = NUL;
        pth_ctrl(PTH_CTRL_GETAVLOAD, &avload);
        fprintf(stderr, "ticker woken up on %s, average load: %.2f\n",
                ct, avload);
    }
    /* NOTREACHED */
    return NULL;
}
Beispiel #6
0
static void *child(void *_arg)
{
    sigset_t sigs;
    char *name = (char *)_arg;
    int i;

    fprintf(stderr, "%s: enter\n", name);

    /* establish cleanup handler */
    pth_cleanup_push(child_cleanup, name);

    /* block different types of signals */
    pth_sigmask(SIG_SETMASK, NULL, &sigs);
    sigaddset(&sigs, SIGINT);
    if (strcmp(name, "child1") == 0) {
        sigaddset(&sigs, SIGUSR1);
        sigdelset(&sigs, SIGUSR2);
    }
    else {
        sigdelset(&sigs, SIGUSR1);
        sigaddset(&sigs, SIGUSR2);
    }
    pth_sigmask(SIG_SETMASK, &sigs, NULL);

    /* do a little bit of processing and show signal states */
    for (i = 0; i < 10; i++) {
        pth_sigmask(SIG_SETMASK, NULL, &sigs);
        fprintf(stderr, "%s: SIGUSR1: %s\n", name,
                sigismember(&sigs, SIGUSR1) ? "blocked" : "unblocked");
        fprintf(stderr, "%s: SIGUSR2: %s\n", name,
                sigismember(&sigs, SIGUSR2) ? "blocked" : "unblocked");
        fprintf(stderr, "%s: leave to scheduler\n", name);
        pth_sleep(1);
        fprintf(stderr, "%s: reentered from scheduler\n", name);
    }

    fprintf(stderr, "%s: leave\n", name);
    return NULL;
}
Beispiel #7
0
/* Unprotect the canconical encoded S-expression key in KEYBUF.  GRIP
   should be the hex encoded keygrip of that key to be used with the
   caching mechanism. DESC_TEXT may be set to override the default
   description used for the pinentry.  If LOOKUP_TTL is given this
   function is used to lookup the default ttl. */
static int
unprotect (ctrl_t ctrl, const char *desc_text,
           unsigned char **keybuf, const unsigned char *grip,
           cache_mode_t cache_mode, lookup_ttl_t lookup_ttl)
{
  struct pin_entry_info_s *pi;
  struct try_unprotect_arg_s arg;
  int rc;
  unsigned char *result;
  size_t resultlen;
  char hexgrip[40+1];

  bin2hex (grip, 20, hexgrip);

  /* First try to get it from the cache - if there is none or we can't
     unprotect it, we fall back to ask the user */
  if (cache_mode != CACHE_MODE_IGNORE)
    {
      void *cache_marker;
      const char *pw;

    retry:
      pw = agent_get_cache (hexgrip, cache_mode, &cache_marker);
      if (pw)
        {
          rc = agent_unprotect (*keybuf, pw, NULL, &result, &resultlen);
          agent_unlock_cache_entry (&cache_marker);
          if (!rc)
            {
              xfree (*keybuf);
              *keybuf = result;
              return 0;
            }
          rc  = 0;
        }

      /* If the pinentry is currently in use, we wait up to 60 seconds
         for it to close and check the cache again.  This solves a common
         situation where several requests for unprotecting a key have
         been made but the user is still entering the passphrase for
         the first request.  Because all requests to agent_askpin are
         serialized they would then pop up one after the other to
         request the passphrase - despite that the user has already
         entered it and is then available in the cache.  This
         implementation is not race free but in the worst case the
         user has to enter the passphrase only once more. */
      if (pinentry_active_p (ctrl, 0))
        {
          /* Active - wait */
          if (!pinentry_active_p (ctrl, 60))
            {
              /* We need to give the other thread a chance to actually put
                 it into the cache. */
              pth_sleep (1);
              goto retry;
            }
          /* Timeout - better call pinentry now the plain way. */
        }
    }

  pi = gcry_calloc_secure (1, sizeof (*pi) + 100);
  if (!pi)
    return gpg_error_from_syserror ();
  pi->max_length = 100;
  pi->min_digits = 0;  /* we want a real passphrase */
  pi->max_digits = 16;
  pi->max_tries = 3;
  pi->check_cb = try_unprotect_cb;
  arg.ctrl = ctrl;
  arg.protected_key = *keybuf;
  arg.unprotected_key = NULL;
  arg.change_required = 0;
  pi->check_cb_arg = &arg;

  rc = agent_askpin (ctrl, desc_text, NULL, NULL, pi);
  if (!rc)
    {
      assert (arg.unprotected_key);
      if (arg.change_required)
        {
          size_t canlen, erroff;
          gcry_sexp_t s_skey;

          assert (arg.unprotected_key);
          canlen = gcry_sexp_canon_len (arg.unprotected_key, 0, NULL, NULL);
          rc = gcry_sexp_sscan (&s_skey, &erroff,
                                (char*)arg.unprotected_key, canlen);
          if (rc)
            {
              log_error ("failed to build S-Exp (off=%u): %s\n",
                         (unsigned int)erroff, gpg_strerror (rc));
              wipememory (arg.unprotected_key, canlen);
              xfree (arg.unprotected_key);
              xfree (pi);
              return rc;
            }
          rc = agent_protect_and_store (ctrl, s_skey);
          gcry_sexp_release (s_skey);
          if (rc)
            {
              log_error ("changing the passphrase failed: %s\n",
                         gpg_strerror (rc));
              wipememory (arg.unprotected_key, canlen);
              xfree (arg.unprotected_key);
              xfree (pi);
              return rc;
            }
        }
      else
        agent_put_cache (hexgrip, cache_mode, pi->pin,
                         lookup_ttl? lookup_ttl (hexgrip) : 0);
      xfree (*keybuf);
      *keybuf = arg.unprotected_key;
    }
  xfree (pi);
  return rc;
}
Beispiel #8
0
int main(int argc, char *argv[])
{
    struct sockaddr_in sar;
    struct protoent *pe;
    struct sockaddr_in peer_addr;
    socklen_t peer_len;
    int sr;
    int port;

    /* initialize scheduler */
    pth_init();
    signal(SIGPIPE, SIG_IGN);
    signal(SIGINT,  myexit);
    signal(SIGTERM, myexit);

    /* argument line parsing */
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <port>\n", argv[0]);
        exit(1);
    }
    port = atoi(argv[1]);
    if (port <= 0 || port >= 65535) {
        fprintf(stderr, "Illegal port: %d\n", port);
        exit(1);
    }

    fprintf(stderr, "This is TEST_HTTPD, a Pth test using socket I/O.\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "Multiple connections are accepted on the specified port.\n");
    fprintf(stderr, "For each connection a separate thread is spawned which\n");
    fprintf(stderr, "reads a HTTP request the socket and writes back a constant\n");
    fprintf(stderr, "(and useless) HTTP response to the socket.\n");
    fprintf(stderr, "Additionally a useless ticker thread awakens every 5s.\n");
    fprintf(stderr, "Watch the average scheduler load the ticker displays.\n");
    fprintf(stderr, "Hit CTRL-C for stopping this test.\n");
    fprintf(stderr, "\n");

    /* run a just for fun ticker thread */
    attr = pth_attr_new();
    pth_attr_set(attr, PTH_ATTR_NAME, "ticker");
    pth_attr_set(attr, PTH_ATTR_JOINABLE, FALSE);
    pth_attr_set(attr, PTH_ATTR_STACK_SIZE, 64*1024);
    pth_spawn(attr, ticker, NULL);

    /* create TCP socket */
    if ((pe = getprotobyname("tcp")) == NULL) {
        perror("getprotobyname");
        exit(1);
    }
    if ((s = socket(AF_INET, SOCK_STREAM, pe->p_proto)) == -1) {
        perror("socket");
        exit(1);
    }

    /* bind socket to port */
    sar.sin_family      = AF_INET;
    sar.sin_addr.s_addr = INADDR_ANY;
    sar.sin_port        = htons(port);
    if (bind(s, (struct sockaddr *)&sar, sizeof(struct sockaddr_in)) == -1) {
        perror("socket");
        exit(1);
    }

    /* start listening on the socket with a queue of 10 */
    if (listen(s, REQ_MAX) == -1) {
        perror("listen");
        exit(1);
    }

    /* finally loop for requests */
    pth_attr_set(attr, PTH_ATTR_NAME, "handler");
    fprintf(stderr, "listening on port %d (max %d simultaneous connections)\n", port, REQ_MAX);
    for (;;) {
        /* accept next connection */
        peer_len = sizeof(peer_addr);
        if ((sr = pth_accept(s, (struct sockaddr *)&peer_addr, &peer_len)) == -1) {
            perror("accept");
            pth_sleep(1);
            continue;
        }
        if (pth_ctrl(PTH_CTRL_GETTHREADS) >= REQ_MAX) {
            fprintf(stderr, "currently no more connections acceptable\n");
            continue;
        }
        fprintf(stderr, "connection established (fd: %d, ip: %s, port: %d)\n",
                sr, inet_ntoa(peer_addr.sin_addr), ntohs(peer_addr.sin_port));

        /* spawn new handling thread for connection */
        pth_spawn(attr, handler, (void *)((long)sr));
    }

}
Beispiel #9
0
LowLevelDriver *
initUSBDriver (LowLevelDriver * i, Trace * tr)
{
  CArray r1, *r = 0;
  LowLevelDriver *iface;
  uchar emiver;
  int cnt = 0;
  const uchar ask[64] = {
    0x01, 0x13, 0x09, 0x00, 0x08, 0x00, 0x01, 0x0f, 0x01, 0x00, 0x00, 0x01
  };
  uchar init[64] = {
    0x01, 0x13, 0x0a, 0x00, 0x08, 0x00, 0x02, 0x0f, 0x03, 0x00, 0x00, 0x05,
    0x01
  };

  if (!i->init ())
    {
      delete i;
      return 0;
    }

  do
    {
      cnt++;
      i->Send_Packet (CArray (ask, sizeof (ask)));
      do
	{
	  r = i->Get_Packet (0);
	  if (r)
	    {
	      r1 = *r;
	      if (r1 () != 64)
		goto cont;
	      if (r1[0] != 01)
		goto cont;
	      if ((r1[1] & 0x0f) != 0x03)
		goto cont;
	      if (r1[2] != 0x0b)
		goto cont;
	      if (r1[3] != 0x00)
		goto cont;
	      if (r1[4] != 0x08)
		goto cont;
	      if (r1[5] != 0x00)
		goto cont;
	      if (r1[6] != 0x03)
		goto cont;
	      if (r1[7] != 0x0F)
		goto cont;
	      if (r1[8] != 0x02)
		goto cont;
	      if (r1[11] != 0x01)
		goto cont;
	      break;
	    cont:
	      delete r;
	      r = 0;
	    }
	}
      while (!r);
      delete r;
      if (r1[13] & 0x2)
	emiver = 2;
      else if (r1[13] & 0x1)
	emiver = 1;
      else if (r1[13] & 0x4)
	emiver = 3;
      else
	emiver = 0;
      if (emiver == 0 && cnt < 5)
	pth_sleep (5);
    }
  while (emiver == 0 && cnt < 5);

  switch (emiver)
    {
    case 1:
      init[12] = 1;
      i->Send_Packet (CArray (init, sizeof (init)));
      iface =
	new USBConverterInterface (i, tr, LowLevelDriver::vEMI1);
      break;
    case 2:
      init[12] = 2;
      i->Send_Packet (CArray (init, sizeof (init)));
      iface =
	new USBConverterInterface (i, tr, LowLevelDriver::vEMI2);
      break;
    case 3:
      init[12] = 3;
      i->Send_Packet (CArray (init, sizeof (init)));
      iface =
	new USBConverterInterface (i, tr, LowLevelDriver::vCEMI);
      break;
    default:
      TRACEPRINTF (tr, 1, i, "Unsupported EMI %02x %02x", r1[12], r1[13]);
      delete i;
      return 0;
    }
  return iface;
}