* pthreadP.h: Define INVALID_TD_P and INVALID_NOT_TERMINATED_TD_P.
	* pthread_cancel.c: Use INVALID_TD_P.
	* pthread_detach.c: Likewise.
	* pthread_getschedparam.c: Likewise.
	* pthread_setschedparam.c: Likewise.
	* sysdeps/pthread/pthread_getcpuclockid.c: Likewise.
	* sysdeps/unix/sysv/linux/pthread_kill.c: Likewise.
	* pthread_join.c: Use INVALID_NOT_TERMINATED_TD_P.
	* pthread_timedjoin.c: Likewise.

	* tst-basic7.c: Include <signal.h>.
This commit is contained in:
Ulrich Drepper 2003-02-21 10:00:33 +00:00
parent 8b1a8bb409
commit 8c2e9a29b1
10 changed files with 85 additions and 36 deletions

View File

@ -1,5 +1,17 @@
2003-02-21 Ulrich Drepper <drepper@redhat.com>
* pthreadP.h: Define INVALID_TD_P and INVALID_NOT_TERMINATED_TD_P.
* pthread_cancel.c: Use INVALID_TD_P.
* pthread_detach.c: Likewise.
* pthread_getschedparam.c: Likewise.
* pthread_setschedparam.c: Likewise.
* sysdeps/pthread/pthread_getcpuclockid.c: Likewise.
* sysdeps/unix/sysv/linux/pthread_kill.c: Likewise.
* pthread_join.c: Use INVALID_NOT_TERMINATED_TD_P.
* pthread_timedjoin.c: Likewise.
* tst-basic7.c: Include <signal.h>.
* pthread_join.c (pthread_join): Limited checking for invalid
descriptors.
* pthread_timedjoin.c (pthread_timedjoin_np): Likewise.

View File

@ -70,8 +70,15 @@ extern int __pthread_debug attribute_hidden;
/** For now disable debugging support. */
#if 0
# define DEBUGGING_P __builtin_expect (__pthread_debug, 0)
# define INVALID_TD_P(pd) (DEBUGGING_P && __find_in_stack_list (pd) == NULL)
# define INVALID_NOT_TERMINATED_TD_P(pd) INVALID_TD_P (pd)
#else
# define DEBUGGING_P 0
/* Simplified test. This will not catch all invalid descriptors but
is better than nothing. And if the test triggers the thread
descriptor is guaranteed to be invalid. */
# define INVALID_TD_P(pd) __builtin_expect ((pd)->tid <= 0, 0)
# define INVALID_NOT_TERMINATED_TD_P(pd) __builtin_expect ((pd)->tid < 0, 0)
#endif

View File

@ -17,6 +17,7 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <signal.h>
#include "pthreadP.h"
#include "atomic.h"
@ -27,8 +28,13 @@ pthread_cancel (th)
pthread_t th;
{
volatile struct pthread *pd = (volatile struct pthread *) th;
int result = 0;
/* Make sure the descriptor is valid. */
if (INVALID_TD_P (pd))
/* Not a valid thread handle. */
return ESRCH;
int result = 0;
while (1)
{
int oldval = pd->cancelhandling;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2002 Free Software Foundation, Inc.
/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -27,6 +27,12 @@ pthread_detach (th)
pthread_t th;
{
struct pthread *pd = (struct pthread *) th;
/* Make sure the descriptor is valid. */
if (INVALID_TD_P (pd))
/* Not a valid thread handle. */
return ESRCH;
int result = 0;
/* Mark the thread as detached. */

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2002 Free Software Foundation, Inc.
/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -17,33 +17,39 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <string.h>
#include "pthreadP.h"
#include <lowlevellock.h>
int
__pthread_getschedparam (thread_id, policy, param)
pthread_t thread_id;
__pthread_getschedparam (threadid, policy, param)
pthread_t threadid;
int *policy;
struct sched_param *param;
{
struct pthread *thread = (struct pthread *) thread_id;
struct pthread *pd = (struct pthread *) threadid;
/* Make sure the descriptor is valid. */
if (INVALID_TD_P (pd))
/* Not a valid thread handle. */
return ESRCH;
/* We have to handle cancellation in the following code since we are
locking another threads desriptor. */
pthread_cleanup_push ((void (*) (void *)) lll_unlock_wake_cb, &thread->lock);
pthread_cleanup_push ((void (*) (void *)) lll_unlock_wake_cb, &pd->lock);
lll_lock (thread->lock);
lll_lock (pd->lock);
/* The library is responsible for maintaining the values at all
times. If the user uses a interface other than
pthread_setschedparam to modify the scheduler setting it is not
the library's problem. */
*policy = thread->schedpolicy;
memcpy (param, &thread->schedparam, sizeof (struct sched_param));
*policy = pd->schedpolicy;
memcpy (param, &pd->schedparam, sizeof (struct sched_param));
lll_unlock (thread->lock);
lll_unlock (pd->lock);
pthread_cleanup_pop (0);

View File

@ -40,7 +40,7 @@ pthread_join (threadid, thread_return)
struct pthread *pd = (struct pthread *) threadid;
/* Make sure the descriptor is valid. */
if ((DEBUGGING_P && __find_in_stack_list (pd) == NULL) || pd->tid <= 0)
if (INVALID_NOT_TERMINATED_TD_P (pd))
/* Not a valid thread handle. */
return ESRCH;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2002 Free Software Foundation, Inc.
/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -25,33 +25,39 @@
int
__pthread_setschedparam (thread_id, policy, param)
pthread_t thread_id;
__pthread_setschedparam (threadid, policy, param)
pthread_t threadid;
int policy;
const struct sched_param *param;
{
struct pthread *thread = (struct pthread *) thread_id;
struct pthread *pd = (struct pthread *) threadid;
/* Make sure the descriptor is valid. */
if (INVALID_TD_P (pd))
/* Not a valid thread handle. */
return ESRCH;
int result = 0;
/* We have to handle cancellation in the following code since we are
locking another threads desriptor. */
pthread_cleanup_push ((void (*) (void *)) lll_unlock_wake_cb, &thread->lock);
pthread_cleanup_push ((void (*) (void *)) lll_unlock_wake_cb, &pd->lock);
lll_lock (thread->lock);
lll_lock (pd->lock);
/* Try to set the scheduler information. */
if (__builtin_expect (__sched_setscheduler (thread->tid, policy,
if (__builtin_expect (__sched_setscheduler (pd->tid, policy,
param) == -1, 0))
result = errno;
else
{
/* We succeeded changing the kernel information. Reflect this
change in the thread descriptor. */
thread->schedpolicy = policy;
memcpy (&thread->schedparam, param, sizeof (struct sched_param));
pd->schedpolicy = policy;
memcpy (&pd->schedparam, param, sizeof (struct sched_param));
}
lll_unlock (thread->lock);
lll_unlock (pd->lock);
pthread_cleanup_pop (0);

View File

@ -19,7 +19,6 @@
#include <errno.h>
#include <stdlib.h>
#include "atomic.h"
#include "pthreadP.h"
@ -42,7 +41,7 @@ pthread_timedjoin_np (threadid, thread_return, abstime)
int result;
/* Make sure the descriptor is valid. */
if ((DEBUGGING_P && __find_in_stack_list (pd) == NULL) || pd->tid <= 0)
if (INVALID_NOT_TERMINATED_TD_P (pd))
/* Not a valid thread handle. */
return ESRCH;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
/* Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -17,23 +17,30 @@
Boston, MA 02111-1307, USA. */
#include <errno.h>
#include <pthread.h>
#include <pthreadP.h>
#include <sys/time.h>
#include <tls.h>
int
pthread_getcpuclockid (thread_id, clock_id)
pthread_t thread_id;
clockid_t *clock_id;
pthread_getcpuclockid (threadid, clockid)
pthread_t threadid;
clockid_t *clockid;
{
struct pthread *pd = (struct pthread *) threadid;
/* Make sure the descriptor is valid. */
if (INVALID_TD_P (pd))
/* Not a valid thread handle. */
return ESRCH;
/* We don't allow any process ID but our own. */
if ((struct pthread *) thread_id != THREAD_SELF)
if (pd != THREAD_SELF)
return EPERM;
#ifdef CLOCK_THREAD_CPUTIME_ID
/* Store the number. */
*clock_id = CLOCK_THREAD_CPUTIME_ID;
*clockid = CLOCK_THREAD_CPUTIME_ID;
return 0;
#else

View File

@ -31,14 +31,14 @@ __pthread_kill (threadid, signo)
{
struct pthread *pd = (struct pthread *) threadid;
/* Make sure the descriptor is valid. */
if (INVALID_TD_P (pd))
/* Not a valid thread handle. */
return ESRCH;
/* We have a special syscall to do the work. */
INTERNAL_SYSCALL_DECL (err);
/* The kernel returns EINVAL for PIDs <= 0. This is not nice since
the user would expect ESRCH. Correct it here. */
if (pd->tid <= 0)
return ESRCH;
int val = INTERNAL_SYSCALL (tkill, err, 2, pd->tid, signo);
return (INTERNAL_SYSCALL_ERROR_P (val, err)