diff options
Diffstat (limited to 'mit-pthreads/patches/Streepy.html')
-rwxr-xr-x | mit-pthreads/patches/Streepy.html | 2873 |
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(¤t_time); + sleep_schedule(¤t_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(¤t_time); + sleep_schedule(¤t_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(¤t_time); + sleep_schedule(¤t_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(¤t_time); + sleep_schedule(¤t_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(¤t_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(¤t_time); +! sleep_schedule(¤t_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(¤t_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(¤t_time); +! sleep_schedule(¤t_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> |