Exemple #1
0
int
main (int argc, char *argv[])
{
  int rc;
  npth_attr_t tattr;
  int state;
  npth_t tid1, tid2;
  void *retval;

  if (argc >= 2 && !strcmp (argv[1], "--verbose"))
    opt_verbose = 1;

  rc = npth_init ();
  fail_if_err (rc);

  rc = npth_mutex_init (&counter_mutex, NULL);
  fail_if_err (rc);

  rc = npth_attr_init (&tattr);
  fail_if_err (rc);
  rc = npth_attr_getdetachstate (&tattr, &state);
  fail_if_err (rc);
  if ( state != NPTH_CREATE_JOINABLE )
    fail_msg ("new tattr is not joinable");

  info_msg ("creating thread-one");
  rc = npth_create (&tid1, &tattr, thread_one, NULL);
  fail_if_err (rc);
  npth_setname_np (tid1, "thread-one");

  info_msg ("creating thread-two");
  rc = npth_create (&tid2, &tattr, thread_two, NULL);
  fail_if_err (rc);
  npth_setname_np (tid2, "thread-two");

  rc = npth_attr_destroy (&tattr);
  fail_if_err (rc);

  info_msg ("waiting for thread-one to terminate");
  rc = npth_join (tid1, &retval);
  fail_if_err (rc);
  if (retval != (void*)4711)
    fail_msg ("thread-one returned an unexpected value");

  info_msg ("waiting for thread-two to terminate");
  rc = npth_join (tid2, &retval);
  fail_if_err (rc);
  if (retval != (void*)4722)
    fail_msg ("thread-two returned an unexpected value");

  if (counter != 100)
    fail_msg ("counter value not as expected");

  return 0;
}
Exemple #2
0
/* Spawn a new thread to let RUNNER work as a coprocess.  */
gpg_error_t
runner_spawn (runner_t runner)
{
  gpg_error_t err;
  npth_attr_t tattr;
  npth_t thread;
  int ret;

  if (check_already_spawned (runner, "runner_spawn"))
    return gpg_error (GPG_ERR_BUG);

  /* In case we have an input fd, open it as an estream so that the
     Pth scheduling will work.  The stdio functions don't work with
     Pth because they don't call the pth counterparts of read and
     write unless linker tricks are used.  */
  if (runner->in_fd != -1)
    {
      estream_t fp;

      fp = es_fdopen (runner->in_fd, "r");
      if (!fp)
        {
          err = gpg_error_from_syserror ();
          log_error ("can't fdopen pipe for reading: %s\n", gpg_strerror (err));
          return err;
        }
      runner->status_fp = fp;
      runner->in_fd = -1;  /* Now owned by status_fp.  */
    }

  npth_attr_init (&tattr);
  npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);

  ret = npth_create (&thread, &tattr, runner_thread, runner);
  if (ret)
    {
      err = gpg_error_from_errno (ret);
      log_error ("error spawning runner thread: %s\n", gpg_strerror (err));
      return err;
    }
  npth_setname_np (thread, runner->name);

  /* The scheduler has not yet kicked in, thus we can safely set the
     spawned flag and the tid.  */
  runner->spawned = 1;
  runner->thread = thread;
  runner->next_running = running_threads;
  running_threads = runner;

  npth_attr_destroy (&tattr);

  /* The runner thread is now runnable.  */

  return 0;
}
Exemple #3
0
/* Pop up a message window similar to the confirm one but keep it open
   until agent_popup_message_stop has been called.  It is crucial for
   the caller to make sure that the stop function gets called as soon
   as the message is not anymore required because the message is
   system modal and all other attempts to use the pinentry will fail
   (after a timeout). */
int
agent_popup_message_start (ctrl_t ctrl, const char *desc, const char *ok_btn)
{
  int rc;
  char line[ASSUAN_LINELENGTH];
  npth_attr_t tattr;
  int err;

  if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
    return gpg_error (GPG_ERR_CANCELED);

  rc = start_pinentry (ctrl);
  if (rc)
    return rc;

  if (desc)
    snprintf (line, DIM(line)-1, "SETDESC %s", desc);
  else
    snprintf (line, DIM(line)-1, "RESET");
  line[DIM(line)-1] = 0;
  rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
  if (rc)
    return unlock_pinentry (rc);

  if (ok_btn)
    {
      snprintf (line, DIM(line)-1, "SETOK %s", ok_btn);
      line[DIM(line)-1] = 0;
      rc = assuan_transact (entry_ctx, line, NULL,NULL,NULL,NULL,NULL,NULL);
      if (rc)
        return unlock_pinentry (rc);
    }

  err = npth_attr_init (&tattr);
  if (err)
    return unlock_pinentry (gpg_error_from_errno (err));
  npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE);

  popup_finished = 0;
  err = npth_create (&popup_tid, &tattr, popup_message_thread, NULL);
  npth_attr_destroy (&tattr);
  if (err)
    {
      rc = gpg_error_from_errno (err);
      log_error ("error spawning popup message handler: %s\n",
                 strerror (err) );
      return unlock_pinentry (rc);
    }
  npth_setname_np (popup_tid, "popup-message");

  return 0;
}
Exemple #4
0
int main(int argc, char** argv) 
{
  npth_attr_t t_attr1;
  npth_t thread1;
  int i;
  npth_init ();
  for(i = 0; i < 5; i++) {
    npth_attr_init(&t_attr1);
    // N.B.: value i will be always 5 because npth is cooperative, and &i is 
    //       stored in the main thread. (all threads created is  cooperative)
    npth_create(&thread1, &t_attr1, (void *)&print, (void *)&i);
  }
  npth_exit(0);

  return 0;
}
Exemple #5
0
/* Fire up a thread to send (DATA,DATALEN) to the file descriptor FD.
   On success the thread receives the ownership over FD.  The thread
   ID is stored at R_TID.  WRITER_ERR is the address of an gpg_error_t
   variable to receive a possible write error after the thread has
   finished.  */
static gpg_error_t
start_writer (int fd, const void *data, size_t datalen, estream_t stream,
              npth_t *r_thread, gpg_error_t *err_addr)
{
  gpg_error_t err;
  struct writer_thread_parms *parm;
  npth_attr_t tattr;
  npth_t thread;
  int ret;

  memset (r_thread, '\0', sizeof (*r_thread));
  *err_addr = 0;

  parm = xtrymalloc (sizeof *parm);
  if (!parm)
    return my_error_from_syserror ();
  parm->fd = fd;
  parm->data = data;
  parm->datalen = datalen;
  parm->stream = stream;
  parm->err_addr = err_addr;

  npth_attr_init (&tattr);
  npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE);

  ret = npth_create (&thread, &tattr, writer_thread_main, parm);
  if (ret)
    {
      err = my_error_from_errno (ret);
      log_error ("error spawning writer thread: %s\n", gpg_strerror (err));
    }
  else
    {
      npth_setname_np (thread, "fd-writer");
      err = 0;
      *r_thread = thread;
    }
  npth_attr_destroy (&tattr);

  return err;
}
Exemple #6
0
/* Fire up a thread to receive data from the file descriptor FD.  On
   success the thread receives the ownership over FD.  The thread ID
   is stored at R_TID.  After the thread has finished an error from
   the thread will be stored at ERR_ADDR.  */
static gpg_error_t
start_reader (int fd, membuf_t *mb, npth_t *r_thread, gpg_error_t *err_addr)
{
  gpg_error_t err;
  struct reader_thread_parms *parm;
  npth_attr_t tattr;
  npth_t thread;
  int ret;

  memset (r_thread, '\0', sizeof (*r_thread));
  *err_addr = 0;

  parm = xtrymalloc (sizeof *parm);
  if (!parm)
    return gpg_error_from_syserror ();
  parm->fd = fd;
  parm->mb = mb;
  parm->err_addr = err_addr;

  npth_attr_init (&tattr);
  npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE);

  ret = npth_create (&thread, &tattr, reader_thread_main, parm);
  if (ret)
    {
      err = gpg_error_from_errno (ret);
      log_error ("error spawning reader thread: %s\n", gpg_strerror (err));
    }
  else
    {
      npth_setname_np (thread, "fd-reader");
      err = 0;
      *r_thread = thread;
    }
  npth_attr_destroy (&tattr);

  return err;
}
Exemple #7
0
static void *
thread_two (void *arg)
{
  int rc, i;

  info_msg ("thread-two started");

  for (i=0; i < 10; i++)
    {
      rc = npth_mutex_lock (&counter_mutex);
      fail_if_err (rc);

      counter--;

      if (i == 5)
        {
          npth_t tid;

          info_msg ("creating thread-twoone");
          rc = npth_create (&tid, NULL, thread_twoone, NULL);
          fail_if_err (rc);
          npth_usleep (10);  /* Give new thread some time to start.  */
        }

      rc = npth_mutex_unlock (&counter_mutex);
      fail_if_err (rc);
    }

  info_msg ("busy waiting for thread twoone");
  while (!thread_twoone_ready)
    npth_sleep (0);

  info_msg ("thread-two terminated");

  return (void*)4722;
}