Exemplo n.º 1
0
int
ldap_int_thread_destroy( void )
{
#ifdef HAVE_PTHREAD_KILL_OTHER_THREADS_NP
	/* LinuxThreads: kill clones */
	pthread_kill_other_threads_np();
#endif
	LDAP_ENSURE( pthread_mutexattr_destroy( &mutex_attr_errorcheck ) == 0);
	return 0;
}
Exemplo n.º 2
0
int
ldap_int_thread_destroy( void )
{
#ifdef HAVE_PTHREAD_KILL_OTHER_THREADS_NP
	/* LinuxThreads: kill clones */
	pthread_kill_other_threads_np();
#endif
#ifdef LDAP_INT_THREAD_MUTEXATTR
	pthread_mutexattr_destroy( &mutex_attr );
#endif
	return 0;
}
static void xkb_free(Control *ctrl) {
  terminate();
  pthread_kill_other_threads_np();
  deinitialize_xkb();

  t_xkb *xkb;

  g_return_if_fail(ctrl != NULL);
  g_return_if_fail(ctrl->data != NULL);

  xkb = (t_xkb *)ctrl->data;

  g_free(xkb);
}
Exemplo n.º 4
0
/**
 * Kill all other threads.
 *
 * THREADS: MT-SAFE
 *
 * This should be called prior to any call to exit/exec, and is abused by
 * bk_general_destroy to prevent concurrent access to bk_general by terminating
 * rival threads with extreme prejudice.
 *
 * @param B BAKA Thread/global state
 * @param flags Flags for the future (avoid pthread_kill_other_threads_np()?)
 */
void bk_thread_kill_others(bk_s B, bk_flags flags)
{
  BK_ENTRY_VOLATILE(B, __FUNCTION__, __FILE__, "libbk");

#ifdef HAVE_PTHREAD_KILL_OTHER_THREADS_NP
  /*
   * <WARNING bugid="1281">
   * Using pthread_kill_other_threads_np is only necessary on Linux (or any
   * platform that doesn't comply with the POSIX requirement that exec/exit
   * terminate all threads - fortunately, Linux is unique in that respect).
   *
   * Even on Linux, this should really be called *after* iterating through the
   * thread list, not *instead of*, since it prevents thread cancellation
   * handlers cancellation etc. etc. but I just want to compile on *BSD without
   * giving anyone a "false sense of security."  So we'll let the users on *BSD
   * find out if this code works, unless a Linux user hangs first because of a
   * mutex held by another thread killed by pthread_kill_other_threads_np.
   * </WARNING>
   */
  pthread_kill_other_threads_np();
#else /* HAVE_PTHREAD_KILL_OTHER_THREADS_NP */
  struct bk_threadlist * volatile tlist;
  struct bk_threadnode *tnode;
  dict_iter iter;

  if ((tlist = BK_GENERAL_TLIST(B)))
  {
    /*
     * <TRICKY>If multiple threads call this at the same time, we need to
     * make sure that only one of them cancels the other threads; all the
     * others should be cancelled by the one that won the race.
     *
     * We do this by checking for cancellation once tlist->btl_lock is held;
     * the cleanup handler makes sure that this thread will release the lock if
     * it lost the race and was cancelled.</TRICKY>
     */

    if (pthread_mutex_lock(&tlist->btl_lock))
      abort();

    pthread_cleanup_push(bk_thread_unlock, &tlist->btl_lock);
    pthread_testcancel();
    pthread_cleanup_pop(0);			// don't unlock yet

    iter = btl_iterate(tlist->btl_list, DICT_FROM_START);
    while ((tnode = btl_nextobj(tlist->btl_list, iter)))
    {
      if (BK_FLAG_ISCLEAR(tnode->btn_flags, BK_THREADNODE_FLAG_CANCELED) &&
	  !pthread_equal(tnode->btn_thid, pthread_self()))
      {
	bk_thread_cancel(B, tnode->btn_thid, 0);
      }
    }
    btl_iterate_done(tlist->btl_list, iter);

    /*
     * We have cancelled all existing baka threads; now we have to wait for
     * them to reach cancellation points and take themselves off the thread
     * list.  (No new threads should be created, since bk_thread_create has a
     * cancellation point that will prevent it from creating a new thread if
     * the existing one is cancelled).
     */
    do
    {
      tnode = btl_minimum(tlist->btl_list);

      // is this thread the only one on the list?
      if (!tnode || (pthread_equal(tnode->btn_thid, pthread_self()) &&
		     !(btl_successor(tlist->btl_list, tnode))))
	break;

      // not yet - wait and see
      if (pthread_cond_wait(&tlist->btl_cv, &tlist->btl_lock))
	abort();

    } while (1);

    if (pthread_mutex_unlock(&tlist->btl_lock))
      abort();
  }
#endif /* HAVE_PTHREAD_KILL_OTHER_THREADS_NP */

  BK_VRETURN(B);
}
Exemplo n.º 5
0
// this function is waste, DON'T USE it
void kill_all_timer()
{
    pthread_kill_other_threads_np();
};
Exemplo n.º 6
0
void rerunDaemon()
{
#ifndef WIN32
#ifdef OW_HAVE_PTHREAD_KILL_OTHER_THREADS_NP
	// do this, since it seems that on some distros (debian sarge for instance)
	// it doesn't happen when calling execv(), and it shouldn't hurt if it's
	// called twice.
	pthread_kill_other_threads_np();
#endif

#ifdef OW_DARWIN
	// On Darwin, execv() fails with a ENOTIMP if any threads are running.
	// The only way we have to really get rid of all the threads is to call fork() and exit() the parent.
	// Note that we don't do this on other platforms because fork() isn't safe to call from a signal handler, and isn't necessary.
	if (::fork() != 0)
	{
		_exit(1); // if fork fails or we're the parent, just exit.
	}
	// child continues.
#endif

	// On Linux pthreads will kill off all the threads when we call
	// execv().  If we close all the fds, then that breaks pthreads and
	// execv() will just hang.
	// Instead set the close on exec flag so all file descriptors are closed
	// by the kernel when we evecv() and we won't leak them.
	rlimit rl;
	int i = sysconf(_SC_OPEN_MAX);
	if (getrlimit(RLIMIT_NOFILE, &rl) != -1)
	{
	  if ( i < 0 )
	  {
		i = rl.rlim_max;
	  }
	  else
	  {
		i = std::min<int>(rl.rlim_max, i);
	  }
	}

	struct flock lck;
	::memset (&lck, '\0', sizeof (lck));
	lck.l_type = F_UNLCK;       // unlock
	lck.l_whence = 0;           // 0 offset for l_start
	lck.l_start = 0L;           // lock starts at BOF
	lck.l_len = 0L;             // extent is entire file

	while (i > 2)
	{
		// clear any file locks - this shouldn't technically be necessary, but it seems on some systems, even though we restart, the locks persist,
		// either because of bugs in the kernel or somehow things still hang around...
		::fcntl(i, F_SETLK, &lck);

		// set it for close on exec
		::fcntl(i, F_SETFD, FD_CLOEXEC);
		i--;
	}

	// reset the signal mask, since that is inherited by an exec()'d process, and if
	// this was called from a signal handler, the signal being handled (e.g. SIGSEGV) will be blocked.
	// some platforms make macros for sigemptyset, so we can't use ::
	sigset_t emptymask;
	sigemptyset(&emptymask);
	::sigprocmask(SIG_SETMASK, &emptymask, 0);
#endif

	// This doesn't return. execv() will replace the current process with a
	// new copy of g_argv[0] (owcimomd).
	::execv(g_argv[0], g_argv);

	// If we get here we're pretty much hosed.
	OW_THROW_ERRNO_MSG(DaemonException, "execv() failed");
}