_Unwind_Word
_Unwind_GetCFA (struct _Unwind_Context *context)
{
  if (__builtin_expect (libgcc_s_getcfa == NULL, 0))
    pthread_cancel_init ();
  return libgcc_s_getcfa (context);
}
_Unwind_Reason_Code
_Unwind_ForcedUnwind (struct _Unwind_Exception *exc, _Unwind_Stop_Fn stop,
		      void *stop_argument)
{
  if (__builtin_expect (libgcc_s_forcedunwind == NULL, 0))
    pthread_cancel_init ();
  return libgcc_s_forcedunwind (exc, stop, stop_argument);
}
_Unwind_Reason_Code
__gcc_personality_v0 (_Unwind_State state,
		      struct _Unwind_Exception *ue_header,
		      struct _Unwind_Context *context)
{
  if (__builtin_expect (libgcc_s_personality == NULL, 0))
    pthread_cancel_init ();
  return libgcc_s_personality (state, ue_header, context);
}
static int
live_server_start(void *arg) {
    pthread_cancel_init();
    if(pthread_create(&server_tid, NULL, liveserver_main, NULL) != 0) {
        ga_error("start live-server failed.\n");
        return -1;
    }
    return 0;
}
Exemplo n.º 5
0
void
_Unwind_Resume (struct _Unwind_Exception *exc)
{
  if (__builtin_expect (libgcc_s_handle == NULL, 0))
    pthread_cancel_init ();
  else
    atomic_read_barrier ();

  void (*resume) (struct _Unwind_Exception *exc) = libgcc_s_resume;
  PTR_DEMANGLE (resume);
  resume (exc);
}
Exemplo n.º 6
0
_Unwind_Word
_Unwind_GetCFA (struct _Unwind_Context *context)
{
  if (__builtin_expect (libgcc_s_handle == NULL, 0))
    pthread_cancel_init ();
  else
    atomic_read_barrier ();

  _Unwind_Word (*getcfa) (struct _Unwind_Context *) = libgcc_s_getcfa;
  PTR_DEMANGLE (getcfa);
  return getcfa (context);
}
Exemplo n.º 7
0
void
_Unwind_Resume (struct _Unwind_Exception *exc)
{
  if (__glibc_unlikely (libgcc_s_handle == NULL))
    pthread_cancel_init ();
  else
    atomic_read_barrier ();

  void (*resume) (struct _Unwind_Exception *exc) = __libgcc_s_resume;
  PTR_DEMANGLE (resume);
  resume (exc);
}
Exemplo n.º 8
0
_Unwind_Reason_Code
_Unwind_ForcedUnwind (struct _Unwind_Exception *exc, _Unwind_Stop_Fn stop,
		      void *stop_argument)
{
  if (__builtin_expect (libgcc_s_handle == NULL, 0))
    pthread_cancel_init ();
  else
    atomic_read_barrier ();

  _Unwind_Reason_Code (*forcedunwind)
    (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *)
    = libgcc_s_forcedunwind;
  PTR_DEMANGLE (forcedunwind);
  return forcedunwind (exc, stop, stop_argument);
}
Exemplo n.º 9
0
_Unwind_Reason_Code
__gcc_personality_v0 (int version, _Unwind_Action actions,
		      _Unwind_Exception_Class exception_class,
		      struct _Unwind_Exception *ue_header,
		      struct _Unwind_Context *context)
{
  if (__builtin_expect (libgcc_s_handle == NULL, 0))
    pthread_cancel_init ();
  else
    atomic_read_barrier ();

  _Unwind_Reason_Code (*personality)
    (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
     struct _Unwind_Context *) = libgcc_s_personality;
  PTR_DEMANGLE (personality);
  return personality (version, actions, exception_class, ue_header, context);
}
Exemplo n.º 10
0
int
pthread_cancel (pthread_t th)
{
  volatile struct pthread *pd = (volatile struct pthread *) th;

  /* Make sure the descriptor is valid.  */
  if (INVALID_TD_P (pd))
    /* Not a valid thread handle.  */
    return ESRCH;

#ifdef SHARED
  pthread_cancel_init ();
#endif
  int result = 0;
  int oldval;
  int newval;
  do
    {
    again:
      oldval = pd->cancelhandling;
      newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK;

      /* Avoid doing unnecessary work.  The atomic operation can
	 potentially be expensive if the bug has to be locked and
	 remote cache lines have to be invalidated.  */
      if (oldval == newval)
	break;

      /* If the cancellation is handled asynchronously just send a
	 signal.  We avoid this if possible since it's more
	 expensive.  */
      if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
	{
	  /* Mark the cancellation as "in progress".  */
	  if (atomic_compare_and_exchange_bool_acq (&pd->cancelhandling,
						    oldval | CANCELING_BITMASK,
						    oldval))
	    goto again;

#ifdef SIGCANCEL
	  /* The cancellation handler will take care of marking the
	     thread as canceled.  */
	  pid_t pid = getpid ();

	  INTERNAL_SYSCALL_DECL (err);
	  int val = INTERNAL_SYSCALL_CALL (tgkill, err, pid, pd->tid,
					   SIGCANCEL);
	  if (INTERNAL_SYSCALL_ERROR_P (val, err))
	    result = INTERNAL_SYSCALL_ERRNO (val, err);
#else
          /* It should be impossible to get here at all, since
             pthread_setcanceltype should never have allowed
             PTHREAD_CANCEL_ASYNCHRONOUS to be set.  */
          abort ();
#endif

	  break;
	}

	/* A single-threaded process should be able to kill itself, since
	   there is nothing in the POSIX specification that says that it
	   cannot.  So we set multiple_threads to true so that cancellation
	   points get executed.  */
	THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1);
#ifndef TLS_MULTIPLE_THREADS_IN_TCB
	__pthread_multiple_threads = *__libc_multiple_threads_ptr = 1;
#endif
    }
  /* Mark the thread as canceled.  This has to be done
     atomically since other bits could be modified as well.  */
  while (atomic_compare_and_exchange_bool_acq (&pd->cancelhandling, newval,
					       oldval));

  return result;
}
Exemplo n.º 11
0
int
pthread_cancel (
    pthread_t th)
{
    volatile struct pthread *pd = (volatile struct pthread *) th;

    /* Make sure the descriptor is valid.  */
    if (INVALID_TD_P (pd))
        /* Not a valid thread handle.  */
        return ESRCH;

#ifdef SHARED
    pthread_cancel_init ();
#endif
    int result = 0;
    int oldval;
    int newval;
    do
    {
again:
        oldval = pd->cancelhandling;
        newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK;

        /* Avoid doing unnecessary work.  The atomic operation can
        potentially be expensive if the bug has to be locked and
         remote cache lines have to be invalidated.  */
        if (oldval == newval)
            break;

        /* If the cancellation is handled asynchronously just send a
        signal.  We avoid this if possible since it's more
         expensive.  */
        if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
        {
            /* Mark the cancellation as "in progress".  */
            if (atomic_compare_and_exchange_bool_acq (&pd->cancelhandling,
                    oldval | CANCELING_BITMASK,
                    oldval))
                goto again;

            /* The cancellation handler will take care of marking the
               thread as canceled.  */
            INTERNAL_SYSCALL_DECL (err);

            /* One comment: The PID field in the TCB can temporarily be
               changed (in fork).  But this must not affect this code
               here.  Since this function would have to be called while
               the thread is executing fork, it would have to happen in
               a signal handler.  But this is no allowed, pthread_cancel
               is not guaranteed to be async-safe.  */
            int val;
#if defined(__ASSUME_TGKILL) && __ASSUME_TGKILL
            val = INTERNAL_SYSCALL (tgkill, err, 3,
                                    THREAD_GETMEM (THREAD_SELF, pid), pd->tid,
                                    SIGCANCEL);
#else
# ifdef __NR_tgkill
            val = INTERNAL_SYSCALL (tgkill, err, 3,
                                    THREAD_GETMEM (THREAD_SELF, pid), pd->tid,
                                    SIGCANCEL);
            if (INTERNAL_SYSCALL_ERROR_P (val, err)
                    && INTERNAL_SYSCALL_ERRNO (val, err) == ENOSYS)
# endif
                val = INTERNAL_SYSCALL (tkill, err, 2, pd->tid, SIGCANCEL);
#endif

            if (INTERNAL_SYSCALL_ERROR_P (val, err))
                result = INTERNAL_SYSCALL_ERRNO (val, err);

            break;
        }
    }
    /* Mark the thread as canceled.  This has to be done
       atomically since other bits could be modified as well.  */
    while (atomic_compare_and_exchange_bool_acq (&pd->cancelhandling, newval,
            oldval));

    return result;
}