mirror of
https://github.com/MariaDB/server.git
synced 2025-02-02 20:11:42 +01:00
2873 lines
80 KiB
HTML
Executable file
2873 lines
80 KiB
HTML
Executable file
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>
|