summaryrefslogtreecommitdiff
path: root/mit-pthreads/patches/Streepy.html
diff options
context:
space:
mode:
Diffstat (limited to 'mit-pthreads/patches/Streepy.html')
-rwxr-xr-xmit-pthreads/patches/Streepy.html2873
1 files changed, 2873 insertions, 0 deletions
diff --git a/mit-pthreads/patches/Streepy.html b/mit-pthreads/patches/Streepy.html
new file mode 100755
index 00000000000..a3b4faa815f
--- /dev/null
+++ b/mit-pthreads/patches/Streepy.html
@@ -0,0 +1,2873 @@
+diff -c -r1.1.1.1 pthread.h
+*** pthread.h 1996/03/13 04:30:57 1.1.1.1
+--- pthread.h 1996/10/02 17:52:47
+***************
+*** 35,40 ****
+--- 35,43 ----
+ *
+ * 1.00 93/07/20 proven
+ * -Started coding this file.
++ *
++ * 93/9/28 streepy - Added support for pthread cancel
++ *
+ */
+
+ #ifndef _PTHREAD_H_
+***************
+*** 65,70 ****
+--- 68,82 ----
+ /* More includes, that need size_t */
+ #include <pthread/pthread_attr.h>
+
++ /* Constants for use with pthread_setcancelstate and pthread_setcanceltype */
++ #define PTHREAD_CANCEL_DISABLE 0
++ #define PTHREAD_CANCEL_ENABLE 1
++ #define PTHREAD_CANCEL_DEFERRED 0
++ #define PTHREAD_CANCEL_ASYNCHRONOUS 1
++
++ #define PTHREAD_CANCELLED (void *)1 /* Exit status of a cancelled thread */
++
++
+ #ifdef PTHREAD_KERNEL
+
+ #include <signal.h> /* for sigset_t */
+***************
+*** 78,120 ****
+ PS_STATE_MAX
+ };
+
+- #define PF_WAIT_EVENT 0x01
+- #define PF_DONE_EVENT 0x02
+-
+ /* Put PANIC inside an expression that evaluates to non-void type, to
+ make it easier to combine it in expressions. */
+! #define DO_PANIC() (PANIC (), 0)
+! #define PANICIF(x) ((x) ? DO_PANIC () : 0)
+
+! #define SET_PF_DONE_EVENT(x) \
+! ( !(x->flags & PF_DONE_EVENT) \
+! ? ( (x->flags & PF_WAIT_EVENT) \
+! ? (x->flags = PF_DONE_EVENT, OK) \
+! : DO_PANIC ()) \
+ : NOTOK )
+
+! #define SET_PF_WAIT_EVENT(x) \
+! ( PANICIF (x->flags & (PF_WAIT_EVENT | PF_DONE_EVENT)), \
+! (x->flags = PF_WAIT_EVENT), 0)
+!
+! #define CLEAR_PF_DONE_EVENT(x) \
+! ( PANICIF (!(x->flags & PF_DONE_EVENT)), \
+! x->flags = 0 )
+
+ struct pthread_select_data {
+! int nfds;
+! fd_set readfds;
+! fd_set writefds;
+! fd_set exceptfds;
+ };
+
+ union pthread_wait_data {
+! pthread_mutex_t * mutex;
+! pthread_cond_t * cond;
+! const sigset_t * sigwait; /* Waiting on a signal in sigwait */
+ struct {
+! short fd; /* Used when thread waiting on fd */
+! short branch; /* line number, for debugging */
+ } fd;
+ struct pthread_select_data * select_data;
+ };
+--- 90,185 ----
+ PS_STATE_MAX
+ };
+
+ /* Put PANIC inside an expression that evaluates to non-void type, to
+ make it easier to combine it in expressions. */
+! #define DO_PANIC() (PANIC (), 0)
+! #define PANICIF(x) ((x) ? DO_PANIC () : 0)
+!
+! /* In the thread flag field, we use a series of bit flags. Flags can
+! * organized into "groups" of mutually exclusive flags. Other flags
+! * are unrelated and can be set and cleared with a single bit operation.
+! */
+
+! #define PF_WAIT_EVENT 0x01
+! #define PF_DONE_EVENT 0x02
+! #define PF_EVENT_GROUP 0x03 /* All event bits */
+!
+! #define PF_CANCEL_STATE 0x04 /* cancellability state */
+! #define PF_CANCEL_TYPE 0x08 /* cancellability type */
+! #define PF_THREAD_CANCELLED 0x10 /* thread has been cancelled */
+! #define PF_RUNNING_TO_CANCEL 0x20 /* Thread is running so it can cancel*/
+! #define PF_AT_CANCEL_POINT 0x40 /* Thread is at a cancel point */
+!
+! /* Flag operations */
+!
+! #define SET_PF_FLAG(x,f) ( (x)->flags |= (f) )
+! #define TEST_PF_FLAG(x,f) ( (x)->flags & (f) )
+! #define CLEAR_PF_FLAG(x,f) ( (x)->flags &= ~(f) )
+! #define CLEAR_PF_GROUP(x,g) ( (x)->flags &= ~(g) )
+! #define SET_PF_FLAG_IN_GROUP(x,g,f) ( CLEAR_PF_GROUP(x,g),SET_PF_FLAG(x,f))
+! #define TEST_PF_GROUP(x,g) ( (x)->flags & (g) )
+!
+! #define SET_PF_DONE_EVENT(x) \
+! ( !TEST_PF_FLAG(x,PF_DONE_EVENT) \
+! ? ( TEST_PF_FLAG(x,PF_WAIT_EVENT) \
+! ? (SET_PF_FLAG_IN_GROUP(x,PF_EVENT_GROUP,PF_DONE_EVENT), OK) \
+! : DO_PANIC ()) \
+ : NOTOK )
+
+! #define SET_PF_WAIT_EVENT(x) \
+! ( PANICIF (TEST_PF_GROUP(x,PF_EVENT_GROUP) ), \
+! SET_PF_FLAG_IN_GROUP(x,PF_EVENT_GROUP,PF_WAIT_EVENT), 0)
+!
+! #define CLEAR_PF_DONE_EVENT(x) \
+! ( PANICIF (!TEST_PF_FLAG(x,PF_DONE_EVENT)), \
+! CLEAR_PF_GROUP(x,PF_EVENT_GROUP) )
+!
+! #define SET_PF_CANCELLED(x) ( SET_PF_FLAG(x,PF_THREAD_CANCELLED) )
+! #define TEST_PF_CANCELLED(x) ( TEST_PF_FLAG(x,PF_THREAD_CANCELLED) )
+!
+! #define SET_PF_RUNNING_TO_CANCEL(x) ( SET_PF_FLAG(x,PF_RUNNING_TO_CANCEL) )
+! #define CLEAR_PF_RUNNING_TO_CANCEL(x)( CLEAR_PF_FLAG(x,PF_RUNNING_TO_CANCEL) )
+! #define TEST_PF_RUNNING_TO_CANCEL(x)( TEST_PF_FLAG(x,PF_RUNNING_TO_CANCEL) )
+!
+! #define SET_PF_AT_CANCEL_POINT(x) ( SET_PF_FLAG(x,PF_AT_CANCEL_POINT) )
+! #define CLEAR_PF_AT_CANCEL_POINT(x) ( CLEAR_PF_FLAG(x,PF_AT_CANCEL_POINT) )
+! #define TEST_PF_AT_CANCEL_POINT(x) ( TEST_PF_FLAG(x,PF_AT_CANCEL_POINT) )
+!
+! #define SET_PF_CANCEL_STATE(x,f) \
+! ( (f) ? SET_PF_FLAG(x,PF_CANCEL_STATE) : CLEAR_PF_FLAG(x,PF_CANCEL_STATE) )
+! #define TEST_PF_CANCEL_STATE(x) \
+! ( (TEST_PF_FLAG(x,PF_CANCEL_STATE)) ? PTHREAD_CANCEL_ENABLE \
+! : PTHREAD_CANCEL_DISABLE )
+!
+! #define SET_PF_CANCEL_TYPE(x,f) \
+! ( (f) ? SET_PF_FLAG(x,PF_CANCEL_TYPE) : CLEAR_PF_FLAG(x,PF_CANCEL_TYPE) )
+! #define TEST_PF_CANCEL_TYPE(x) \
+! ( (TEST_PF_FLAG(x,PF_CANCEL_TYPE)) ? PTHREAD_CANCEL_ASYNCHRONOUS \
+! : PTHREAD_CANCEL_DEFERRED )
+!
+! /* See if a thread is in a state that it can be cancelled */
+! #define TEST_PTHREAD_IS_CANCELLABLE(x) \
+! ( (TEST_PF_CANCEL_STATE(x) == PTHREAD_CANCEL_ENABLE && TEST_PF_CANCELLED(x)) \
+! ? ((TEST_PF_CANCEL_TYPE(x) == PTHREAD_CANCEL_ASYNCHRONOUS) \
+! ? 1 \
+! : TEST_PF_AT_CANCEL_POINT(x)) \
+! : 0 )
+!
+
+ struct pthread_select_data {
+! int nfds;
+! fd_set readfds;
+! fd_set writefds;
+! fd_set exceptfds;
+ };
+
+ union pthread_wait_data {
+! pthread_mutex_t * mutex;
+! pthread_cond_t * cond;
+! const sigset_t * sigwait; /* Waiting on a signal in sigwait */
+ struct {
+! short fd; /* Used when thread waiting on fd */
+! short branch; /* line number, for debugging */
+ } fd;
+ struct pthread_select_data * select_data;
+ };
+***************
+*** 122,143 ****
+ #define PTT_USER_THREAD 0x0001
+
+ struct pthread {
+! int thread_type;
+ struct machdep_pthread machdep_data;
+! pthread_attr_t attr;
+
+ /* Signal interface */
+! sigset_t sigmask;
+! sigset_t sigpending;
+! int sigcount; /* Number of signals pending */
+
+ /* Timeout time */
+! struct timespec wakeup_time;
+
+ /* Join queue for waiting threads */
+ struct pthread_queue join_queue;
+
+-
+ /*
+ * Thread implementations are just multiple queue type implemenations,
+ * Below are the various link lists currently necessary
+--- 187,207 ----
+ #define PTT_USER_THREAD 0x0001
+
+ struct pthread {
+! int thread_type;
+ struct machdep_pthread machdep_data;
+! pthread_attr_t attr;
+
+ /* Signal interface */
+! sigset_t sigmask;
+! sigset_t sigpending;
+! int sigcount; /* Number of signals pending */
+
+ /* Timeout time */
+! struct timespec wakeup_time;
+
+ /* Join queue for waiting threads */
+ struct pthread_queue join_queue;
+
+ /*
+ * Thread implementations are just multiple queue type implemenations,
+ * Below are the various link lists currently necessary
+***************
+*** 152,165 ****
+ * ALL threads, in any state.
+ * Must lock kernel lock before manipulating.
+ */
+! struct pthread * pll;
+
+ /*
+ * Standard link list for running threads, mutexes, etc ...
+ * It can't be on both a running link list and a wait queue.
+ * Must lock kernel lock before manipulating.
+ */
+! struct pthread * next;
+ union pthread_wait_data data;
+
+ /*
+--- 216,229 ----
+ * ALL threads, in any state.
+ * Must lock kernel lock before manipulating.
+ */
+! struct pthread * pll;
+
+ /*
+ * Standard link list for running threads, mutexes, etc ...
+ * It can't be on both a running link list and a wait queue.
+ * Must lock kernel lock before manipulating.
+ */
+! struct pthread * next;
+ union pthread_wait_data data;
+
+ /*
+***************
+*** 167,197 ****
+ * (Note: "priority" is a reserved word in Concurrent C, please
+ * don't use it. --KR)
+ */
+! struct pthread_queue * queue;
+! enum pthread_state state;
+! char flags;
+! char pthread_priority;
+
+ /*
+ * Sleep queue, this is different from the standard link list
+ * because it is possible to be on both (pthread_cond_timedwait();
+ * Must lock sleep mutex before manipulating
+ */
+! struct pthread *sll; /* For sleeping threads */
+
+ /*
+ * Data that doesn't need to be locked
+! * Mostly it's because only the thread owning the data can manipulate it
+ */
+! void * ret;
+! int error;
+! int * error_p;
+! const void ** specific_data;
+! int specific_data_count;
+
+ /* Cleanup handlers Link List */
+ struct pthread_cleanup *cleanup;
+-
+ };
+
+ #else /* not PTHREAD_KERNEL */
+--- 231,261 ----
+ * (Note: "priority" is a reserved word in Concurrent C, please
+ * don't use it. --KR)
+ */
+! struct pthread_queue * queue;
+! enum pthread_state state;
+! enum pthread_state old_state; /* Used when cancelled */
+! char flags;
+! char pthread_priority;
+
+ /*
+ * Sleep queue, this is different from the standard link list
+ * because it is possible to be on both (pthread_cond_timedwait();
+ * Must lock sleep mutex before manipulating
+ */
+! struct pthread *sll; /* For sleeping threads */
+
+ /*
+ * Data that doesn't need to be locked
+! * Mostly because only the thread owning the data can manipulate it
+ */
+! void * ret;
+! int error;
+! int * error_p;
+! const void ** specific_data;
+! int specific_data_count;
+
+ /* Cleanup handlers Link List */
+ struct pthread_cleanup *cleanup;
+ };
+
+ #else /* not PTHREAD_KERNEL */
+***************
+*** 200,223 ****
+
+ #endif
+
+! typedef struct pthread * pthread_t;
+
+ /*
+ * Globals
+ */
+ #ifdef PTHREAD_KERNEL
+
+! extern struct pthread * pthread_run;
+! extern struct pthread * pthread_initial;
+! extern struct pthread * pthread_link_list;
+ extern struct pthread_queue pthread_dead_queue;
+ extern struct pthread_queue pthread_alloc_queue;
+
+! extern pthread_attr_t pthread_attr_default;
+! extern volatile int fork_lock;
+! extern pthread_size_t pthread_pagesize;
+!
+! extern sigset_t * uthread_sigmask;
+
+ #endif
+
+--- 264,293 ----
+
+ #endif
+
+! typedef struct pthread *pthread_t;
+
+ /*
+ * Globals
+ */
+ #ifdef PTHREAD_KERNEL
+
+! extern struct pthread * pthread_run;
+! extern struct pthread * pthread_initial;
+! extern struct pthread * pthread_link_list;
+ extern struct pthread_queue pthread_dead_queue;
+ extern struct pthread_queue pthread_alloc_queue;
+
+! extern pthread_attr_t pthread_attr_default;
+! extern volatile int fork_lock;
+! extern pthread_size_t pthread_pagesize;
+!
+! extern sigset_t * uthread_sigmask;
+!
+! /* Kernel global functions */
+! extern void pthread_sched_prevent(void);
+! extern void pthread_sched_resume(void);
+! extern int __pthread_is_valid( pthread_t );
+! extern void pthread_cancel_internal( int freelocks );
+
+ #endif
+
+***************
+*** 229,271 ****
+
+ #if defined(DCE_COMPAT)
+
+! typedef void * (*pthread_startroutine_t)(void *)
+! typedef void * pthread_addr_t
+
+! int pthread_create __P((pthread_t *, pthread_attr_t,
+! pthread_startroutine_t,
+! pthread_addr_t));
+! void pthread_exit __P((pthread_addr_t));
+! int pthread_join __P((pthread_t, pthread_addr_t *));
+
+ #else
+
+! void pthread_init __P((void));
+! int pthread_create __P((pthread_t *,
+! const pthread_attr_t *,
+! void * (*start_routine)(void *),
+! void *));
+! void pthread_exit __P((void *));
+! pthread_t pthread_self __P((void));
+! int pthread_equal __P((pthread_t, pthread_t));
+! int pthread_join __P((pthread_t, void **));
+! int pthread_detach __P((pthread_t));
+! void pthread_yield __P((void));
+!
+! int pthread_setschedparam __P((pthread_t pthread, int policy,
+! struct sched_param * param));
+! int pthread_getschedparam __P((pthread_t pthread, int * policy,
+! struct sched_param * param));
+!
+! int pthread_kill __P((struct pthread *, int));
+! int pthread_signal __P((int, void (*)(int)));
+
+ #endif
+
+ #if defined(PTHREAD_KERNEL)
+
+ /* Not valid, but I can't spell so this will be caught at compile time */
+! #define pthread_yeild(notvalid)
+
+ #endif
+
+--- 299,343 ----
+
+ #if defined(DCE_COMPAT)
+
+! typedef void * (*pthread_startroutine_t)(void *);
+! typedef void * pthread_addr_t;
+
+! int pthread_create __P((pthread_t *, pthread_attr_t,
+! pthread_startroutine_t, pthread_addr_t));
+! void pthread_exit __P((pthread_addr_t));
+! int pthread_join __P((pthread_t, pthread_addr_t *));
+
+ #else
+
+! void pthread_init __P((void));
+! int pthread_create __P((pthread_t *, const pthread_attr_t *,
+! void * (*start_routine)(void *), void *));
+! void pthread_exit __P((void *));
+! pthread_t pthread_self __P((void));
+! int pthread_equal __P((pthread_t, pthread_t));
+! int pthread_join __P((pthread_t, void **));
+! int pthread_detach __P((pthread_t));
+! void pthread_yield __P((void));
+!
+! int pthread_setschedparam __P((pthread_t pthread, int policy,
+! struct sched_param * param));
+! int pthread_getschedparam __P((pthread_t pthread, int * policy,
+! struct sched_param * param));
+!
+! int pthread_kill __P((struct pthread *, int));
+! int pthread_signal __P((int, void (*)(int)));
+!
+! int pthread_cancel __P(( pthread_t pthread ));
+! int pthread_setcancelstate __P(( int state, int *oldstate ));
+! int pthread_setcanceltype __P(( int type, int *oldtype ));
+! void pthread_testcancel __P(( void ));
+
+ #endif
+
+ #if defined(PTHREAD_KERNEL)
+
+ /* Not valid, but I can't spell so this will be caught at compile time */
+! #define pthread_yeild(notvalid)
+
+ #endif
+
+=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/include/signal.h,v retrieving revision 1.1.1.1
+diff -c -r1.1.1.1 signal.h
+*** signal.h 1995/12/25 03:03:09 1.1.1.1
+--- signal.h 1996/09/26 21:46:04
+***************
+*** 43,48 ****
+--- 43,49 ----
+ __BEGIN_DECLS
+
+ int raise __P((int));
++ __sighandler_t signal __P((int __sig, __sighandler_t));
+
+ #ifndef _ANSI_SOURCE
+
+=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/include/pthread/kernel.h,v retrieving revision 1.1.1.1
+diff -c -r1.1.1.1 kernel.h
+*** kernel.h 1994/12/13 07:09:01 1.1.1.1
+--- kernel.h 1996/10/02 19:08:41
+***************
+*** 42,48 ****
+ */
+ #if defined(PTHREAD_KERNEL)
+
+! #define PANIC() abort()
+
+ /* Time each rr thread gets */
+ #define PTHREAD_RR_TIMEOUT 100000000
+--- 42,54 ----
+ */
+ #if defined(PTHREAD_KERNEL)
+
+! #ifdef __GNUC__
+! #include <assert.h>
+! #define PANIC() panic_kernel( __FILE__, __LINE__, __ASSERT_FUNCTION )
+! #else
+! #define PANIC() panic_kernel( __FILE__, __LINE__, (const char *)0 )
+! #endif
+!
+
+ /* Time each rr thread gets */
+ #define PTHREAD_RR_TIMEOUT 100000000
+=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/machdep/syscall-i386-linux-1.0.S,v retrieving revision 1.1.1.1
+diff -c -r1.1.1.1 syscall-i386-linux-1.0.S
+*** syscall-i386-linux-1.0.S 1995/09/27 04:38:55 1.1.1.1
+--- syscall-i386-linux-1.0.S 1996/06/04 19:20:17
+***************
+*** 147,154 ****
+
+ /* =========================================================================
+ * exit 1 select 82
+! * fork 2 socketcall 102
+! * read 3
+ * write 4
+ * open 5
+ * creat 8
+--- 147,154 ----
+
+ /* =========================================================================
+ * exit 1 select 82
+! * fork 2 fstatfs 100
+! * read 3 socketcall 102
+ * write 4
+ * open 5
+ * creat 8
+***************
+*** 160,166 ****
+ * chown 16
+ * lseek 19
+ * rename 38
+! * dup 41
+ * pipe 42
+ * ioctl 54
+ * fcntl 55
+--- 160,166 ----
+ * chown 16
+ * lseek 19
+ * rename 38
+! * dup 41
+ * pipe 42
+ * ioctl 54
+ * fcntl 55
+***************
+*** 302,314 ****
+ #endif
+
+ /* ==========================================================================
+! * machdep_sys_fstat()
+ */
+ #ifdef __ELF__
+ STATCALL2(lstat)
+ #else
+ SYSCALL2(lstat)
+ #endif
+
+ /* ==========================================================================
+ * machdep_sys_ftruncate()
+--- 302,320 ----
+ #endif
+
+ /* ==========================================================================
+! * machdep_sys_lstat()
+ */
+ #ifdef __ELF__
+ STATCALL2(lstat)
+ #else
+ SYSCALL2(lstat)
+ #endif
++
++ /* ==========================================================================
++ * machdep_sys_fstatfs()
++ */
++ SYSCALL2(fstatfs)
++
+
+ /* ==========================================================================
+ * machdep_sys_ftruncate()
+=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/machdep/linux-1.0/socket.h,v retrieving revision 1.1.1.1
+diff -c -r1.1.1.1 socket.h
+*** socket.h 1995/12/26 02:28:03 1.1.1.1
+--- socket.h 1996/09/27 18:12:45
+***************
+*** 26,32 ****
+
+ #endif
+
+! /* #include <asm/socket.h> /* arch-dependent defines */
+ #include <linux/sockios.h> /* the SIOCxxx I/O controls */
+ #include <pthread/posix.h>
+
+--- 26,32 ----
+
+ #endif
+
+! /* #include <asm/socket.h> arch-dependent defines */
+ #include <linux/sockios.h> /* the SIOCxxx I/O controls */
+ #include <pthread/posix.h>
+
+***************
+*** 161,166 ****
+--- 161,188 ----
+ int connect __P((int, const struct sockaddr *, int));
+ int listen __P((int, int));
+ int socket __P((int, int, int));
++
++ int getsockopt __P ((int __s, int __level, int __optname,
++ void *__optval, int *__optlen));
++ int setsockopt __P ((int __s, int __level, int __optname,
++ __const void *__optval, int optlen));
++ int getsockname __P ((int __sockfd, struct sockaddr *__addr,
++ int *__paddrlen));
++ int getpeername __P ((int __sockfd, struct sockaddr *__peer,
++ int *__paddrlen));
++ ssize_t send __P ((int __sockfd, __const void *__buff, size_t __len, int __flags));
++ ssize_t recv __P ((int __sockfd, void *__buff, size_t __len, int __flags));
++ ssize_t sendto __P ((int __sockfd, __const void *__buff, size_t __len,
++ int __flags, __const struct sockaddr *__to,
++ int __tolen));
++ ssize_t recvfrom __P ((int __sockfd, void *__buff, size_t __len,
++ int __flags, struct sockaddr *__from,
++ int *__fromlen));
++ extern ssize_t sendmsg __P ((int __fd, __const struct msghdr *__message,
++ int __flags));
++ extern ssize_t recvmsg __P ((int __fd, struct msghdr *__message,
++ int __flags));
++ int shutdown __P ((int __sockfd, int __how));
+
+ __END_DECLS
+
+=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/machdep/linux-1.0/timers.h,v retrieving revision 1.1.1.1
+diff -c -r1.1.1.1 timers.h
+*** timers.h 1996/03/05 08:28:36 1.1.1.1
+--- timers.h 1996/05/25 21:30:08
+***************
+*** 43,52 ****
+--- 43,54 ----
+ #include <sys/types.h>
+ #include <time.h>
+
++ #ifndef _LINUX_TIME_H
+ struct timespec {
+ time_t tv_sec;
+ long tv_nsec;
+ };
++ #endif /* _LINUX_TIME_H */
+
+ #define TIMEVAL_TO_TIMESPEC(tv, ts) { \
+ (ts)->tv_sec = (tv)->tv_sec; \
+=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/net/getprotoent.c,v retrieving revision 1.1.1.1
+diff -c -r1.1.1.1 getprotoent.c
+*** getprotoent.c 1996/02/09 05:39:41 1.1.1.1
+--- getprotoent.c 1996/05/27 01:11:27
+***************
+*** 128,135 ****
+ if (p != NULL)
+ *p++ = '\0';
+ }
+! if (p && *p);
+! break;
+ }
+ *alias = NULL;
+ pthread_mutex_unlock(&proto_file_lock);
+--- 128,135 ----
+ if (p != NULL)
+ *p++ = '\0';
+ }
+! if (p && *p)
+! break;
+ }
+ *alias = NULL;
+ pthread_mutex_unlock(&proto_file_lock);
+=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/net/proto_internal.c,v retrieving revision 1.1.1.1
+diff -c -r1.1.1.1 proto_internal.c
+*** proto_internal.c 1996/02/09 05:39:49 1.1.1.1
+--- proto_internal.c 1996/06/04 16:25:57
+***************
+*** 49,55 ****
+ static int init_status;
+
+ /* Performs global initialization. */
+! char *_proto_init()
+ {
+ char *buf;
+
+--- 49,55 ----
+ static int init_status;
+
+ /* Performs global initialization. */
+! char *_proto_buf()
+ {
+ char *buf;
+
+***************
+*** 75,78 ****
+ {
+ init_status = pthread_key_create(&key, free);
+ }
+-
+--- 75,77 ----
+=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/net/res_internal.c,v retrieving revision 1.1.1.1
+diff -c -r1.1.1.1 res_internal.c
+*** res_internal.c 1996/02/09 05:39:53 1.1.1.1
+--- res_internal.c 1996/09/25 23:31:11
+***************
+*** 144,149 ****
+--- 144,150 ----
+ break;
+ cp += n;
+ result->h_name = bp;
++ bp += strlen(bp) + 1;
+ iquery_done = 1;
+ break;
+ }
+=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/GNUmakefile.inc,v retrieving revision 1.1.1.1
+diff -c -r1.1.1.1 GNUmakefile.inc
+*** GNUmakefile.inc 1995/08/30 22:27:04 1.1.1.1
+--- GNUmakefile.inc 1996/10/02 19:04:29
+***************
+*** 8,14 ****
+ syscall.S pthread_join.c pthread_detach.c pthread_once.c sleep.c \
+ specific.c process.c wait.c errno.c schedparam.c _exit.c prio_queue.c \
+ pthread_init.c init.cc sig.c info.c mutexattr.c select.c wrapper.c \
+! dump_state.c pthread_kill.c stat.c readv.c writev.c condattr.c $(SRCS)
+
+ ifeq ($(HAVE_SYSCALL_TEMPLATE),yes)
+ SYSCALL_FILTER_RULE= for s in $(AVAILABLE_SYSCALLS) ; do \
+--- 8,15 ----
+ syscall.S pthread_join.c pthread_detach.c pthread_once.c sleep.c \
+ specific.c process.c wait.c errno.c schedparam.c _exit.c prio_queue.c \
+ pthread_init.c init.cc sig.c info.c mutexattr.c select.c wrapper.c \
+! dump_state.c pthread_kill.c stat.c readv.c writev.c condattr.c \
+! pthread_cancel.c panic.c $(SRCS)
+
+ ifeq ($(HAVE_SYSCALL_TEMPLATE),yes)
+ SYSCALL_FILTER_RULE= for s in $(AVAILABLE_SYSCALLS) ; do \
+=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/Makefile.inc,v retrieving revision 1.1.1.1
+diff -c -r1.1.1.1 Makefile.inc
+*** Makefile.inc 1995/08/22 22:09:07 1.1.1.1
+--- Makefile.inc 1996/10/02 19:04:38
+***************
+*** 8,14 ****
+ pthread_join.c pthread_detach.c pthread_once.c sleep.c specific.c \
+ process.c wait.c errno.c schedparam.c _exit.c prio_queue.c \
+ pthread_init.c init.cc sig.c info.c mutexattr.c select.c wrapper.c \
+! dump_state.c pthread_kill.c condattr.c
+
+ .if $(HAVE_SYSCALL_TEMPLATE) == yes
+ OBJS+= syscalls.o
+--- 8,14 ----
+ pthread_join.c pthread_detach.c pthread_once.c sleep.c specific.c \
+ process.c wait.c errno.c schedparam.c _exit.c prio_queue.c \
+ pthread_init.c init.cc sig.c info.c mutexattr.c select.c wrapper.c \
+! dump_state.c pthread_kill.c condattr.c pthread_cancel.c panic.c
+
+ .if $(HAVE_SYSCALL_TEMPLATE) == yes
+ OBJS+= syscalls.o
+=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/cond.c,v retrieving revision 1.1.1.1
+diff -c -r1.1.1.1 cond.c
+*** cond.c 1996/03/05 08:29:12 1.1.1.1
+--- cond.c 1996/10/03 18:19:04
+***************
+*** 188,197 ****
+--- 188,204 ----
+ pthread_queue_enq(&cond->c_queue, pthread_run);
+ pthread_mutex_unlock(mutex);
+
++ pthread_run->data.mutex = mutex;
++
+ SET_PF_WAIT_EVENT(pthread_run);
++ SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
+ /* Reschedule will unlock pthread_run */
+ pthread_resched_resume(PS_COND_WAIT);
++ CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
+ CLEAR_PF_DONE_EVENT(pthread_run);
++
++ pthread_run->data.mutex = NULL;
++
+ rval = pthread_mutex_lock(mutex);
+ return(rval);
+ break;
+***************
+*** 203,212 ****
+--- 210,226 ----
+ pthread_mutex_unlock(mutex);
+ mutex->m_data.m_count = 1;
+
++ pthread_run->data.mutex = mutex;
++
+ SET_PF_WAIT_EVENT(pthread_run);
++ SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
+ /* Reschedule will unlock pthread_run */
+ pthread_resched_resume(PS_COND_WAIT);
++ CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
+ CLEAR_PF_DONE_EVENT(pthread_run);
++
++ pthread_run->data.mutex = NULL;
++
+ rval = pthread_mutex_lock(mutex);
+ mutex->m_data.m_count = count;
+ return(rval);
+***************
+*** 258,265 ****
+--- 272,285 ----
+ SET_PF_WAIT_EVENT(pthread_run);
+ pthread_mutex_unlock(mutex);
+
++ pthread_run->data.mutex = mutex;
++
++ SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
+ /* Reschedule will unlock pthread_run */
+ pthread_resched_resume(PS_COND_WAIT);
++ CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
++
++ pthread_run->data.mutex = NULL;
+
+ /* Remove ourselves from sleep queue. If we fail then we timedout */
+ if (sleep_cancel(pthread_run) == NOTOK) {
+***************
+*** 285,292 ****
+--- 305,318 ----
+ SET_PF_WAIT_EVENT(pthread_run);
+ pthread_mutex_unlock(mutex);
+
++ pthread_run->data.mutex = mutex;
++
++ SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
+ /* Reschedule will unlock pthread_run */
+ pthread_resched_resume(PS_COND_WAIT);
++ CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
++
++ pthread_run->data.mutex = NULL;
+
+ /* Remove ourselves from sleep queue. If we fail then we timedout */
+ if (sleep_cancel(pthread_run) == NOTOK) {
+=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/fd.c,v retrieving revision 1.1.1.1
+diff -c -r1.1.1.1 fd.c
+*** fd.c 1996/02/09 02:54:19 1.1.1.1
+--- fd.c 1996/10/03 01:33:03
+***************
+*** 48,54 ****
+--- 48,59 ----
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <sys/uio.h>
++ #include <sys/ioctl.h>
++ #if __STDC__
+ #include <stdarg.h>
++ #else
++ #include <varargs.h>
++ #endif
+ #include <fcntl.h>
+ #include <errno.h>
+ #include <pthread/posix.h>
+***************
+*** 62,67 ****
+--- 67,74 ----
+ static const int dtablecount = 4096/sizeof(struct fd_table_entry);
+ int dtablesize;
+
++ static int fd_get_pthread_fd_from_kernel_fd( int );
++
+ /* ==========================================================================
+ * Allocate dtablecount entries at once and populate the fd_table.
+ *
+***************
+*** 199,204 ****
+--- 206,244 ----
+ return(NOTOK);
+ }
+
++ /*----------------------------------------------------------------------
++ * Function: fd_get_pthread_fd_from_kernel_fd
++ * Purpose: get the fd_table index of a kernel fd
++ * Args: fd = kernel fd to convert
++ * Returns: fd_table index, -1 if not found
++ * Notes:
++ *----------------------------------------------------------------------*/
++ static int
++ fd_get_pthread_fd_from_kernel_fd( int kfd )
++ {
++ int j;
++
++ /* This is *SICK*, but unless there is a faster way to
++ * turn a kernel fd into an fd_table index, this has to do.
++ */
++ for( j=0; j < dtablesize; j++ ) {
++ if( fd_table[j] &&
++ fd_table[j]->type != FD_NT &&
++ fd_table[j]->type != FD_NIU &&
++ fd_table[j]->fd.i == kfd ) {
++ return j;
++ }
++ }
++
++ /* Not listed byfd, Check for kernel fd == pthread fd */
++ if( fd_table[kfd] == NULL || fd_table[kfd]->type == FD_NT ) {
++ /* Assume that the kernel fd is the same */
++ return kfd;
++ }
++
++ return NOTOK; /* Not found */
++ }
++
+ /* ==========================================================================
+ * fd_basic_basic_unlock()
+ *
+***************
+*** 288,293 ****
+--- 328,334 ----
+ switch (fd_table[fd]->type) {
+ case FD_NIU:
+ /* If not in use return EBADF error */
++ SET_ERRNO(EBADF);
+ return(NOTOK);
+ break;
+ case FD_NT:
+***************
+*** 297,302 ****
+--- 338,344 ----
+ */
+ fd_kern_init(fd);
+ if (fd_table[fd]->type == FD_NIU) {
++ SET_ERRNO(EBADF);
+ return(NOTOK);
+ }
+ break;
+***************
+*** 409,414 ****
+--- 451,545 ----
+ return(OK);
+ }
+
++ /*----------------------------------------------------------------------
++ * Function: fd_unlock_for_cancel
++ * Purpose: Unlock all fd locks held prior to being cancelled
++ * Args: void
++ * Returns:
++ * OK or NOTOK
++ * Notes:
++ * Assumes the kernel is locked on entry
++ *----------------------------------------------------------------------*/
++ int
++ fd_unlock_for_cancel( void )
++ {
++ int i, fd;
++ struct pthread_select_data *data;
++ int rdlk, wrlk, lktype;
++ int found;
++
++ /* What we do depends on the previous state of the thread */
++ switch( pthread_run->old_state ) {
++ case PS_RUNNING:
++ case PS_JOIN:
++ case PS_SLEEP_WAIT:
++ case PS_WAIT_WAIT:
++ case PS_SIGWAIT:
++ case PS_FDLR_WAIT:
++ case PS_FDLW_WAIT:
++ case PS_DEAD:
++ case PS_UNALLOCED:
++ break; /* Nothing to do */
++
++ case PS_COND_WAIT:
++ CLEAR_PF_GROUP( pthread_run, PF_EVENT_GROUP );
++ /* Must reaquire the mutex according to the standard */
++ if( pthread_run->data.mutex == NULL ) {
++ PANIC();
++ }
++ pthread_mutex_lock( pthread_run->data.mutex );
++ break;
++
++ case PS_FDR_WAIT:
++ CLEAR_PF_GROUP( pthread_run, PF_EVENT_GROUP);
++ /* Free the lock on the fd being used */
++ fd = fd_get_pthread_fd_from_kernel_fd( pthread_run->data.fd.fd );
++ if( fd == NOTOK ) {
++ PANIC(); /* Can't find fd */
++ }
++ fd_unlock( fd, FD_READ );
++ break;
++
++ case PS_FDW_WAIT: /* Waiting on i/o */
++ CLEAR_PF_GROUP( pthread_run, PF_EVENT_GROUP);
++ /* Free the lock on the fd being used */
++ fd = fd_get_pthread_fd_from_kernel_fd( pthread_run->data.fd.fd );
++ if( fd == NOTOK ) {
++ PANIC(); /* Can't find fd */
++ }
++ fd_unlock( fd, FD_WRITE );
++ break;
++
++ case PS_SELECT_WAIT:
++ data = pthread_run->data.select_data;
++
++ CLEAR_PF_GROUP( pthread_run, PF_EVENT_GROUP);
++
++ for( i = 0; i < data->nfds; i++) {
++ rdlk =(FD_ISSET(i,&data->readfds)
++ || FD_ISSET(i,&data->exceptfds));
++ wrlk = FD_ISSET(i, &data->writefds);
++ lktype = rdlk ? (wrlk ? FD_RDWR : FD_READ) : FD_WRITE;
++
++ if( ! (rdlk || wrlk) )
++ continue; /* No locks, no unlock */
++
++ if( (fd = fd_get_pthread_fd_from_kernel_fd( i )) == NOTOK ) {
++ PANIC(); /* Can't find fd */
++ }
++
++ fd_unlock( fd, lktype );
++ }
++ break;
++
++ case PS_MUTEX_WAIT:
++ PANIC(); /* Should never cancel a mutex wait */
++
++ default:
++ PANIC(); /* Unknown thread status */
++ }
++ }
++
+ /* ==========================================================================
+ * fd_lock()
+ */
+***************
+*** 476,481 ****
+--- 607,616 ----
+ ret = fd_table[fd]->ops->read(fd_table[fd]->fd,
+ fd_table[fd]->flags, buf, nbytes, timeout);
+ fd_unlock(fd, FD_READ);
++ if( ret < 0 ) {
++ SET_ERRNO(-ret);
++ ret = NOTOK;
++ }
+ }
+ return(ret);
+ }
+***************
+*** 500,505 ****
+--- 635,644 ----
+ ret = fd_table[fd]->ops->readv(fd_table[fd]->fd,
+ fd_table[fd]->flags, iov, iovcnt, timeout);
+ fd_unlock(fd, FD_READ);
++ if( ret < 0 ) {
++ SET_ERRNO(-ret);
++ ret = NOTOK;
++ }
+ }
+ return(ret);
+ }
+***************
+*** 524,529 ****
+--- 663,672 ----
+ ret = fd_table[fd]->ops->write(fd_table[fd]->fd,
+ fd_table[fd]->flags, buf, nbytes, timeout);
+ fd_unlock(fd, FD_WRITE);
++ if( ret < 0 ) {
++ SET_ERRNO(-ret);
++ ret = NOTOK;
++ }
+ }
+ return(ret);
+ }
+***************
+*** 548,553 ****
+--- 691,700 ----
+ ret = fd_table[fd]->ops->writev(fd_table[fd]->fd,
+ fd_table[fd]->flags, iov, iovcnt, timeout);
+ fd_unlock(fd, FD_WRITE);
++ if( ret < 0 ) {
++ SET_ERRNO(-ret);
++ ret = NOTOK;
++ }
+ }
+ return(ret);
+ }
+***************
+*** 599,677 ****
+ union fd_data realfd;
+ int ret, flags;
+
+ /* Need to lock the newfd by hand */
+! if (fd < dtablesize) {
+! pthread_mutex_lock(&fd_table_mutex);
+! if (fd_table[fd]) {
+! pthread_mutex_unlock(&fd_table_mutex);
+! mutex = &(fd_table[fd]->mutex);
+! pthread_mutex_lock(mutex);
+
+! /*
+! * XXX Gross hack ... because of fork(), any fd closed by the
+! * parent should not change the fd of the child, unless it owns it.
+ */
+! switch(fd_table[fd]->type) {
+! case FD_NIU:
+! pthread_mutex_unlock(mutex);
+! ret = -EINVAL;
+! break;
+! case FD_NT:
+! /*
+! * If it's not tested then the only valid possibility is it's
+! * kernel fd.
+! */
+! ret = machdep_sys_close(fd);
+! fd_table[fd]->type = FD_NIU;
+! pthread_mutex_unlock(mutex);
+! break;
+! case FD_TEST_FULL_DUPLEX:
+! case FD_TEST_HALF_DUPLEX:
+ realfd = fd_table[fd]->fd;
+ flags = fd_table[fd]->flags;
+ if ((entry = fd_free(fd)) == NULL) {
+! ret = fd_table[fd]->ops->close(realfd, flags);
+ } else {
+! /* There can't be any others waiting for fd. */
+ pthread_mutex_unlock(&entry->mutex);
+ /* Note: entry->mutex = mutex */
+- mutex = &(fd_table[fd]->mutex);
+ }
+ pthread_mutex_unlock(mutex);
+- break;
+- default:
+- ret = fd_basic_lock(fd, FD_RDWR, mutex, NULL);
+- if (ret == OK) {
+- realfd = fd_table[fd]->fd;
+- flags = fd_table[fd]->flags;
+- pthread_mutex_unlock(mutex);
+- if ((entry = fd_free(fd)) == NULL) {
+- ret = fd_table[fd]->ops->close(realfd, flags);
+- } else {
+- fd_basic_basic_unlock(entry, FD_RDWR);
+- pthread_mutex_unlock(&entry->mutex);
+- /* Note: entry->mutex = mutex */
+- }
+- fd_unlock(fd, FD_RDWR);
+- } else {
+- pthread_mutex_unlock(mutex);
+- }
+- break;
+ }
+! } else {
+! /* Don't bother creating a table entry */
+! pthread_mutex_unlock(&fd_table_mutex);
+! ret = machdep_sys_close(fd);
+ }
+! return(ret);
+ }
+! return(-EINVAL);
+ }
+
+ /* ==========================================================================
+ * fd_basic_dup()
+ *
+ * Might need to do more than just what's below.
+ */
+ static inline void fd_basic_dup(int fd, int newfd)
+ {
+--- 746,836 ----
+ union fd_data realfd;
+ int ret, flags;
+
++ if( fd < 0 || fd >= dtablesize ) {
++ SET_ERRNO(EBADF);
++ return -1;
++ }
++
+ /* Need to lock the newfd by hand */
+! pthread_mutex_lock(&fd_table_mutex);
+! if (fd_table[fd]) {
+! pthread_mutex_unlock(&fd_table_mutex);
+! mutex = &(fd_table[fd]->mutex);
+! pthread_mutex_lock(mutex);
+
+! /*
+! * XXX Gross hack ... because of fork(), any fd closed by the
+! * parent should not change the fd of the child, unless it owns it.
+! */
+! switch(fd_table[fd]->type) {
+! case FD_NIU:
+! pthread_mutex_unlock(mutex);
+! ret = -EBADF;
+! break;
+! case FD_NT:
+! /*
+! * If it's not tested then the only valid possibility is it's
+! * kernel fd.
+ */
+! ret = machdep_sys_close(fd);
+! fd_table[fd]->type = FD_NIU;
+! pthread_mutex_unlock(mutex);
+! break;
+! case FD_TEST_FULL_DUPLEX:
+! case FD_TEST_HALF_DUPLEX:
+! realfd = fd_table[fd]->fd;
+! flags = fd_table[fd]->flags;
+! if ((entry = fd_free(fd)) == NULL) {
+! ret = fd_table[fd]->ops->close(realfd, flags);
+! } else {
+! /* There can't be any others waiting for fd. */
+! pthread_mutex_unlock(&entry->mutex);
+! /* Note: entry->mutex = mutex */
+! mutex = &(fd_table[fd]->mutex);
+! }
+! pthread_mutex_unlock(mutex);
+! break;
+! default:
+! ret = fd_basic_lock(fd, FD_RDWR, mutex, NULL);
+! if (ret == OK) {
+ realfd = fd_table[fd]->fd;
+ flags = fd_table[fd]->flags;
++ pthread_mutex_unlock(mutex);
+ if ((entry = fd_free(fd)) == NULL) {
+! ret = fd_table[fd]->ops->close(realfd, flags);
+ } else {
+! fd_basic_basic_unlock(entry, FD_RDWR);
+ pthread_mutex_unlock(&entry->mutex);
+ /* Note: entry->mutex = mutex */
+ }
++ fd_unlock(fd, FD_RDWR);
++ } else {
+ pthread_mutex_unlock(mutex);
+ }
+! break;
+ }
+! } else {
+! /* Don't bother creating a table entry */
+! pthread_mutex_unlock(&fd_table_mutex);
+! ret = machdep_sys_close(fd);
+! }
+!
+! if( ret < 0 ) {
+! SET_ERRNO(-ret);
+! ret = -1;
+ }
+!
+! return ret;
+ }
+
+ /* ==========================================================================
+ * fd_basic_dup()
+ *
+ * Might need to do more than just what's below.
++ *
++ * This is a MAJOR guess!! I don't know if the mutext unlock is valid
++ * in the BIG picture. But it seems to be needed to avoid deadlocking
++ * with ourselves when we try to close the duped file descriptor.
+ */
+ static inline void fd_basic_dup(int fd, int newfd)
+ {
+***************
+*** 679,684 ****
+--- 838,845 ----
+ fd_table[fd]->next = fd_table[newfd];
+ fd_table[newfd] = fd_table[fd];
+ fd_table[fd]->count++;
++ pthread_mutex_unlock(&fd_table[newfd]->next->mutex);
++
+ }
+
+ /* ==========================================================================
+***************
+*** 896,904 ****
+ * ala select()... --SNL
+ */
+ int
+! ioctl(int fd, unsigned long request, caddr_t arg)
+ {
+ int ret;
+
+ if (fd < 0 || fd >= dtablesize)
+ ret = NOTOK;
+--- 1057,1071 ----
+ * ala select()... --SNL
+ */
+ int
+! ioctl(int fd, int request, ...)
+ {
+ int ret;
++ pthread_va_list ap;
++ caddr_t arg;
++
++ va_start( ap, request ); /* Get the arg */
++ arg = va_arg(ap,caddr_t);
++ va_end( ap );
+
+ if (fd < 0 || fd >= dtablesize)
+ ret = NOTOK;
+***************
+*** 906,911 ****
+--- 1073,1086 ----
+ ret = machdep_sys_ioctl(fd, request, arg);
+ else if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
+ ret = machdep_sys_ioctl(fd_table[fd]->fd.i, request, arg);
++ if( ret == 0 && request == FIONBIO ) {
++ /* Properly set NONBLOCK flag */
++ int v = *(int *)arg;
++ if( v )
++ fd_table[fd]->flags |= __FD_NONBLOCK;
++ else
++ fd_table[fd]->flags &= ~__FD_NONBLOCK;
++ }
+ fd_unlock(fd, FD_RDWR);
+ }
+ return ret;
+=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/fd_kern.c,v retrieving revision 1.1.1.1
+diff -c -r1.1.1.1 fd_kern.c
+*** fd_kern.c 1996/02/12 00:58:30 1.1.1.1
+--- fd_kern.c 1996/10/03 01:54:15
+***************
+*** 128,134 ****
+
+
+ if ((count = machdep_sys_select(dtablesize, &fd_set_read,
+! &fd_set_write, NULL, &__fd_kern_poll_timeout)) < OK) {
+ if (count == -EINTR) {
+ return;
+ }
+--- 128,134 ----
+
+
+ if ((count = machdep_sys_select(dtablesize, &fd_set_read,
+! &fd_set_write, &fd_set_except, &__fd_kern_poll_timeout)) < OK) {
+ if (count == -EINTR) {
+ return;
+ }
+***************
+*** 167,200 ****
+
+ for (pthread = fd_wait_select.q_next; count && pthread; ) {
+ int found_one = 0;
+
+ for (i = 0; i < pthread->data.select_data->nfds; i++) {
+ int count_dec = 0;
+
+! if ((FD_ISSET(i, &pthread->data.select_data->exceptfds) &&
+! ! FD_ISSET(i, &fd_set_except))) {
+! FD_CLR(i, &pthread->data.select_data->exceptfds);
+! } else {
+! count_dec++;
+ }
+! if ((FD_ISSET(i, &pthread->data.select_data->writefds) &&
+! ! FD_ISSET(i, &fd_set_write))) {
+! FD_CLR(i, &pthread->data.select_data->writefds);
+! } else {
+! count_dec++;
+ }
+! if ((FD_ISSET(i, &pthread->data.select_data->readfds) &&
+! ! FD_ISSET(i, &fd_set_read))) {
+! FD_CLR(i, &pthread->data.select_data->readfds);
+! } else {
+! count_dec++;
+ }
+ if (count_dec) {
+ found_one++;
+ count--;
+ }
+ }
+ if (found_one) {
+ deq = pthread;
+ pthread = pthread->next;
+ pthread_queue_remove(&fd_wait_select, deq);
+--- 167,223 ----
+
+ for (pthread = fd_wait_select.q_next; count && pthread; ) {
+ int found_one = 0;
++ fd_set tmp_readfds, tmp_writefds, tmp_exceptfds;
++
++ memcpy(&tmp_readfds, &pthread->data.select_data->readfds,
++ sizeof(fd_set));
++ memcpy(&tmp_writefds, &pthread->data.select_data->writefds,
++ sizeof(fd_set));
++ memcpy(&tmp_exceptfds, &pthread->data.select_data->exceptfds,
++ sizeof(fd_set));
+
+ for (i = 0; i < pthread->data.select_data->nfds; i++) {
+ int count_dec = 0;
+
+! if( (FD_ISSET(i, &tmp_exceptfds)) ) {
+! if( FD_ISSET(i, &fd_set_except) ) {
+! count_dec++; /* got a hit */
+! } else {
+! FD_CLR(i, &tmp_exceptfds);
+! }
+ }
+!
+! if( (FD_ISSET(i, &tmp_writefds)) ) {
+! if( FD_ISSET(i, &fd_set_write) ) {
+! count_dec++; /* got a hit */
+! } else {
+! FD_CLR(i, &tmp_writefds);
+! }
+ }
+!
+! if( (FD_ISSET(i, &tmp_readfds)) ) {
+! if( FD_ISSET(i, &fd_set_read) ) {
+! count_dec++; /* got a hit */
+! } else {
+! FD_CLR(i, &tmp_readfds);
+! }
+ }
++
+ if (count_dec) {
+ found_one++;
+ count--;
+ }
+ }
++
+ if (found_one) {
++ /* Update the threads saved select data fd sets */
++ memcpy(&pthread->data.select_data->readfds, &tmp_readfds,
++ sizeof(fd_set));
++ memcpy(&pthread->data.select_data->writefds, &tmp_writefds,
++ sizeof(fd_set));
++ memcpy(&pthread->data.select_data->exceptfds, &tmp_exceptfds,
++ sizeof(fd_set));
++
+ deq = pthread;
+ pthread = pthread->next;
+ pthread_queue_remove(&fd_wait_select, deq);
+***************
+*** 266,272 ****
+ */
+
+ while ((count = machdep_sys_select(dtablesize, &fd_set_read,
+! &fd_set_write, NULL, &__fd_kern_wait_timeout)) < OK) {
+ if (count == -EINTR) {
+ return;
+ }
+--- 289,295 ----
+ */
+
+ while ((count = machdep_sys_select(dtablesize, &fd_set_read,
+! &fd_set_write, &fd_set_except, &__fd_kern_wait_timeout)) < OK) {
+ if (count == -EINTR) {
+ return;
+ }
+***************
+*** 305,338 ****
+
+ for (pthread = fd_wait_select.q_next; count && pthread; ) {
+ int found_one = 0;
+
+ for (i = 0; i < pthread->data.select_data->nfds; i++) {
+ int count_dec = 0;
+
+! if ((FD_ISSET(i, &pthread->data.select_data->exceptfds) &&
+! ! FD_ISSET(i, &fd_set_except))) {
+! FD_CLR(i, &pthread->data.select_data->exceptfds);
+! } else {
+! count_dec++;
+ }
+! if ((FD_ISSET(i, &pthread->data.select_data->writefds) &&
+! ! FD_ISSET(i, &fd_set_write))) {
+! FD_CLR(i, &pthread->data.select_data->writefds);
+! } else {
+! count_dec++;
+ }
+! if ((FD_ISSET(i, &pthread->data.select_data->readfds) &&
+! ! FD_ISSET(i, &fd_set_read))) {
+! FD_CLR(i, &pthread->data.select_data->readfds);
+! } else {
+! count_dec++;
+ }
+ if (count_dec) {
+ found_one++;
+ count--;
+ }
+ }
+ if (found_one) {
+ deq = pthread;
+ pthread = pthread->next;
+ pthread_queue_remove(&fd_wait_select, deq);
+--- 328,383 ----
+
+ for (pthread = fd_wait_select.q_next; count && pthread; ) {
+ int found_one = 0;
++ fd_set tmp_readfds, tmp_writefds, tmp_exceptfds;
++
++ memcpy(&tmp_readfds, &pthread->data.select_data->readfds,
++ sizeof(fd_set));
++ memcpy(&tmp_writefds, &pthread->data.select_data->writefds,
++ sizeof(fd_set));
++ memcpy(&tmp_exceptfds, &pthread->data.select_data->exceptfds,
++ sizeof(fd_set));
+
+ for (i = 0; i < pthread->data.select_data->nfds; i++) {
+ int count_dec = 0;
+
+! if( (FD_ISSET(i, &tmp_exceptfds)) ) {
+! if( FD_ISSET(i, &fd_set_except) ) {
+! count_dec++; /* got a hit */
+! } else {
+! FD_CLR(i, &tmp_exceptfds);
+! }
+ }
+!
+! if( (FD_ISSET(i, &tmp_writefds)) ) {
+! if( FD_ISSET(i, &fd_set_write) ) {
+! count_dec++; /* got a hit */
+! } else {
+! FD_CLR(i, &tmp_writefds);
+! }
+ }
+!
+! if( (FD_ISSET(i, &tmp_readfds)) ) {
+! if( FD_ISSET(i, &fd_set_read) ) {
+! count_dec++; /* got a hit */
+! } else {
+! FD_CLR(i, &tmp_readfds);
+! }
+ }
++
+ if (count_dec) {
+ found_one++;
+ count--;
+ }
+ }
+ if (found_one) {
++ /* Update the threads saved select data fd sets */
++ memcpy(&pthread->data.select_data->readfds, &tmp_readfds,
++ sizeof(fd_set));
++ memcpy(&pthread->data.select_data->writefds, &tmp_writefds,
++ sizeof(fd_set));
++ memcpy(&pthread->data.select_data->exceptfds, &tmp_exceptfds,
++ sizeof(fd_set));
++
+ deq = pthread;
+ pthread = pthread->next;
+ pthread_queue_remove(&fd_wait_select, deq);
+***************
+*** 380,404 ****
+ machdep_gettimeofday(&current_time);
+ sleep_schedule(&current_time, timeout);
+
+ pthread_resched_resume(PS_FDR_WAIT);
+
+ /* We're awake */
+ pthread_sched_prevent();
+ if (sleep_cancel(pthread_run) == NOTOK) {
+ CLEAR_PF_DONE_EVENT(pthread_run);
+ pthread_sched_resume();
+- SET_ERRNO(ETIMEDOUT);
+ ret = -ETIMEDOUT;
+ break;
+ }
+ pthread_sched_resume();
+ } else {
+ pthread_resched_resume(PS_FDR_WAIT);
+ }
+ CLEAR_PF_DONE_EVENT(pthread_run);
+ } else {
+- SET_ERRNO(-ret);
+- ret = NOTOK;
+ break;
+ }
+ }
+--- 425,450 ----
+ machdep_gettimeofday(&current_time);
+ sleep_schedule(&current_time, timeout);
+
++ SET_PF_AT_CANCEL_POINT(pthread_run);
+ pthread_resched_resume(PS_FDR_WAIT);
++ CLEAR_PF_AT_CANCEL_POINT(pthread_run);
+
+ /* We're awake */
+ pthread_sched_prevent();
+ if (sleep_cancel(pthread_run) == NOTOK) {
+ CLEAR_PF_DONE_EVENT(pthread_run);
+ pthread_sched_resume();
+ ret = -ETIMEDOUT;
+ break;
+ }
+ pthread_sched_resume();
+ } else {
++ SET_PF_AT_CANCEL_POINT(pthread_run);
+ pthread_resched_resume(PS_FDR_WAIT);
++ CLEAR_PF_AT_CANCEL_POINT(pthread_run);
+ }
+ CLEAR_PF_DONE_EVENT(pthread_run);
+ } else {
+ break;
+ }
+ }
+***************
+*** 437,443 ****
+ if (sleep_cancel(pthread_run) == NOTOK) {
+ CLEAR_PF_DONE_EVENT(pthread_run);
+ pthread_sched_resume();
+- SET_ERRNO(ETIMEDOUT);
+ ret = -ETIMEDOUT;
+ break;
+ }
+--- 483,488 ----
+***************
+*** 447,454 ****
+ }
+ CLEAR_PF_DONE_EVENT(pthread_run);
+ } else {
+- SET_ERRNO(-ret);
+- ret = NOTOK;
+ break;
+ }
+ }
+--- 492,497 ----
+***************
+*** 480,504 ****
+ machdep_gettimeofday(&current_time);
+ sleep_schedule(&current_time, timeout);
+
+ pthread_resched_resume(PS_FDW_WAIT);
+
+ /* We're awake */
+ pthread_sched_prevent();
+ if (sleep_cancel(pthread_run) == NOTOK) {
+ CLEAR_PF_DONE_EVENT(pthread_run);
+ pthread_sched_resume();
+- SET_ERRNO(ETIMEDOUT);
+ ret = -ETIMEDOUT;
+ break;
+ }
+ pthread_sched_resume();
+ } else {
+ pthread_resched_resume(PS_FDW_WAIT);
+ }
+ CLEAR_PF_DONE_EVENT(pthread_run);
+ } else {
+- SET_ERRNO(-ret);
+- ret = NOTOK;
+ break;
+ }
+ }
+--- 523,548 ----
+ machdep_gettimeofday(&current_time);
+ sleep_schedule(&current_time, timeout);
+
++ SET_PF_AT_CANCEL_POINT(pthread_run);
+ pthread_resched_resume(PS_FDW_WAIT);
++ CLEAR_PF_AT_CANCEL_POINT(pthread_run);
+
+ /* We're awake */
+ pthread_sched_prevent();
+ if (sleep_cancel(pthread_run) == NOTOK) {
+ CLEAR_PF_DONE_EVENT(pthread_run);
+ pthread_sched_resume();
+ ret = -ETIMEDOUT;
+ break;
+ }
+ pthread_sched_resume();
+ } else {
++ SET_PF_AT_CANCEL_POINT(pthread_run);
+ pthread_resched_resume(PS_FDW_WAIT);
++ CLEAR_PF_AT_CANCEL_POINT(pthread_run);
+ }
+ CLEAR_PF_DONE_EVENT(pthread_run);
+ } else {
+ break;
+ }
+ }
+***************
+*** 537,543 ****
+ if (sleep_cancel(pthread_run) == NOTOK) {
+ CLEAR_PF_DONE_EVENT(pthread_run);
+ pthread_sched_resume();
+- SET_ERRNO(ETIMEDOUT);
+ ret = -ETIMEDOUT;
+ break;
+ }
+--- 581,586 ----
+***************
+*** 547,554 ****
+ }
+ CLEAR_PF_DONE_EVENT(pthread_run);
+ } else {
+- SET_ERRNO(-ret);
+- ret = NOTOK;
+ break;
+ }
+ }
+--- 590,595 ----
+***************
+*** 662,668 ****
+ */
+ int create(const char *path, mode_t mode)
+ {
+! return creat (path, mode);
+ }
+
+ /* ==========================================================================
+--- 703,709 ----
+ */
+ int create(const char *path, mode_t mode)
+ {
+! return creat (path, mode);
+ }
+
+ /* ==========================================================================
+***************
+*** 672,678 ****
+
+ int creat(const char *path, mode_t mode)
+ {
+! return open (path, O_CREAT | O_TRUNC | O_WRONLY, mode);
+ }
+
+ /* ==========================================================================
+--- 713,719 ----
+
+ int creat(const char *path, mode_t mode)
+ {
+! return open (path, O_CREAT | O_TRUNC | O_WRONLY, mode);
+ }
+
+ /* ==========================================================================
+***************
+*** 1079,1090 ****
+ int bind(int fd, const struct sockaddr *name, int namelen)
+ {
+ /* Not much to do in bind */
+- semaphore *plock;
+ int ret;
+
+ if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
+ if ((ret = machdep_sys_bind(fd_table[fd]->fd.i, name, namelen)) < OK) {
+ SET_ERRNO(-ret);
+ }
+ fd_unlock(fd, FD_RDWR);
+ }
+--- 1120,1131 ----
+ int bind(int fd, const struct sockaddr *name, int namelen)
+ {
+ /* Not much to do in bind */
+ int ret;
+
+ if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
+ if ((ret = machdep_sys_bind(fd_table[fd]->fd.i, name, namelen)) < OK) {
+ SET_ERRNO(-ret);
++ ret = NOTOK;
+ }
+ fd_unlock(fd, FD_RDWR);
+ }
+***************
+*** 1100,1113 ****
+ */
+ int connect(int fd, const struct sockaddr *name, int namelen)
+ {
+! struct sockaddr tmpname;
+! int ret, tmpnamelen;
+
+! if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
+ if ((ret = machdep_sys_connect(fd_table[fd]->fd.i, name, namelen)) < OK) {
+ if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
+! ((ret == -EWOULDBLOCK) || (ret == -EINPROGRESS) ||
+! (ret == -EALREADY) || (ret == -EAGAIN))) {
+ pthread_sched_prevent();
+
+ /* queue pthread for a FDW_WAIT */
+--- 1141,1154 ----
+ */
+ int connect(int fd, const struct sockaddr *name, int namelen)
+ {
+! struct sockaddr tmpname;
+! int ret, tmpnamelen;
+
+! if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
+ if ((ret = machdep_sys_connect(fd_table[fd]->fd.i, name, namelen)) < OK) {
+ if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
+! ((ret == -EWOULDBLOCK) || (ret == -EINPROGRESS) ||
+! (ret == -EALREADY) || (ret == -EAGAIN))) {
+ pthread_sched_prevent();
+
+ /* queue pthread for a FDW_WAIT */
+***************
+*** 1121,1131 ****
+ tmpnamelen = sizeof(tmpname);
+ /* OK now lets see if it really worked */
+ if (((ret = machdep_sys_getpeername(fd_table[fd]->fd.i,
+! &tmpname, &tmpnamelen)) < OK) && (ret == -ENOTCONN)) {
+
+ /* Get the error, this function should not fail */
+ machdep_sys_getsockopt(fd_table[fd]->fd.i, SOL_SOCKET,
+! SO_ERROR, &pthread_run->error, &tmpnamelen);
+ }
+ } else {
+ SET_ERRNO(-ret);
+--- 1162,1180 ----
+ tmpnamelen = sizeof(tmpname);
+ /* OK now lets see if it really worked */
+ if (((ret = machdep_sys_getpeername(fd_table[fd]->fd.i,
+! &tmpname, &tmpnamelen)) < OK)
+! && (ret == -ENOTCONN)) {
+
+ /* Get the error, this function should not fail */
+ machdep_sys_getsockopt(fd_table[fd]->fd.i, SOL_SOCKET,
+! SO_ERROR, &ret, &tmpnamelen);
+! SET_ERRNO(-ret);
+! ret = NOTOK;
+! } else {
+! if( ret < 0 ) {
+! SET_ERRNO(-ret);
+! ret = NOTOK;
+! }
+ }
+ } else {
+ SET_ERRNO(-ret);
+***************
+*** 1133,1140 ****
+ }
+ }
+ fd_unlock(fd, FD_RDWR);
+! }
+! return(ret);
+ }
+
+ #endif
+--- 1182,1189 ----
+ }
+ }
+ fd_unlock(fd, FD_RDWR);
+! }
+! return(ret);
+ }
+
+ #endif
+***************
+*** 1164,1170 ****
+ } else {
+ fd_unlock(fd, FD_RDWR);
+ SET_ERRNO(-fd_kern);
+! return(fd_kern);
+ }
+ }
+ fd_unlock(fd, FD_RDWR);
+--- 1213,1219 ----
+ } else {
+ fd_unlock(fd, FD_RDWR);
+ SET_ERRNO(-fd_kern);
+! return(NOTOK);
+ }
+ }
+ fd_unlock(fd, FD_RDWR);
+***************
+*** 1198,1205 ****
+ int ret;
+
+ if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
+! ret = machdep_sys_listen(fd_table[fd]->fd.i, backlog);
+! if ((ret = machdep_sys_listen(fd_table[fd]->fd.i, backlog)) < OK) {
+ SET_ERRNO(-ret);
+ ret = NOTOK;
+ }
+--- 1247,1253 ----
+ int ret;
+
+ if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
+! if ((ret = machdep_sys_listen(fd_table[fd]->fd.i, backlog)) < OK) {
+ SET_ERRNO(-ret);
+ ret = NOTOK;
+ }
+***************
+*** 1246,1252 ****
+ CLEAR_PF_DONE_EVENT(pthread_run);
+ pthread_sched_resume();
+ SET_ERRNO(ETIMEDOUT);
+! ret = -ETIMEDOUT;
+ break;
+ }
+ pthread_sched_resume();
+--- 1294,1300 ----
+ CLEAR_PF_DONE_EVENT(pthread_run);
+ pthread_sched_resume();
+ SET_ERRNO(ETIMEDOUT);
+! ret = NOTOK;
+ break;
+ }
+ pthread_sched_resume();
+***************
+*** 1311,1317 ****
+ CLEAR_PF_DONE_EVENT(pthread_run);
+ pthread_sched_resume();
+ SET_ERRNO(ETIMEDOUT);
+! ret = -ETIMEDOUT;
+ break;
+ }
+ pthread_sched_resume();
+--- 1359,1365 ----
+ CLEAR_PF_DONE_EVENT(pthread_run);
+ pthread_sched_resume();
+ SET_ERRNO(ETIMEDOUT);
+! ret = NOTOK;
+ break;
+ }
+ pthread_sched_resume();
+***************
+*** 1405,1411 ****
+ CLEAR_PF_DONE_EVENT(pthread_run);
+ pthread_sched_resume();
+ SET_ERRNO(ETIMEDOUT);
+! ret = -ETIMEDOUT;
+ break;
+ }
+ pthread_sched_resume();
+--- 1453,1459 ----
+ CLEAR_PF_DONE_EVENT(pthread_run);
+ pthread_sched_resume();
+ SET_ERRNO(ETIMEDOUT);
+! ret = NOTOK;
+ break;
+ }
+ pthread_sched_resume();
+***************
+*** 1471,1477 ****
+ CLEAR_PF_DONE_EVENT(pthread_run);
+ pthread_sched_resume();
+ SET_ERRNO(ETIMEDOUT);
+! ret = -ETIMEDOUT;
+ break;
+ }
+ pthread_sched_resume();
+--- 1519,1525 ----
+ CLEAR_PF_DONE_EVENT(pthread_run);
+ pthread_sched_resume();
+ SET_ERRNO(ETIMEDOUT);
+! ret = NOTOK;
+ break;
+ }
+ pthread_sched_resume();
+***************
+*** 1536,1542 ****
+ CLEAR_PF_DONE_EVENT(pthread_run);
+ pthread_sched_resume();
+ SET_ERRNO(ETIMEDOUT);
+! ret = -ETIMEDOUT;
+ break;
+ }
+ pthread_sched_resume();
+--- 1584,1590 ----
+ CLEAR_PF_DONE_EVENT(pthread_run);
+ pthread_sched_resume();
+ SET_ERRNO(ETIMEDOUT);
+! ret = NOTOK;
+ break;
+ }
+ pthread_sched_resume();
+***************
+*** 1603,1609 ****
+ CLEAR_PF_DONE_EVENT(pthread_run);
+ pthread_sched_resume();
+ SET_ERRNO(ETIMEDOUT);
+! ret = -ETIMEDOUT;
+ break;
+ }
+ pthread_sched_resume();
+--- 1651,1657 ----
+ CLEAR_PF_DONE_EVENT(pthread_run);
+ pthread_sched_resume();
+ SET_ERRNO(ETIMEDOUT);
+! ret = NOTOK;
+ break;
+ }
+ pthread_sched_resume();
+***************
+*** 1734,1744 ****
+ */
+ int getsockopt(int fd, int level, int optname, void * optval, int * optlen)
+ {
+! int ret;
+
+! if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
+ if ((ret = machdep_sys_getsockopt(fd_table[fd]->fd.i, level,
+! optname, optval, optlen)) < OK) {
+ SET_ERRNO(-ret);
+ ret = NOTOK;
+ }
+--- 1782,1792 ----
+ */
+ int getsockopt(int fd, int level, int optname, void * optval, int * optlen)
+ {
+! int ret;
+
+! if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
+ if ((ret = machdep_sys_getsockopt(fd_table[fd]->fd.i, level,
+! optname, optval, optlen)) < OK) {
+ SET_ERRNO(-ret);
+ ret = NOTOK;
+ }
+***************
+*** 1756,1772 ****
+ */
+ int getsockname(int fd, struct sockaddr * name, int * naddrlen)
+ {
+! int ret;
+
+! if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
+! if ((ret = machdep_sys_getsockname(fd_table[fd]->fd.i,
+! name, naddrlen)) < OK) {
+! SET_ERRNO(-ret);
+! ret = NOTOK;
+! }
+! fd_unlock(fd, FD_RDWR);
+! }
+! return ret;
+ }
+
+ #endif
+--- 1804,1820 ----
+ */
+ int getsockname(int fd, struct sockaddr * name, int * naddrlen)
+ {
+! int ret;
+
+! if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
+! if ((ret = machdep_sys_getsockname(fd_table[fd]->fd.i,
+! name, naddrlen)) < OK) {
+! SET_ERRNO(-ret);
+! ret = NOTOK;
+! }
+! fd_unlock(fd, FD_RDWR);
+! }
+! return ret;
+ }
+
+ #endif
+***************
+*** 1778,1793 ****
+ */
+ int getpeername(int fd, struct sockaddr * peer, int * paddrlen)
+ {
+! int ret;
+
+! if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
+! if ((ret = machdep_sys_getpeername(fd_table[fd]->fd.i,
+! peer, paddrlen)) < OK) {
+ SET_ERRNO(-ret);
+ ret = NOTOK;
+! }
+! fd_unlock(fd, FD_READ);
+! }
+ return ret;
+ }
+
+--- 1826,1841 ----
+ */
+ int getpeername(int fd, struct sockaddr * peer, int * paddrlen)
+ {
+! int ret;
+
+! if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
+! if ((ret = machdep_sys_getpeername(fd_table[fd]->fd.i,
+! peer, paddrlen)) < OK) {
+ SET_ERRNO(-ret);
+ ret = NOTOK;
+! }
+! fd_unlock(fd, FD_READ);
+! }
+ return ret;
+ }
+
+=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/pthread.c,v retrieving revision 1.1.1.1
+diff -c -r1.1.1.1 pthread.c
+*** pthread.c 1995/12/13 05:53:01 1.1.1.1
+--- pthread.c 1996/10/01 21:42:01
+***************
+*** 129,134 ****
+--- 129,160 ----
+
+ }
+
++ /*----------------------------------------------------------------------
++ * Function: __pthread_is_valid
++ * Purpose: Scan the list of threads to see if a specified thread exists
++ * Args:
++ * pthread = The thread to scan for
++ * Returns:
++ * int = 1 if found, 0 if not
++ * Notes:
++ * The kernel is assumed to be locked
++ *----------------------------------------------------------------------*/
++ int
++ __pthread_is_valid( pthread_t pthread )
++ {
++ int rtn = 0; /* Assume not found */
++ pthread_t t;
++
++ for( t = pthread_link_list; t; t = t->pll ) {
++ if( t == pthread ) {
++ rtn = 1; /* Found it */
++ break;
++ }
++ }
++
++ return rtn;
++ }
++
+ /* ==========================================================================
+ * __pthread_free()
+ */
+***************
+*** 242,247 ****
+--- 268,277 ----
+ new_thread->next = NULL;
+ new_thread->flags = 0;
+
++ /* PTHREADS spec says we start with cancellability on and deferred */
++ SET_PF_CANCEL_STATE(new_thread, PTHREAD_CANCEL_ENABLE);
++ SET_PF_CANCEL_TYPE(new_thread, PTHREAD_CANCEL_DEFERRED);
++
+ new_thread->error_p = NULL;
+ new_thread->sll = NULL;
+
+***************
+*** 261,269 ****
+ }
+ return(retval);
+ }
+-
+- /* ==========================================================================
+- * pthread_cancel()
+- *
+- * This routine will also require a sig_prevent/sig_check_and_resume()
+- */
+--- 291,293 ----
+=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/pthread_init.c,v retrieving revision 1.1.1.1
+diff -c -r1.1.1.1 pthread_init.c
+*** pthread_init.c 1996/03/13 04:33:10 1.1.1.1
+--- pthread_init.c 1996/10/01 21:43:59
+***************
+*** 92,99 ****
+ pthread_initial->next = NULL;
+ pthread_initial->flags = 0;
+ pthread_initial->pll = NULL;
+- pthread_initial->flags = 0;
+ pthread_initial->sll = NULL;
+
+ /* Ugly errno hack */
+ pthread_initial->error_p = &errno;
+--- 92,103 ----
+ pthread_initial->next = NULL;
+ pthread_initial->flags = 0;
+ pthread_initial->pll = NULL;
+ pthread_initial->sll = NULL;
++
++ /* PTHREADS spec says we start with cancellability on and deferred */
++ SET_PF_CANCEL_STATE(pthread_initial, PTHREAD_CANCEL_ENABLE);
++ SET_PF_CANCEL_TYPE(pthread_initial, PTHREAD_CANCEL_DEFERRED);
++
+
+ /* Ugly errno hack */
+ pthread_initial->error_p = &errno;
+=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/pthread_join.c,v retrieving revision 1.1.1.1
+diff -c -r1.1.1.1 pthread_join.c
+*** pthread_join.c 1995/12/13 05:53:07 1.1.1.1
+--- pthread_join.c 1996/10/02 16:54:36
+***************
+*** 42,47 ****
+--- 42,49 ----
+ #include <pthread.h>
+ #include <errno.h>
+
++ static int testDeadlock( struct pthread_queue *queue, pthread_t target );
++
+ /* ==========================================================================
+ * pthread_join()
+ */
+***************
+*** 51,56 ****
+--- 53,64 ----
+
+ pthread_sched_prevent();
+
++ /* Ensure they gave us a legal pthread pointer */
++ if( ! __pthread_is_valid( pthread ) ) {
++ pthread_sched_resume();
++ return(EINVAL);
++ }
++
+ /* Check that thread isn't detached already */
+ if (pthread->attr.flags & PTHREAD_DETACHED) {
+ pthread_sched_resume();
+***************
+*** 62,81 ****
+ * Note: This must happen after checking detached state.
+ */
+ if (pthread_queue_remove(&pthread_dead_queue, pthread) != OK) {
+! pthread_queue_enq(&(pthread->join_queue), pthread_run);
+! pthread_resched_resume(PS_JOIN);
+! pthread_sched_prevent();
+!
+! if (pthread_queue_remove(&pthread_dead_queue, pthread) == OK) {
+! pthread_queue_enq(&pthread_alloc_queue, pthread);
+! pthread->attr.flags |= PTHREAD_DETACHED;
+! pthread->state = PS_UNALLOCED;
+! if (thread_return) {
+! *thread_return = pthread->ret;
+! }
+! ret = OK;
+ } else {
+! ret = ESRCH;
+ }
+ } else {
+ /* Just get the return value and detach the thread */
+--- 70,98 ----
+ * Note: This must happen after checking detached state.
+ */
+ if (pthread_queue_remove(&pthread_dead_queue, pthread) != OK) {
+!
+! /* Before we pend on the join, ensure there is no dead lock */
+!
+! if( testDeadlock( &pthread_run->join_queue, pthread ) == NOTOK ) {
+! ret = EDEADLK;
+ } else {
+! pthread_queue_enq(&(pthread->join_queue), pthread_run);
+! SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
+! pthread_resched_resume(PS_JOIN);
+! CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
+! pthread_sched_prevent();
+!
+! if (pthread_queue_remove(&pthread_dead_queue, pthread) == OK) {
+! pthread_queue_enq(&pthread_alloc_queue, pthread);
+! pthread->attr.flags |= PTHREAD_DETACHED;
+! pthread->state = PS_UNALLOCED;
+! if (thread_return) {
+! *thread_return = pthread->ret;
+! }
+! ret = OK;
+! } else {
+! ret = ESRCH;
+! }
+ }
+ } else {
+ /* Just get the return value and detach the thread */
+***************
+*** 89,92 ****
+--- 106,139 ----
+ }
+ pthread_sched_resume();
+ return(ret);
++ }
++
++ /*----------------------------------------------------------------------
++ * Function: testDeadlock
++ * Purpose: recursive queue walk to check for deadlocks
++ * Args:
++ * queue = the queue to walk
++ * pthread = target to scan for
++ * Returns:
++ * OK = no deadlock, NOTOK = deadlock
++ * Notes:
++ *----------------------------------------------------------------------*/
++ static int
++ testDeadlock( struct pthread_queue *queue, pthread_t target )
++ {
++ pthread_t t;
++
++ if( queue == NULL )
++ return OK; /* Empty queue, obviously ok */
++
++ for( t = queue->q_next; t; t = t->next ) {
++ if( t == target )
++ return NOTOK; /* bang, your dead */
++
++ if( testDeadlock( &t->join_queue, target ) == NOTOK ) {
++ return NOTOK;
++ }
++ }
++
++ return OK; /* No deadlock */
+ }
+=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/select.c,v retrieving revision 1.1.1.1
+diff -c -r1.1.1.1 select.c
+*** select.c 1996/03/05 08:29:14 1.1.1.1
+--- select.c 1996/10/02 16:56:27
+***************
+*** 56,220 ****
+ int select(int numfds, fd_set *readfds, fd_set *writefds,
+ fd_set *exceptfds, struct timeval *timeout)
+ {
+! fd_set real_exceptfds, real_readfds, real_writefds; /* mapped fd_sets */
+! fd_set * real_readfds_p, * real_writefds_p, * real_exceptfds_p;
+! fd_set read_locks, write_locks, rdwr_locks;
+! struct timespec timeout_time, current_time;
+! struct timeval zero_timeout = { 0, 0 };
+! int i, j, ret = 0, got_all_locks = 1;
+! struct pthread_select_data data;
+!
+! if (numfds > dtablesize) {
+! numfds = dtablesize;
+! }
+!
+! data.nfds = 0;
+! FD_ZERO(&data.readfds);
+! FD_ZERO(&data.writefds);
+! FD_ZERO(&data.exceptfds);
+
+! /* Do this first */
+! if (timeout) {
+ machdep_gettimeofday(&current_time);
+! timeout_time.tv_sec = current_time.tv_sec + timeout->tv_sec;
+! if ((timeout_time.tv_nsec = current_time.tv_nsec +
+! (timeout->tv_usec * 1000)) > 1000000000) {
+! timeout_time.tv_nsec -= 1000000000;
+! timeout_time.tv_sec++;
+! }
+! }
+!
+! FD_ZERO(&read_locks);
+! FD_ZERO(&write_locks);
+! FD_ZERO(&rdwr_locks);
+! FD_ZERO(&real_readfds);
+! FD_ZERO(&real_writefds);
+! FD_ZERO(&real_exceptfds);
+!
+! /* lock readfds */
+! if (readfds || writefds || exceptfds) {
+! for (i = 0; i < numfds; i++) {
+! if ((readfds && (FD_ISSET(i, readfds))) ||
+! (exceptfds && FD_ISSET(i, exceptfds))) {
+! if (writefds && FD_ISSET(i ,writefds)) {
+! if ((ret = fd_lock(i, FD_RDWR, NULL)) != OK) {
+! got_all_locks = 0;
+! break;
+! }
+! FD_SET(i, &rdwr_locks);
+! FD_SET(fd_table[i]->fd.i,&real_writefds);
+! } else {
+! if ((ret = fd_lock(i, FD_READ, NULL)) != OK) {
+! got_all_locks = 0;
+! break;
+! }
+! FD_SET(i, &read_locks);
+! }
+! if (readfds && FD_ISSET(i,readfds)) {
+! FD_SET(fd_table[i]->fd.i, &real_readfds);
+! }
+! if (exceptfds && FD_ISSET(i,exceptfds)) {
+! FD_SET(fd_table[i]->fd.i, &real_exceptfds);
+! }
+! if (fd_table[i]->fd.i >= data.nfds) {
+! data.nfds = fd_table[i]->fd.i + 1;
+! }
+! } else {
+! if (writefds && FD_ISSET(i, writefds)) {
+! if ((ret = fd_lock(i, FD_WRITE, NULL)) != OK) {
+! got_all_locks = 0;
+! break;
+! }
+! FD_SET(i, &write_locks);
+! FD_SET(fd_table[i]->fd.i,&real_writefds);
+! }
+! if (fd_table[i]->fd.i >= data.nfds) {
+! data.nfds = fd_table[i]->fd.i + 1;
+! }
+! }
+! }
+! }
+!
+! if (got_all_locks) {
+!
+! memcpy(&data.readfds,&real_readfds,sizeof(fd_set));
+! memcpy(&data.writefds,&real_writefds,sizeof(fd_set));
+! memcpy(&data.exceptfds,&real_exceptfds,sizeof(fd_set));
+!
+! real_readfds_p = (readfds == NULL) ? NULL : &real_readfds;
+! real_writefds_p = (writefds == NULL) ? NULL : &real_writefds;
+! real_exceptfds_p = (exceptfds == NULL) ? NULL : &real_exceptfds;
+!
+! if ((ret = machdep_sys_select(data.nfds, real_readfds_p,
+! real_writefds_p, real_exceptfds_p, &zero_timeout)) == OK) {
+!
+! pthread_sched_prevent();
+!
+! real_exceptfds_p = (exceptfds == NULL) ? NULL : &data.exceptfds;
+! real_writefds_p = (writefds == NULL) ? NULL : &data.writefds;
+! real_readfds_p = (readfds == NULL) ? NULL : &data.readfds;
+!
+! pthread_queue_enq(&fd_wait_select, pthread_run);
+! pthread_run->data.select_data = &data;
+! SET_PF_WAIT_EVENT(pthread_run);
+!
+! if (timeout) {
+! machdep_gettimeofday(&current_time);
+! sleep_schedule(&current_time, &timeout_time);
+!
+! pthread_resched_resume(PS_SELECT_WAIT);
+!
+! /* We're awake */
+! CLEAR_PF_DONE_EVENT(pthread_run);
+! if (sleep_cancel(pthread_run) == NOTOK) {
+! ret = OK;
+! } else {
+! ret = data.nfds;
+! }
+! } else {
+! pthread_resched_resume(PS_SELECT_WAIT);
+! CLEAR_PF_DONE_EVENT(pthread_run);
+! ret = data.nfds; /* XXX ??? snl */
+! }
+! } else if (ret < 0) {
+! SET_ERRNO(-ret);
+! ret = NOTOK;
+! }
+! }
+!
+! /* clean up the locks */
+! for (i = 0; i < numfds; i++)
+! if (FD_ISSET(i,&read_locks)) fd_unlock(i,FD_READ);
+! for (i = 0; i < numfds; i++)
+! if (FD_ISSET(i,&rdwr_locks)) fd_unlock(i,FD_RDWR);
+! for (i = 0; i < numfds; i++)
+! if (FD_ISSET(i,&write_locks)) fd_unlock(i,FD_WRITE);
+!
+! if (ret > 0) {
+! if (readfds != NULL) {
+! for (i = 0; i < numfds; i++) {
+! if (! (FD_ISSET(i,readfds) &&
+! FD_ISSET(fd_table[i]->fd.i,real_readfds_p)))
+! FD_CLR(i,readfds);
+! }
+! }
+! if (writefds != NULL) {
+! for (i = 0; i < numfds; i++)
+! if (! (FD_ISSET(i,writefds) &&
+! FD_ISSET(fd_table[i]->fd.i,real_writefds_p)))
+! FD_CLR(i,writefds);
+! }
+! if (exceptfds != NULL) {
+! for (i = 0; i < numfds; i++)
+! if (! (FD_ISSET(i,exceptfds) &&
+! FD_ISSET(fd_table[i]->fd.i,real_exceptfds_p)))
+! FD_CLR(i,exceptfds);
+! }
+! } else {
+! if (exceptfds != NULL) FD_ZERO(exceptfds);
+! if (writefds != NULL) FD_ZERO(writefds);
+! if (readfds != NULL) FD_ZERO(readfds);
+ }
+
+! return(ret);
+ }
+--- 56,223 ----
+ int select(int numfds, fd_set *readfds, fd_set *writefds,
+ fd_set *exceptfds, struct timeval *timeout)
+ {
+! fd_set real_exceptfds, real_readfds, real_writefds; /* mapped fd_sets */
+! fd_set * real_readfds_p, * real_writefds_p, * real_exceptfds_p;
+! fd_set read_locks, write_locks, rdwr_locks;
+! struct timespec timeout_time, current_time;
+! struct timeval zero_timeout = { 0, 0 };
+! int i, j, ret = 0, got_all_locks = 1;
+! struct pthread_select_data data;
+!
+! if (numfds > dtablesize) {
+! numfds = dtablesize;
+! }
+!
+! data.nfds = 0;
+! FD_ZERO(&data.readfds);
+! FD_ZERO(&data.writefds);
+! FD_ZERO(&data.exceptfds);
+!
+! /* Do this first */
+! if (timeout) {
+! machdep_gettimeofday(&current_time);
+! timeout_time.tv_sec = current_time.tv_sec + timeout->tv_sec;
+! if ((timeout_time.tv_nsec = current_time.tv_nsec +
+! (timeout->tv_usec * 1000)) > 1000000000) {
+! timeout_time.tv_nsec -= 1000000000;
+! timeout_time.tv_sec++;
+! }
+! }
+!
+! FD_ZERO(&read_locks);
+! FD_ZERO(&write_locks);
+! FD_ZERO(&rdwr_locks);
+! FD_ZERO(&real_readfds);
+! FD_ZERO(&real_writefds);
+! FD_ZERO(&real_exceptfds);
+!
+! /* lock readfds */
+! if (readfds || writefds || exceptfds) {
+! for (i = 0; i < numfds; i++) {
+! if ((readfds && (FD_ISSET(i, readfds))) ||
+! (exceptfds && FD_ISSET(i, exceptfds))) {
+! if (writefds && FD_ISSET(i ,writefds)) {
+! if ((ret = fd_lock(i, FD_RDWR, NULL)) != OK) {
+! got_all_locks = 0;
+! break;
+! }
+! FD_SET(i, &rdwr_locks);
+! FD_SET(fd_table[i]->fd.i,&real_writefds);
+! } else {
+! if ((ret = fd_lock(i, FD_READ, NULL)) != OK) {
+! got_all_locks = 0;
+! break;
+! }
+! FD_SET(i, &read_locks);
+! }
+! if (readfds && FD_ISSET(i,readfds)) {
+! FD_SET(fd_table[i]->fd.i, &real_readfds);
+! }
+! if (exceptfds && FD_ISSET(i,exceptfds)) {
+! FD_SET(fd_table[i]->fd.i, &real_exceptfds);
+! }
+! if (fd_table[i]->fd.i >= data.nfds) {
+! data.nfds = fd_table[i]->fd.i + 1;
+! }
+! } else {
+! if (writefds && FD_ISSET(i, writefds)) {
+! if ((ret = fd_lock(i, FD_WRITE, NULL)) != OK) {
+! got_all_locks = 0;
+! break;
+! }
+! FD_SET(i, &write_locks);
+! FD_SET(fd_table[i]->fd.i,&real_writefds);
+! if (fd_table[i]->fd.i >= data.nfds) {
+! data.nfds = fd_table[i]->fd.i + 1;
+! }
+! }
+! }
+! }
+! }
+!
+! if (got_all_locks) {
+! memcpy(&data.readfds,&real_readfds,sizeof(fd_set));
+! memcpy(&data.writefds,&real_writefds,sizeof(fd_set));
+! memcpy(&data.exceptfds,&real_exceptfds,sizeof(fd_set));
+!
+! real_readfds_p = (readfds == NULL) ? NULL : &real_readfds;
+! real_writefds_p = (writefds == NULL) ? NULL : &real_writefds;
+! real_exceptfds_p = (exceptfds == NULL) ? NULL : &real_exceptfds;
+!
+! if ((ret = machdep_sys_select(data.nfds, real_readfds_p,
+! real_writefds_p, real_exceptfds_p,
+! &zero_timeout)) == OK) {
+! pthread_sched_prevent();
+!
+! real_exceptfds_p = (exceptfds == NULL) ? NULL : &data.exceptfds;
+! real_writefds_p = (writefds == NULL) ? NULL : &data.writefds;
+! real_readfds_p = (readfds == NULL) ? NULL : &data.readfds;
+!
+! pthread_queue_enq(&fd_wait_select, pthread_run);
+! pthread_run->data.select_data = &data;
+! SET_PF_WAIT_EVENT(pthread_run);
+
+! if (timeout) {
+ machdep_gettimeofday(&current_time);
+! sleep_schedule(&current_time, &timeout_time);
+!
+! SET_PF_AT_CANCEL_POINT(pthread_run);
+! pthread_resched_resume(PS_SELECT_WAIT);
+! CLEAR_PF_AT_CANCEL_POINT(pthread_run);
+!
+! /* We're awake */
+! CLEAR_PF_DONE_EVENT(pthread_run);
+! if (sleep_cancel(pthread_run) == NOTOK) {
+! ret = OK;
+! } else {
+! ret = data.nfds;
+! }
+! } else {
+! SET_PF_AT_CANCEL_POINT(pthread_run);
+! pthread_resched_resume(PS_SELECT_WAIT);
+! CLEAR_PF_AT_CANCEL_POINT(pthread_run);
+! CLEAR_PF_DONE_EVENT(pthread_run);
+! ret = data.nfds; /* XXX ??? snl */
+! }
+! } else if (ret < 0) {
+! SET_ERRNO(-ret);
+! ret = NOTOK;
+! }
+! }
+!
+! /* clean up the locks */
+! for (i = 0; i < numfds; i++)
+! if (FD_ISSET(i,&read_locks)) fd_unlock(i,FD_READ);
+! for (i = 0; i < numfds; i++)
+! if (FD_ISSET(i,&rdwr_locks)) fd_unlock(i,FD_RDWR);
+! for (i = 0; i < numfds; i++)
+! if (FD_ISSET(i,&write_locks)) fd_unlock(i,FD_WRITE);
+!
+! if (ret > 0) {
+! if (readfds != NULL) {
+! for (i = 0; i < numfds; i++) {
+! if (! (FD_ISSET(i,readfds) &&
+! FD_ISSET(fd_table[i]->fd.i,real_readfds_p)))
+! FD_CLR(i,readfds);
+! }
+! }
+! if (writefds != NULL) {
+! for (i = 0; i < numfds; i++)
+! if (! (FD_ISSET(i,writefds) &&
+! FD_ISSET(fd_table[i]->fd.i,real_writefds_p)))
+! FD_CLR(i,writefds);
+! }
+! if (exceptfds != NULL) {
+! for (i = 0; i < numfds; i++)
+! if (! (FD_ISSET(i,exceptfds) &&
+! FD_ISSET(fd_table[i]->fd.i,real_exceptfds_p)))
+! FD_CLR(i,exceptfds);
+ }
++ } else {
++ if (exceptfds != NULL) FD_ZERO(exceptfds);
++ if (writefds != NULL) FD_ZERO(writefds);
++ if (readfds != NULL) FD_ZERO(readfds);
++ }
+
+! return(ret);
+ }
+=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/sig.c,v retrieving revision 1.1.1.1
+diff -c -r1.1.1.1 sig.c
+*** sig.c 1996/03/13 04:33:13 1.1.1.1
+--- sig.c 1996/10/03 01:07:54
+***************
+*** 301,307 ****
+--- 301,310 ----
+ pthread_run->data.sigwait = set;
+ pthread_run->ret = sig;
+
++ SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
+ pthread_resched_resume(PS_SIGWAIT);
++ CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
++
+ return(OK);
+ }
+
+=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/signal.c,v retrieving revision 1.1.1.1
+diff -c -r1.1.1.1 signal.c
+*** signal.c 1996/03/13 04:33:17 1.1.1.1
+--- signal.c 1996/10/03 17:30:16
+***************
+*** 72,77 ****
+--- 72,78 ----
+
+ static void sig_handler(int signal);
+ static void set_thread_timer();
++ static void __cleanup_after_resume( void );
+ void sig_prevent(void);
+ void sig_resume(void);
+
+***************
+*** 482,502 ****
+ }
+ }
+
+! /* Only bother if we are truly unlocking the kernel */
+! while (!(--pthread_kernel_lock)) {
+! if (sig_to_process) {
+! /* if (SIG_ANY(sig_to_process)) { */
+! pthread_kernel_lock++;
+! sig_handler(0);
+! continue;
+! }
+! if (pthread_run && pthread_run->sigcount) {
+! pthread_kernel_lock++;
+! pthread_sig_process();
+! continue;
+! }
+! break;
+! }
+ }
+
+ /* ==========================================================================
+--- 483,489 ----
+ }
+ }
+
+! __cleanup_after_resume();
+ }
+
+ /* ==========================================================================
+***************
+*** 508,530 ****
+ void pthread_resched_resume(enum pthread_state state)
+ {
+ pthread_run->state = state;
+- sig_handler(SIGVTALRM);
+
+! /* Only bother if we are truely unlocking the kernel */
+! while (!(--pthread_kernel_lock)) {
+! if (sig_to_process) {
+! /* if (SIG_ANY(sig_to_process)) { */
+! pthread_kernel_lock++;
+! sig_handler(0);
+! continue;
+! }
+! if (pthread_run && pthread_run->sigcount) {
+! pthread_kernel_lock++;
+! pthread_sig_process();
+! continue;
+! }
+! break;
+ }
+ }
+
+ /* ==========================================================================
+--- 495,523 ----
+ void pthread_resched_resume(enum pthread_state state)
+ {
+ pthread_run->state = state;
+
+! /* Since we are about to block this thread, lets see if we are
+! * at a cancel point and if we've been cancelled.
+! * Avoid cancelling dead or unalloced threads.
+! */
+! if( ! TEST_PF_RUNNING_TO_CANCEL(pthread_run) &&
+! TEST_PTHREAD_IS_CANCELLABLE(pthread_run) &&
+! state != PS_DEAD && state != PS_UNALLOCED ) {
+!
+! /* Set this flag to avoid recursively calling pthread_exit */
+! /* We have to set this flag here because we will unlock the
+! * kernel prior to calling pthread_cancel_internal.
+! */
+! SET_PF_RUNNING_TO_CANCEL(pthread_run);
+!
+! pthread_run->old_state = state; /* unlock needs this data */
+! pthread_sched_resume(); /* Unlock kernel before cancel */
+! pthread_cancel_internal( 1 ); /* free locks and exit */
+ }
++
++ sig_handler(SIGVTALRM);
++
++ __cleanup_after_resume();
+ }
+
+ /* ==========================================================================
+***************
+*** 532,537 ****
+--- 525,543 ----
+ */
+ void pthread_sched_resume()
+ {
++ __cleanup_after_resume();
++ }
++
++ /*----------------------------------------------------------------------
++ * Function: __cleanup_after_resume
++ * Purpose: cleanup kernel locks after a resume
++ * Args: void
++ * Returns: void
++ * Notes:
++ *----------------------------------------------------------------------*/
++ static void
++ __cleanup_after_resume( void )
++ {
+ /* Only bother if we are truely unlocking the kernel */
+ while (!(--pthread_kernel_lock)) {
+ /* if (SIG_ANY(sig_to_process)) { */
+***************
+*** 546,551 ****
+--- 552,568 ----
+ continue;
+ }
+ break;
++ }
++
++ if( pthread_run == NULL )
++ return; /* Must be during init processing */
++
++ /* Test for cancel that should be handled now */
++
++ if( ! TEST_PF_RUNNING_TO_CANCEL(pthread_run) &&
++ TEST_PTHREAD_IS_CANCELLABLE(pthread_run) ) {
++ /* Kernel is already unlocked */
++ pthread_cancel_internal( 1 ); /* free locks and exit */
+ }
+ }
+
+=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/sleep.c,v retrieving revision 1.1.1.1
+diff -c -r1.1.1.1 sleep.c
+*** sleep.c 1996/03/11 08:33:32 1.1.1.1
+--- sleep.c 1996/10/03 01:14:58
+***************
+*** 249,255 ****
+--- 249,257 ----
+
+ /* Reschedule thread */
+ SET_PF_WAIT_EVENT(pthread_run);
++ SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
+ pthread_resched_resume(PS_SLEEP_WAIT);
++ CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
+ CLEAR_PF_DONE_EVENT(pthread_run);
+
+ /* Return actual time slept */
+***************
+*** 332,338 ****
+ current_time.tv_sec++;
+ }
+ machdep_start_timer(&(current_time),
+! &(pthread_sleep->wakeup_time));
+ }
+ } else {
+ for (pthread_last = pthread_sleep; pthread_last;
+--- 334,340 ----
+ current_time.tv_sec++;
+ }
+ machdep_start_timer(&(current_time),
+! &(pthread_sleep->wakeup_time));
+ }
+ } else {
+ for (pthread_last = pthread_sleep; pthread_last;
+=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/stat.c,v retrieving revision 1.1.1.1
+diff -c -r1.1.1.1 stat.c
+*** stat.c 1995/09/21 02:36:05 1.1.1.1
+--- stat.c 1996/06/04 19:17:33
+***************
+*** 43,48 ****
+--- 43,49 ----
+ #include <errno.h>
+
+ struct stat;
++ struct statfs;
+
+ /* ==========================================================================
+ * fstat()
+***************
+*** 91,95 ****
+--- 92,115 ----
+ }
+ return(ret);
+
++ }
++
++ /* ==========================================================================
++ * fstatfs()
++ *
++ * Might want to indirect this.
++ */
++ int fstatfs(int fd, struct statfs *buf)
++ {
++ int ret;
++
++ if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
++ if ((ret = machdep_sys_fstatfs(fd_table[fd]->fd.i, buf)) < OK) {
++ SET_ERRNO(-ret);
++ ret = NOTOK;
++ }
++ fd_unlock(fd, FD_READ);
++ }
++ return(ret);
+ }
+
+=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/wait.c,v retrieving revision 1.1.1.1
+diff -c -r1.1.1.1 wait.c
+*** wait.c 1995/02/21 08:07:24 1.1.1.1
+--- wait.c 1996/10/03 01:20:02
+***************
+*** 103,109 ****
+--- 103,111 ----
+ pthread_queue_enq(&wait_queue, pthread_run);
+
+ /* reschedule unlocks scheduler */
++ SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
+ pthread_resched_resume(PS_WAIT_WAIT);
++ CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
+
+ pthread_sched_prevent();
+ }
+***************
+*** 126,132 ****
+--- 128,136 ----
+ pthread_queue_enq(&wait_queue, pthread_run);
+
+ /* reschedule unlocks scheduler */
++ SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
+ pthread_resched_resume(PS_WAIT_WAIT);
++ CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
+
+ pthread_sched_prevent();
+ }
+<pre><font size=-1>