mevans
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:19k
- =A0
- Attached are several patches for pthreads-1_60_beta6. The patches fall
- into 3 catagories:
- 1. Crashes and hangs.
- 2. Missing functionality (namely flock())
- 3. Use of POSIX reentrant safe routines.
- Most of the patches contain a comment as to why the change was made.
- The one major exception is to fd_kern.c at line 257 (unpatched). The
- change to that line is to fix a "hang" that prevents threads for
- scheduling for an hour if there is no external I/O event.
- I also include patches that modify several functions to use POSIX
- reentrant safe routines. I know that MIT pthreads implements routine
- like gethostbyname in a thread safe manner, but we're pretty, um, anal
- about trying to keep our code as portable as possible. By excluding
- using routines that are not reentrant safe according to the PTHREAD
- safe, it's easy for us to stub out the unsafe routines and catch
- non-compliant code. I almost left these patches out, but I'm hoping
- they'll be adopted. :-)
- WARNING: None of the MIT pthreads routines that convert floats/doubles
- between their native forms and strings are thread safe! (i.e printf,
- sprintf, fprintf, atod, strtod, etc) I have replacements, but I need to
- check with the author of the replacements and my employer.
- Mark Evans
- ------------69CDAAF52A3566916F8ED01A0
- Content-Disposition: inline; filename="pthreads-1_60_beta6.patch"
- Content-Type: text/plain; charset=us-ascii; name="pthreads-1_60_beta6.patch"
- Content-Transfer-Encoding: 7bit
- diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/config/config.h.in pthreads-1_60_beta6+/config/config.h.in
- *** pthreads-1_60_beta6/config/config.h.in Thu Mar 21 21:30:04 1996
- --- pthreads-1_60_beta6+/config/config.h.in Sat Mar 15 14:08:55 1997
- ***************
- *** 137,142 ****
- --- 137,145 ----
- /* Define if you have the syscall_ftruncate function. */
- #undef HAVE_SYSCALL_FTRUNCATE
-
- + /* Define if you have the syscall_flock function. */
- + #undef HAVE_SYSCALL_FLOCK
- +
- /* Define if you have the syscall_getdents function. */
- #undef HAVE_SYSCALL_GETDENTS
-
- diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/config/configure.in pthreads-1_60_beta6+/config/configure.in
- *** pthreads-1_60_beta6/config/configure.in Wed Nov 13 14:03:08 1996
- --- pthreads-1_60_beta6+/config/configure.in Sat Mar 15 14:08:55 1997
- ***************
- *** 241,247 ****
-
- PTHREADS_CHECK_SYSCALLS(open write read creat close fcntl lseek dup2 dup pipe
- fchmod fchown execve fstat lstat link unlink chdir chown chmod stat
- ! rename select getdtablesize ioctl ftruncate
- dnl - signals
- sigsuspend sigaction sigpause sigprocmask ksigaction
- dnl - directory reading
- --- 241,247 ----
-
- PTHREADS_CHECK_SYSCALLS(open write read creat close fcntl lseek dup2 dup pipe
- fchmod fchown execve fstat lstat link unlink chdir chown chmod stat
- ! rename select getdtablesize ioctl ftruncate flock
- dnl - signals
- sigsuspend sigaction sigpause sigprocmask ksigaction
- dnl - directory reading
- diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/gen/directory.c pthreads-1_60_beta6+/gen/directory.c
- *** pthreads-1_60_beta6/gen/directory.c Sat May 20 10:55:34 1995
- --- pthreads-1_60_beta6+/gen/directory.c Sat Mar 15 14:08:55 1997
- ***************
- *** 251,262 ****
- --- 251,266 ----
- /*
- * Seek to an entry in a directory.
- * _seekdir is in telldir.c so that it can share opaque data structures.
- + *
- + * Use the POSIX reentrant safe readdir_r to simplify varifying POSIX
- + * thread-safe compliance.
- */
- void seekdir(DIR * dirp, long loc)
- {
- register struct ddloc ** prevlp;
- register struct ddloc * lp;
- struct dirent * dp;
- + struct dirent de;
-
- pthread_mutex_lock (dirp->dd_lock);
- prevlp = (struct ddloc **)&(dirp->dd_ddloc);
- ***************
- *** 277,283 ****
- dirp->dd_seek = lp->loc_seek;
- dirp->dd_loc = 0;
- while (dirp->dd_loc < lp->loc_loc) {
- ! if (!(dp = readdir(dirp))) {
- *prevlp = lp->loc_next;
- break;
- }
- --- 281,287 ----
- dirp->dd_seek = lp->loc_seek;
- dirp->dd_loc = 0;
- while (dirp->dd_loc < lp->loc_loc) {
- ! if (readdir_r(dirp, &de, &dp)) {
- *prevlp = lp->loc_next;
- break;
- }
- diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/gen/getcwd.c pthreads-1_60_beta6+/gen/getcwd.c
- *** pthreads-1_60_beta6/gen/getcwd.c Sat Sep 2 17:39:30 1995
- --- pthreads-1_60_beta6+/gen/getcwd.c Sat Mar 15 14:08:55 1997
- ***************
- *** 50,67 ****
- (dp->d_name[0] == '.' && (dp->d_name[1] == ' ' ||
- dp->d_name[1] == '.' && dp->d_name[2] == ' '))
-
- char *
- getcwd(pt, size)
- char *pt;
- size_t size;
- {
- - register struct dirent *dp;
- register DIR *dir;
- register dev_t dev;
- register ino_t ino;
- register int first;
- register char *bpt, *bup;
- struct stat s;
- dev_t root_dev;
- ino_t root_ino;
- size_t ptsize, upsize;
- --- 50,71 ----
- (dp->d_name[0] == '.' && (dp->d_name[1] == ' ' ||
- dp->d_name[1] == '.' && dp->d_name[2] == ' '))
-
- + /* Only use reentrant safe routines to simplify varifying POSIX thread-safe
- + * compliance. (mevans).
- + */
- char *
- getcwd(pt, size)
- char *pt;
- size_t size;
- {
- register DIR *dir;
- register dev_t dev;
- register ino_t ino;
- register int first;
- register char *bpt, *bup;
- struct stat s;
- + struct dirent *dp;
- + struct dirent de;
- dev_t root_dev;
- ino_t root_ino;
- size_t ptsize, upsize;
- ***************
- *** 166,179 ****
- save_errno = 0;
- if (s.st_dev == dev) {
- for (;;) {
- ! if (!(dp = readdir(dir)))
- goto notfound;
- if (dp->d_fileno == ino)
- break;
- }
- } else
- for (;;) {
- ! if (!(dp = readdir(dir)))
- goto notfound;
- if (ISDOT(dp))
- continue;
- --- 170,183 ----
- save_errno = 0;
- if (s.st_dev == dev) {
- for (;;) {
- ! if (readdir_r(dir, &de, &dp))
- goto notfound;
- if (dp->d_fileno == ino)
- break;
- }
- } else
- for (;;) {
- ! if (readdir_r(dir, &de, &dp))
- goto notfound;
- if (ISDOT(dp))
- continue;
- diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/include/syslog.h pthreads-1_60_beta6+/include/syslog.h
- *** pthreads-1_60_beta6/include/syslog.h Mon Sep 26 21:26:29 1994
- --- pthreads-1_60_beta6+/include/syslog.h Sat Mar 15 14:08:56 1997
- ***************
- *** 9,14 ****
- --- 9,16 ----
- #ifndef SYSLOG_H
- #define SYSLOG_H
-
- + /* Added __[BEGIN/END]_DECLS so this file would work with C++. (mevans) */
- + #include <sys/cdefs.h>
- #include <stdarg.h>
-
- /* Discipline: openlog(), closelog(), and setlogmask() are not thread-safe
- ***************
- *** 84,95 ****
- --- 86,101 ----
- #define LOG_NDELAY 0x08 /* don't delay open */
- #define LOG_NOWAIT 0x10 /* if forking to log on console, don't wait() */
-
- + __BEGIN_DECLS
- +
- /* Syslogging functions. */
- void syslog(int pri, char *fmt, ...);
- void vsyslog(int pri, char *fmt, va_list args);
- void openlog(char *ident, int logstat, int logfac);
- void closelog(void);
- int setlogmask(int pmask);
- +
- + __END_DECLS
-
- #endif
-
- diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/machdep/engine-i386-linux-1.0.c pthreads-1_60_beta6+/machdep/engine-i386-linux-1.0.c
- *** pthreads-1_60_beta6/machdep/engine-i386-linux-1.0.c Mon Oct 21 20:39:13 1996
- --- pthreads-1_60_beta6+/machdep/engine-i386-linux-1.0.c Sat Mar 15 14:08:56 1997
- ***************
- *** 142,147 ****
- --- 142,149 ----
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state->__pc = (char *)machdep_pthread_start;
- + machdep_pthread->machdep_state->__bp = (char *)0;/* So the backtrace
- + * is sensible (mevans) */
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state->__sp =
- diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/machdep/syscall-i386-linux-1.0.S pthreads-1_60_beta6+/machdep/syscall-i386-linux-1.0.S
- *** pthreads-1_60_beta6/machdep/syscall-i386-linux-1.0.S Mon Oct 21 22:17:32 1996
- --- pthreads-1_60_beta6+/machdep/syscall-i386-linux-1.0.S Sat Mar 15 14:08:56 1997
- ***************
- *** 148,156 ****
- /* =========================================================================
- * exit 1 select 82
- * fork 2 socketcall 102
- ! * read 3 readv 145
- ! * write 4 writev 146
- ! * open 5
- * creat 8
- * link 9
- * unlink 10
- --- 148,156 ----
- /* =========================================================================
- * exit 1 select 82
- * fork 2 socketcall 102
- ! * read 3 flock 143
- ! * write 4 readv 145
- ! * open 5 writev 146
- * creat 8
- * link 9
- * unlink 10
- ***************
- *** 390,394 ****
- --- 390,401 ----
- */
- #ifdef HAVE_SYSCALL_WRITEV
- SYSCALL3(writev)
- + #endif
- +
- + /* ==========================================================================
- + * machdep_sys_flock()
- + */
- + #ifdef HAVE_SYSCALL_FLOCK
- + SYSCALL2(flock)
- #endif
-
- diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/net/gethostbyname.c pthreads-1_60_beta6+/net/gethostbyname.c
- *** pthreads-1_60_beta6/net/gethostbyname.c Mon Apr 22 22:41:21 1996
- --- pthreads-1_60_beta6+/net/gethostbyname.c Sat Mar 15 14:08:58 1997
- ***************
- *** 146,161 ****
- {
- char **alias;
- FILE *fp = NULL;
-
- pthread_mutex_lock(&host_iterate_lock);
- sethostent(0);
- ! while ((result = gethostent_r(result, buf, bufsize, errval)) != NULL) {
- /* Check the entry's name and aliases against the given name. */
- if (strcasecmp(result->h_name, name) == 0)
- break;
- for (alias = result->h_aliases; *alias; alias++) {
- ! if (strcasecmp(*alias, name) == 0)
- break;
- }
- }
- pthread_mutex_unlock(&host_iterate_lock);
- --- 146,166 ----
- {
- char **alias;
- FILE *fp = NULL;
- + int fFound = FALSE;
-
- pthread_mutex_lock(&host_iterate_lock);
- sethostent(0);
- ! while (!fFound && (result = gethostent_r(result, buf, bufsize, errval))
- ! != NULL) {
- /* Check the entry's name and aliases against the given name. */
- if (strcasecmp(result->h_name, name) == 0)
- break;
- for (alias = result->h_aliases; *alias; alias++) {
- ! if (strcasecmp(*alias, name) == 0) {
- ! /* fFound will exit while loop. (mevans). */
- ! fFound = TRUE;
- break;
- + }
- }
- }
- pthread_mutex_unlock(&host_iterate_lock);
- diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/net/res_debug.c pthreads-1_60_beta6+/net/res_debug.c
- *** pthreads-1_60_beta6/net/res_debug.c Thu Feb 23 22:42:35 1995
- --- pthreads-1_60_beta6+/net/res_debug.c Sat Mar 15 14:08:58 1997
- ***************
- *** 375,380 ****
- --- 375,383 ----
-
- /*
- * Print resource record fields in human readable form.
- + *
- + * Removed calls to non-reentrant routines to simplify varifying
- + * POSIX thread-safe implementations. (mevans).
- */
- char *
- p_rr(cp, msg, file)
- ***************
- *** 386,391 ****
- --- 389,395 ----
- char *cp1, *cp2;
- u_long tmpttl, t;
- int lcnt;
- + char buf[32];
-
- if ((cp = p_fqname(cp, msg, file)) == NULL)
- return (NULL); /* compression error */
- ***************
- *** 413,426 ****
- case C_HS:
- bcopy(cp, (char *)&inaddr, sizeof(inaddr));
- if (dlen == 4) {
- ! fprintf(file,"t%s", inet_ntoa(inaddr));
- cp += dlen;
- } else if (dlen == 7) {
- char *address;
- u_char protocol;
- u_short port;
-
- ! address = inet_ntoa(inaddr);
- cp += sizeof(inaddr);
- protocol = *(u_char*)cp;
- cp += sizeof(u_char);
- --- 417,432 ----
- case C_HS:
- bcopy(cp, (char *)&inaddr, sizeof(inaddr));
- if (dlen == 4) {
- ! fprintf(file,"t%s",
- ! inet_ntoa_r(inaddr, buf, sizeof(buf)));
- cp += dlen;
- } else if (dlen == 7) {
- char *address;
- u_char protocol;
- u_short port;
-
- ! address = inet_ntoa_r(inaddr,
- ! buf, sizeof(buf));
- cp += sizeof(inaddr);
- protocol = *(u_char*)cp;
- cp += sizeof(u_char);
- ***************
- *** 524,530 ****
- bcopy(cp, (char *)&inaddr, sizeof(inaddr));
- cp += sizeof(u_long);
- fprintf(file, "t%s %s ( ",
- ! inet_ntoa(inaddr),
- deproto((int) *cp));
- cp += sizeof(u_char);
- n = 0;
- --- 530,536 ----
- bcopy(cp, (char *)&inaddr, sizeof(inaddr));
- cp += sizeof(u_long);
- fprintf(file, "t%s %s ( ",
- ! inet_ntoa_r(inaddr, buf, sizeof(buf)),
- deproto((int) *cp));
- cp += sizeof(u_char);
- n = 0;
- diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/pthreads/fd_kern.c pthreads-1_60_beta6+/pthreads/fd_kern.c
- *** pthreads-1_60_beta6/pthreads/fd_kern.c Tue Oct 1 12:26:48 1996
- --- pthreads-1_60_beta6+/pthreads/fd_kern.c Sat Mar 15 14:09:00 1997
- ***************
- *** 215,221 ****
- * Called when there is no active thread to run.
- */
- extern struct timeval __fd_kern_wait_timeout;
- !
- void fd_kern_wait()
- {
- fd_set fd_set_read, fd_set_write, fd_set_except;
- --- 215,221 ----
- * Called when there is no active thread to run.
- */
- extern struct timeval __fd_kern_wait_timeout;
- ! extern volatile sig_atomic_t sig_to_process;
- void fd_kern_wait()
- {
- fd_set fd_set_read, fd_set_write, fd_set_except;
- ***************
- *** 254,260 ****
-
- machdep_unset_thread_timer(NULL);
- __fd_kern_wait_timeout.tv_usec = 0;
- ! __fd_kern_wait_timeout.tv_sec = 3600;
-
- machdep_sys_sigprocmask(SIG_UNBLOCK, &sig_to_block, &oset);
-
- --- 254,260 ----
-
- machdep_unset_thread_timer(NULL);
- __fd_kern_wait_timeout.tv_usec = 0;
- ! __fd_kern_wait_timeout.tv_sec = (sig_to_process) ? 0 : 3600;
-
- machdep_sys_sigprocmask(SIG_UNBLOCK, &sig_to_block, &oset);
-
- ***************
- *** 726,731 ****
- --- 726,753 ----
- return(ret);
- }
-
- + #if defined (HAVE_SYSCALL_FLOCK)
- + /* ==========================================================================
- + * flock()
- + *
- + * Added (mevans)
- + */
- + int flock(int fd, int operation)
- + {
- + int ret;
- +
- + if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- + if ((ret = machdep_sys_flock(fd_table[fd]->fd.i,
- + operation)) < OK) {
- + SET_ERRNO(-ret);
- + ret = NOTOK;
- + }
- + fd_unlock(fd, FD_RDWR);
- + }
- + return(ret);
- + }
- + #endif
- +
- /* ==========================================================================
- * pipe()
- */
- ***************
- *** 1126,1132 ****
- /* 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 {
- --- 1148,1155 ----
- /* Get the error, this function should not fail */
- machdep_sys_getsockopt(fd_table[fd]->fd.i, SOL_SOCKET,
- SO_ERROR, &ret, &tmpnamelen);
- ! /* ret is already positive (mevans) */
- ! SET_ERRNO(ret);
- ret = NOTOK;
- }
- } else {
- diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/pthreads/malloc.c pthreads-1_60_beta6+/pthreads/malloc.c
- *** pthreads-1_60_beta6/pthreads/malloc.c Thu Mar 9 21:06:43 1995
- --- pthreads-1_60_beta6+/pthreads/malloc.c Sat Mar 15 14:09:00 1997
- ***************
- *** 196,204 ****
- else
- n = n - x;
- if (n) {
- ! if (sbrk(n) == (char *)-1)
- return (NULL);
- }
- bucket = 0;
- amt = 8;
- while (pagesz > amt) {
- --- 196,207 ----
- else
- n = n - x;
- if (n) {
- ! if (sbrk(n) == (char *)-1) {
- ! /* Unlock before returning (mevans) */
- ! pthread_mutex_unlock(mutex);
- return (NULL);
- }
- + }
- bucket = 0;
- amt = 8;
- while (pagesz > amt) {
- ***************
- *** 363,366 ****
- --- 366,382 ----
- free(cp);
-
- return (res);
- + }
- + /* ==========================================================================
- + * calloc()
- + *
- + * Added to ensure pthread's allocation is used (mevans).
- + */
- + void *calloc(size_t nmemb, size_t size)
- + {
- + void *p;
- + size *= nmemb;
- + p = malloc(size);
- + if (p) memset(p, 0, size);
- + return (p);
- }
- diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/pthreads/select.c pthreads-1_60_beta6+/pthreads/select.c
- *** pthreads-1_60_beta6/pthreads/select.c Sat Jul 6 21:58:55 1996
- --- pthreads-1_60_beta6+/pthreads/select.c Sat Mar 15 14:09:00 1997
- ***************
- *** 165,176 ****
- 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);
- --- 165,180 ----
- pthread_resched_resume(PS_SELECT_WAIT);
-
- /* We're awake */
- if (sleep_cancel(pthread_run) == NOTOK) {
- ret = OK;
- } else {
- ret = data.nfds;
- }
- + /* Moving this after the sleep_cancel() seemed
- + * to fix intermittent crashes during heavy
- + * socket use. (mevans)
- + */
- + CLEAR_PF_DONE_EVENT(pthread_run);
- } else {
- pthread_resched_resume(PS_SELECT_WAIT);
- CLEAR_PF_DONE_EVENT(pthread_run);
- diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/pthreads/signal.c pthreads-1_60_beta6+/pthreads/signal.c
- *** pthreads-1_60_beta6/pthreads/signal.c Tue Mar 12 21:33:17 1996
- --- pthreads-1_60_beta6+/pthreads/signal.c Sat Mar 15 14:09:00 1997
- ***************
- *** 65,71 ****
- */
-
- static sig_atomic_t signum_to_process[SIGMAX + 1] = { 0, };
- ! static sig_atomic_t sig_to_process = 0;
-
- /* static volatile sigset_t sig_to_process; */
- static volatile int sig_count = 0;
- --- 65,71 ----
- */
-
- static sig_atomic_t signum_to_process[SIGMAX + 1] = { 0, };
- ! volatile sig_atomic_t sig_to_process = 0;
-
- /* static volatile sigset_t sig_to_process; */
- static volatile int sig_count = 0;
- ***************
- *** 303,309 ****
- break;
- case NOTOK:
- /* Do the registered action, no threads were sleeping */
- ! sigdefault(sig);
- break;
- }
- break;
- --- 303,317 ----
- break;
- case NOTOK:
- /* Do the registered action, no threads were sleeping */
- ! /* There is a timing window that gets
- ! * here when no threads are on the
- ! * sleep queue. This is a quick fix.
- ! * The real problem is possibly related
- ! * to heavy use of condition variables
- ! * with time outs.
- ! * (mevans)
- ! *sigdefault(sig);
- ! */
- break;
- }
- break;
- diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/stdio/setvbuf.c pthreads-1_60_beta6+/stdio/setvbuf.c
- *** pthreads-1_60_beta6/stdio/setvbuf.c Sat Sep 3 20:58:36 1994
- --- pthreads-1_60_beta6+/stdio/setvbuf.c Sat Mar 15 14:09:00 1997
- ***************
- *** 142,148 ****
- flags |= __SLBF;
- if (flags & __SRW)
- flags &= ~(__SRD | __SWR);
- ! fp->_w = 0;
- fp->_flags = flags;
- fp->_bf._base = fp->_p = (unsigned char *)buf;
- fp->_bf._size = size;
- --- 142,148 ----
- flags |= __SLBF;
- if (flags & __SRW)
- flags &= ~(__SRD | __SWR);
- ! fp->_w = size; /* Was 0 (mevans) */
- fp->_flags = flags;
- fp->_bf._base = fp->_p = (unsigned char *)buf;
- fp->_bf._size = size;
- diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/stdlib/system.c pthreads-1_60_beta6+/stdlib/system.c
- *** pthreads-1_60_beta6/stdlib/system.c Wed Apr 24 21:18:56 1996
- --- pthreads-1_60_beta6+/stdlib/system.c Sat Mar 15 14:09:01 1997
- ***************
- *** 62,68 ****
- argp[2] = (char *) command;
- sigemptyset(&tmp_mask);
- sigaddset(&tmp_mask, SIGCHLD);
- ! pthread_sigmask(SIG_BLOCK, tmp_mask, &old_mask);
- switch(pid = fork()) {
- case -1: /* error */
- (void)pthread_sigmask(SIG_SETMASK, &old_mask, NULL);
- --- 62,69 ----
- argp[2] = (char *) command;
- sigemptyset(&tmp_mask);
- sigaddset(&tmp_mask, SIGCHLD);
- ! /* Pass the address of tmp_mask to avoid a sigfault. (mevans). */
- ! pthread_sigmask(SIG_BLOCK, &tmp_mask, &old_mask);
- switch(pid = fork()) {
- case -1: /* error */
- (void)pthread_sigmask(SIG_SETMASK, &old_mask, NULL);