コード例 #1
0
ファイル: branch.c プロジェクト: besco/binkd
int branch (register void (*F) (void *), register void *arg, register size_t size)
{
  register int rc;
  char *tmp;

  /* We make our own copy of arg for the child as the parent may destroy it
   * before the child finish to use it. It's not really needed with fork()
   * but we do not want extra checks for HAVE_FORK before free(arg) in the
   * child. */
  if (size > 0)
  {
    if ((tmp = malloc (size)) == NULL)
    {
      Log (1, "malloc failed");
      return -1;
    }
    else
    {
      memcpy (tmp, arg, size);
      arg = tmp;
    }
  }
  else
    arg = 0;

#if defined(HAVE_FORK) && !defined(HAVE_THREADS) && !defined(AMIGA) && !defined(DEBUGCHILD)
again:
  if (!(rc = fork ()))
  {
    /* new process */
    mypid = getpid();
    F (arg);
    exit (0);
  }
  else if (rc < 0)
  {
    if (errno == EINTR) goto again;
    /* parent, error */
    Log (1, "fork: %s", strerror (errno));
  }
  else
  {
    /* parent, free our copy of args */
    xfree (arg);
  }
#endif

#if defined(HAVE_THREADS) && !defined(DEBUGCHILD)
  #ifdef WITH_PTHREADS
  { thread_args_t args;
    pthread_t tid;

    args.F = F;
    args.args = arg;
    InitSem(&args.mutex);
    LockSem(&args.mutex);
    if ((rc = pthread_create (&tid, NULL, thread_start, &args)) != 0)
    {
      Log (1, "pthread_create: %s", strerror (rc));
      rc = -1;
    }
    else
    {
      LockSem(&args.mutex); /* wait until thread releases this mutex */
      #ifdef HAVE_GETTID
      rc = args.tid;
      #else
      rc = (int)(0xffff & (long int)tid);
      #endif
    }
    ReleaseSem(&args.mutex);
    CleanSem(&args.mutex);
  }
  #else
  if ((rc = BEGINTHREAD (F, STACKSIZE, arg)) < 0)
    Log (1, "_beginthread: %s", strerror (errno));
  #endif
#endif

#ifdef AMIGA
  /* this is rather bizzare. this function pretends to be a fork and behaves
   * like one, but actually it's a kind of a thread. so we'll need semaphores */

  if (!(rc = ix_vfork ()))
  {
    vfork_setup_child ();
    ix_vfork_resume ();
    F (arg);
    exit (0);
  }
  else if (rc < 0)
  {
    Log (1, "ix_vfork: %s", strerror (errno));
  }
#endif

#if defined(DOS) || defined(DEBUGCHILD)
  rc = 0;
  F (arg);
#endif

  return rc;
}
コード例 #2
0
ファイル: win9x.c プロジェクト: askovpen/binkd
void CreateWin9xThread(PHANDLER_ROUTINE phandler)
{
        BEGINTHREAD(Win9xWindowThread, 0, phandler);
}