From ed92686917250ff0cd818edae39dc79dc0795409 Mon Sep 17 00:00:00 2001 From: John Birrell Date: Fri, 3 Apr 1998 09:31:15 +0000 Subject: [PATCH] Add a magic field to the pthread structure to help recognize valid threads from invalid ones. The pthread structure is opaque to the user so this change does not cause any incompatibilities. Hopefully this change will help code that was written for draft 4 fail gracefully if the programmer ignores the compiler warning about the change in the level of indirection for the argument passed to pthread_detach(). I got burnt, so I fixed then (expletive deleted) thing. These functions comply with the revised standard. That should shut Terry up! --- lib/libc_r/uthread/pthread_private.h | 9 ++++++++- lib/libc_r/uthread/uthread_create.c | 6 ++++++ lib/libc_r/uthread/uthread_detach.c | 2 +- lib/libc_r/uthread/uthread_join.c | 10 ++++++++++ lib/libkse/thread/thr_create.c | 6 ++++++ lib/libkse/thread/thr_detach.c | 2 +- lib/libkse/thread/thr_join.c | 10 ++++++++++ lib/libkse/thread/thr_private.h | 9 ++++++++- lib/libpthread/thread/thr_create.c | 6 ++++++ lib/libpthread/thread/thr_detach.c | 2 +- lib/libpthread/thread/thr_join.c | 10 ++++++++++ lib/libpthread/thread/thr_private.h | 9 ++++++++- 12 files changed, 75 insertions(+), 6 deletions(-) diff --git a/lib/libc_r/uthread/pthread_private.h b/lib/libc_r/uthread/pthread_private.h index 7d5bf89f3a3..e4b377a00c6 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 da00e4d4403..412f5580174 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 a9f24699e3c..57c073ab3ab 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 63d0d5880be..9e86a0154b6 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 da00e4d4403..412f5580174 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 a9f24699e3c..57c073ab3ab 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 63d0d5880be..9e86a0154b6 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 7d5bf89f3a3..e4b377a00c6 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 da00e4d4403..412f5580174 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 a9f24699e3c..57c073ab3ab 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 63d0d5880be..9e86a0154b6 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 7d5bf89f3a3..e4b377a00c6 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. */