diff --git a/lib/libc_r/uthread/pthread_private.h b/lib/libc_r/uthread/pthread_private.h index 7d5bf89f3a3e..e4b377a00c6a 100644 --- a/lib/libc_r/uthread/pthread_private.h +++ b/lib/libc_r/uthread/pthread_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 John Birrell . + * Copyright (c) 1995-1998 John Birrell . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -277,6 +277,13 @@ union pthread_wait_data { * Thread structure. */ struct pthread { + /* + * Magic value to help recognize a valid thread structure + * from an invalid one: + */ +#define PTHREAD_MAGIC ((u_int32_t) 0xd09ba115) + u_int32_t magic; + /* * Pointer to the next thread in the thread linked list. */ diff --git a/lib/libc_r/uthread/uthread_create.c b/lib/libc_r/uthread/uthread_create.c index da00e4d44038..412f5580174c 100644 --- a/lib/libc_r/uthread/uthread_create.c +++ b/lib/libc_r/uthread/uthread_create.c @@ -60,6 +60,12 @@ _thread_create(pthread_t * thread, const pthread_attr_t * attr, /* Insufficient memory to create a thread: */ ret = EAGAIN; } else { + /* + * Write a magic value to the thread structure to help + * identify valid ones: + */ + new_thread->magic = PTHREAD_MAGIC; + /* Check if default thread attributes are required: */ if (attr == NULL || *attr == NULL) { /* Use the default thread attributes: */ diff --git a/lib/libc_r/uthread/uthread_detach.c b/lib/libc_r/uthread/uthread_detach.c index a9f24699e3c6..57c073ab3ab9 100644 --- a/lib/libc_r/uthread/uthread_detach.c +++ b/lib/libc_r/uthread/uthread_detach.c @@ -46,7 +46,7 @@ pthread_detach(pthread_t pthread) _thread_kern_sig_block(&status); /* Check for invalid calling parameters: */ - if (pthread == NULL) { + if (pthread == NULL || pthread->magic != PTHREAD_MAGIC) { /* Return an invalid argument error: */ rval = EINVAL; } diff --git a/lib/libc_r/uthread/uthread_join.c b/lib/libc_r/uthread/uthread_join.c index 63d0d5880bec..9e86a0154b6b 100644 --- a/lib/libc_r/uthread/uthread_join.c +++ b/lib/libc_r/uthread/uthread_join.c @@ -42,6 +42,16 @@ pthread_join(pthread_t pthread, void **thread_return) int status; pthread_t pthread1; + /* Check if the caller has specified an invalid thread: */ + if (pthread == NULL || pthread->magic != PTHREAD_MAGIC) + /* Invalid thread: */ + return(EINVAL); + + /* Check if the caller has specified itself: */ + if (pthread == _thread_run) + /* Avoid a deadlock condition: */ + return(EDEADLK); + /* Block signals: */ _thread_kern_sig_block(&status); diff --git a/lib/libkse/thread/thr_create.c b/lib/libkse/thread/thr_create.c index da00e4d44038..412f5580174c 100644 --- a/lib/libkse/thread/thr_create.c +++ b/lib/libkse/thread/thr_create.c @@ -60,6 +60,12 @@ _thread_create(pthread_t * thread, const pthread_attr_t * attr, /* Insufficient memory to create a thread: */ ret = EAGAIN; } else { + /* + * Write a magic value to the thread structure to help + * identify valid ones: + */ + new_thread->magic = PTHREAD_MAGIC; + /* Check if default thread attributes are required: */ if (attr == NULL || *attr == NULL) { /* Use the default thread attributes: */ diff --git a/lib/libkse/thread/thr_detach.c b/lib/libkse/thread/thr_detach.c index a9f24699e3c6..57c073ab3ab9 100644 --- a/lib/libkse/thread/thr_detach.c +++ b/lib/libkse/thread/thr_detach.c @@ -46,7 +46,7 @@ pthread_detach(pthread_t pthread) _thread_kern_sig_block(&status); /* Check for invalid calling parameters: */ - if (pthread == NULL) { + if (pthread == NULL || pthread->magic != PTHREAD_MAGIC) { /* Return an invalid argument error: */ rval = EINVAL; } diff --git a/lib/libkse/thread/thr_join.c b/lib/libkse/thread/thr_join.c index 63d0d5880bec..9e86a0154b6b 100644 --- a/lib/libkse/thread/thr_join.c +++ b/lib/libkse/thread/thr_join.c @@ -42,6 +42,16 @@ pthread_join(pthread_t pthread, void **thread_return) int status; pthread_t pthread1; + /* Check if the caller has specified an invalid thread: */ + if (pthread == NULL || pthread->magic != PTHREAD_MAGIC) + /* Invalid thread: */ + return(EINVAL); + + /* Check if the caller has specified itself: */ + if (pthread == _thread_run) + /* Avoid a deadlock condition: */ + return(EDEADLK); + /* Block signals: */ _thread_kern_sig_block(&status); diff --git a/lib/libkse/thread/thr_private.h b/lib/libkse/thread/thr_private.h index 7d5bf89f3a3e..e4b377a00c6a 100644 --- a/lib/libkse/thread/thr_private.h +++ b/lib/libkse/thread/thr_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 John Birrell . + * Copyright (c) 1995-1998 John Birrell . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -277,6 +277,13 @@ union pthread_wait_data { * Thread structure. */ struct pthread { + /* + * Magic value to help recognize a valid thread structure + * from an invalid one: + */ +#define PTHREAD_MAGIC ((u_int32_t) 0xd09ba115) + u_int32_t magic; + /* * Pointer to the next thread in the thread linked list. */ diff --git a/lib/libpthread/thread/thr_create.c b/lib/libpthread/thread/thr_create.c index da00e4d44038..412f5580174c 100644 --- a/lib/libpthread/thread/thr_create.c +++ b/lib/libpthread/thread/thr_create.c @@ -60,6 +60,12 @@ _thread_create(pthread_t * thread, const pthread_attr_t * attr, /* Insufficient memory to create a thread: */ ret = EAGAIN; } else { + /* + * Write a magic value to the thread structure to help + * identify valid ones: + */ + new_thread->magic = PTHREAD_MAGIC; + /* Check if default thread attributes are required: */ if (attr == NULL || *attr == NULL) { /* Use the default thread attributes: */ diff --git a/lib/libpthread/thread/thr_detach.c b/lib/libpthread/thread/thr_detach.c index a9f24699e3c6..57c073ab3ab9 100644 --- a/lib/libpthread/thread/thr_detach.c +++ b/lib/libpthread/thread/thr_detach.c @@ -46,7 +46,7 @@ pthread_detach(pthread_t pthread) _thread_kern_sig_block(&status); /* Check for invalid calling parameters: */ - if (pthread == NULL) { + if (pthread == NULL || pthread->magic != PTHREAD_MAGIC) { /* Return an invalid argument error: */ rval = EINVAL; } diff --git a/lib/libpthread/thread/thr_join.c b/lib/libpthread/thread/thr_join.c index 63d0d5880bec..9e86a0154b6b 100644 --- a/lib/libpthread/thread/thr_join.c +++ b/lib/libpthread/thread/thr_join.c @@ -42,6 +42,16 @@ pthread_join(pthread_t pthread, void **thread_return) int status; pthread_t pthread1; + /* Check if the caller has specified an invalid thread: */ + if (pthread == NULL || pthread->magic != PTHREAD_MAGIC) + /* Invalid thread: */ + return(EINVAL); + + /* Check if the caller has specified itself: */ + if (pthread == _thread_run) + /* Avoid a deadlock condition: */ + return(EDEADLK); + /* Block signals: */ _thread_kern_sig_block(&status); diff --git a/lib/libpthread/thread/thr_private.h b/lib/libpthread/thread/thr_private.h index 7d5bf89f3a3e..e4b377a00c6a 100644 --- a/lib/libpthread/thread/thr_private.h +++ b/lib/libpthread/thread/thr_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 John Birrell . + * Copyright (c) 1995-1998 John Birrell . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -277,6 +277,13 @@ union pthread_wait_data { * Thread structure. */ struct pthread { + /* + * Magic value to help recognize a valid thread structure + * from an invalid one: + */ +#define PTHREAD_MAGIC ((u_int32_t) 0xd09ba115) + u_int32_t magic; + /* * Pointer to the next thread in the thread linked list. */