diff options
Diffstat (limited to 'pr/src/pthreads')
-rw-r--r-- | pr/src/pthreads/Makefile.in | 5 | ||||
-rw-r--r-- | pr/src/pthreads/ptio.c | 413 | ||||
-rw-r--r-- | pr/src/pthreads/ptsynch.c | 9 | ||||
-rw-r--r-- | pr/src/pthreads/ptthread.c | 73 |
4 files changed, 405 insertions, 95 deletions
diff --git a/pr/src/pthreads/Makefile.in b/pr/src/pthreads/Makefile.in index a43fd6ac..8eb237d4 100644 --- a/pr/src/pthreads/Makefile.in +++ b/pr/src/pthreads/Makefile.in @@ -63,6 +63,11 @@ INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/incl DEFINES += -D_NSPR_BUILD_ +ifeq ($(OS_ARCH),Linux) +# for pthread_mutexattr_settype +DEFINES += -D_XOPEN_SOURCE=500 +endif + include $(topsrcdir)/config/rules.mk export:: $(TARGETS) diff --git a/pr/src/pthreads/ptio.c b/pr/src/pthreads/ptio.c index ce263217..8267148b 100644 --- a/pr/src/pthreads/ptio.c +++ b/pr/src/pthreads/ptio.c @@ -40,9 +40,11 @@ #if defined(_PR_PTHREADS) #if defined(_PR_POLL_WITH_SELECT) +#if !(defined(HPUX) && defined(_USE_BIG_FDS)) /* set fd limit for select(), before including system header files */ #define FD_SETSIZE (16 * 1024) #endif +#endif #include <pthread.h> #include <string.h> /* for memset() */ @@ -173,11 +175,18 @@ static ssize_t (*pt_aix_sendfile_fptr)() = NULL; #endif /* HAVE_SEND_FILE */ #endif /* AIX */ +#ifdef LINUX +#include <sys/sendfile.h> +#endif + #include "primpl.h" -/* On Alpha Linux, these are already defined in sys/socket.h */ -#if !(defined(LINUX) && defined(__alpha)) #include <netinet/tcp.h> /* TCP_NODELAY, TCP_MAXSEG */ +#ifdef LINUX +/* TCP_CORK is not defined in <netinet/tcp.h> on Red Hat Linux 6.0 */ +#ifndef TCP_CORK +#define TCP_CORK 3 +#endif #endif #if defined(SOLARIS) @@ -281,11 +290,9 @@ static PRBool IsValidNetAddrLen(const PRNetAddr *addr, PRInt32 addr_len) * most current systems. */ #if defined(HAVE_SOCKLEN_T) \ - || (defined(LINUX) && defined(__GLIBC__) && __GLIBC__ >= 2 \ - && !defined(__alpha)) + || (defined(LINUX) && defined(__GLIBC__) && __GLIBC__ >= 2) typedef socklen_t pt_SockLen; #elif (defined(AIX) && !defined(AIX4_1)) \ - || (defined(LINUX) && defined(__alpha)) \ || defined(VMS) typedef PRSize pt_SockLen; #else @@ -338,6 +345,15 @@ struct pt_Continuation */ int nbytes_to_send; /* size of header and file */ #endif /* SOLARIS */ + +#ifdef LINUX + /* + * For sendfile() + */ + int in_fd; /* descriptor of file to send */ + off_t offset; + size_t count; +#endif /* LINUX */ PRIntervalTime timeout; /* client (relative) timeout */ @@ -358,15 +374,13 @@ struct pt_Continuation PTDebug pt_debug; /* this is shared between several modules */ -PR_IMPLEMENT(void) PT_GetStats(PTDebug* here) { *here = pt_debug; } - PR_IMPLEMENT(void) PT_FPrintStats(PRFileDesc *debug_out, const char *msg) { PTDebug stats; char buffer[100]; PRExplodedTime tod; PRInt64 elapsed, aMil; - PT_GetStats(&stats); /* a copy */ + stats = pt_debug; /* a copy */ PR_ExplodeTime(stats.timeStarted, PR_LocalTimeParameters, &tod); (void)PR_FormatTime(buffer, sizeof(buffer), "%T", &tod); @@ -391,6 +405,13 @@ PR_IMPLEMENT(void) PT_FPrintStats(PRFileDesc *debug_out, const char *msg) stats.cvars_notified, stats.delayed_cv_deletes); } /* PT_FPrintStats */ +#else + +PR_IMPLEMENT(void) PT_FPrintStats(PRFileDesc *debug_out, const char *msg) +{ + /* do nothing */ +} /* PT_FPrintStats */ + #endif /* DEBUG */ #if defined(_PR_POLL_WITH_SELECT) @@ -406,6 +427,7 @@ static void pt_poll_now_with_select(pt_Continuation *op) fd_set rd, wr, *rdp, *wrp; struct timeval tv; PRIntervalTime epoch, now, elapsed, remaining; + PRBool wait_for_remaining; PRThread *self = PR_GetCurrentThread(); PR_ASSERT(PR_INTERVAL_NO_WAIT != op->timeout); @@ -485,9 +507,12 @@ static void pt_poll_now_with_select(pt_Continuation *op) } else wrp = NULL; + wait_for_remaining = PR_TRUE; msecs = (PRInt32)PR_IntervalToMilliseconds(remaining); - if (msecs > PT_DEFAULT_POLL_MSEC) + if (msecs > PT_DEFAULT_POLL_MSEC) { + wait_for_remaining = PR_FALSE; msecs = PT_DEFAULT_POLL_MSEC; + } tv.tv_sec = msecs/PR_MSEC_PER_SEC; tv.tv_usec = (msecs % PR_MSEC_PER_SEC) * PR_USEC_PER_MSEC; rv = select(op->arg1.osfd + 1, rdp, wrp, NULL, &tv); @@ -514,9 +539,12 @@ static void pt_poll_now_with_select(pt_Continuation *op) } else if ((rv == 0) || ((errno == EINTR) || (errno == EAGAIN))) { - if (rv == 0) /* select timed out */ - now += PR_MillisecondsToInterval(msecs); - else + if (rv == 0) { /* select timed out */ + if (wait_for_remaining) + now += remaining; + else + now += PR_MillisecondsToInterval(msecs); + } else now = PR_IntervalNow(); elapsed = (PRIntervalTime) (now - epoch); if (elapsed >= op->timeout) { @@ -542,6 +570,7 @@ static void pt_poll_now(pt_Continuation *op) { PRInt32 msecs; PRIntervalTime epoch, now, elapsed, remaining; + PRBool wait_for_remaining; PRThread *self = PR_GetCurrentThread(); PR_ASSERT(PR_INTERVAL_NO_WAIT != op->timeout); @@ -618,9 +647,13 @@ static void pt_poll_now(pt_Continuation *op) tmp_pfd.fd = op->arg1.osfd; tmp_pfd.events = op->event; + wait_for_remaining = PR_TRUE; msecs = (PRInt32)PR_IntervalToMilliseconds(remaining); if (msecs > PT_DEFAULT_POLL_MSEC) + { + wait_for_remaining = PR_FALSE; msecs = PT_DEFAULT_POLL_MSEC; + } rv = poll(&tmp_pfd, 1, msecs); if (self->state & PT_THREAD_ABORTED) @@ -654,7 +687,12 @@ static void pt_poll_now(pt_Continuation *op) } else if ((rv == 0) || ((errno == EINTR) || (errno == EAGAIN))) { if (rv == 0) /* poll timed out */ - now += PR_MillisecondsToInterval(msecs); + { + if (wait_for_remaining) + now += remaining; + else + now += PR_MillisecondsToInterval(msecs); + } else now = PR_IntervalNow(); elapsed = (PRIntervalTime) (now - epoch); @@ -1024,17 +1062,18 @@ static PRBool pt_solaris_sendfile_cont(pt_Continuation *op, PRInt16 revents) ssize_t count; count = SOLARIS_SENDFILEV(op->arg1.osfd, vec, op->arg3.amount, &xferred); - PR_ASSERT((count == -1) || (count == xferred)); - PR_ASSERT(xferred <= op->nbytes_to_send); op->syserrno = errno; + PR_ASSERT((count == -1) || (count == xferred)); if (count == -1) { - if (op->syserrno != EWOULDBLOCK && op->syserrno != EAGAIN) { + if (op->syserrno != EWOULDBLOCK && op->syserrno != EAGAIN + && op->syserrno != EINTR) { op->result.code = -1; return PR_TRUE; } count = xferred; } + PR_ASSERT(count <= op->nbytes_to_send); op->result.code += count; if (count < op->nbytes_to_send) { @@ -1059,7 +1098,34 @@ static PRBool pt_solaris_sendfile_cont(pt_Continuation *op, PRInt16 revents) } #endif /* SOLARIS */ -void _PR_InitIO() +#ifdef LINUX +static PRBool pt_linux_sendfile_cont(pt_Continuation *op, PRInt16 revents) +{ + ssize_t rv; + off_t oldoffset; + + oldoffset = op->offset; + rv = sendfile(op->arg1.osfd, op->in_fd, &op->offset, op->count); + op->syserrno = errno; + + if (rv == -1) { + if (op->syserrno != EWOULDBLOCK && op->syserrno != EAGAIN) { + op->result.code = -1; + return PR_TRUE; + } + rv = 0; + } + PR_ASSERT(rv == op->offset - oldoffset); + op->result.code += rv; + if (rv < op->count) { + op->count -= rv; + return PR_FALSE; + } + return PR_TRUE; +} +#endif /* LINUX */ + +void _PR_InitIO(void) { #if defined(DEBUG) memset(&pt_debug, 0, sizeof(PTDebug)); @@ -1569,6 +1635,18 @@ static PRFileDesc* pt_Accept( if (pt_TestAbort()) return newfd; +#ifdef _PR_STRICT_ADDR_LEN + if (addr) + { + /* + * Set addr->raw.family just so that we can use the + * PR_NETADDR_SIZE macro. + */ + addr->raw.family = fd->secret->af; + addr_len = PR_NETADDR_SIZE(addr); + } +#endif + osfd = accept(fd->secret->md.osfd, (struct sockaddr*)addr, &addr_len); syserrno = errno; @@ -1614,6 +1692,14 @@ static PRFileDesc* pt_Accept( { PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); PR_ASSERT(IsValidNetAddrLen(addr, addr_len) == PR_TRUE); +#ifdef LINUX + /* + * On Linux, experiments showed that the accepted sockets + * inherit the TCP_NODELAY socket option of the listening + * socket. + */ + newfd->secret->md.tcp_nodelay = fd->secret->md.tcp_nodelay; +#endif } return newfd; @@ -2107,7 +2193,7 @@ static PRInt32 pt_AIXSendFile(PRFileDesc *sd, PRSendFileData *sfd, } if (count == -1) { - _MD_aix_map_sendfile_error(syserrno); + pt_MapError(_MD_aix_map_sendfile_error, syserrno); return -1; } if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) { @@ -2146,14 +2232,16 @@ static PRInt32 pt_HPUXSendFile(PRFileDesc *sd, PRSendFileData *sfd, PRInt32 count; int syserrno; - /* Get file size */ - if (fstat(sfd->fd->secret->md.osfd, &statbuf) == -1) { - _PR_MD_MAP_FSTAT_ERROR(errno); - return -1; + if (sfd->file_nbytes == 0) { + /* Get file size */ + if (fstat(sfd->fd->secret->md.osfd, &statbuf) == -1) { + _PR_MD_MAP_FSTAT_ERROR(errno); + return -1; + } + file_nbytes_to_send = statbuf.st_size - sfd->file_offset; + } else { + file_nbytes_to_send = sfd->file_nbytes; } - file_nbytes_to_send = (sfd->file_nbytes == 0) ? - statbuf.st_size - sfd->file_offset : - sfd->file_nbytes; nbytes_to_send = sfd->hlen + sfd->tlen + file_nbytes_to_send; hdtrl[0].iov_base = (void *) sfd->header; /* cast away the 'const' */ @@ -2228,7 +2316,7 @@ static PRInt32 pt_HPUXSendFile(PRFileDesc *sd, PRSendFileData *sfd, } if (count == -1) { - _MD_hpux_map_sendfile_error(syserrno); + pt_MapError(_MD_hpux_map_sendfile_error, syserrno); return -1; } if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) { @@ -2358,7 +2446,7 @@ static PRInt32 pt_SolarisSendFile(PRFileDesc *sd, PRSendFileData *sfd, done: if (count == -1) { - _MD_solaris_map_sendfile_error(syserrno); + pt_MapError(_MD_solaris_map_sendfile_error, syserrno); return -1; } if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) { @@ -2425,6 +2513,140 @@ static PRInt32 pt_SolarisDispatchSendFile(PRFileDesc *sd, PRSendFileData *sfd, #endif /* SOLARIS */ +#ifdef LINUX +/* + * pt_LinuxSendFile + * + * Send file sfd->fd across socket sd. If specified, header and trailer + * buffers are sent before and after the file, respectively. + * + * PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file + * + * return number of bytes sent or -1 on error + * + * This implementation takes advantage of the sendfile() system + * call available in Linux kernel 2.2 or higher. + */ + +static PRInt32 pt_LinuxSendFile(PRFileDesc *sd, PRSendFileData *sfd, + PRTransmitFileFlags flags, PRIntervalTime timeout) +{ + struct stat statbuf; + size_t file_nbytes_to_send; + PRInt32 count = 0; + ssize_t rv; + int syserrno; + off_t offset; + PRBool tcp_cork_enabled = PR_FALSE; + int tcp_cork; + + if (sfd->file_nbytes == 0) { + /* Get file size */ + if (fstat(sfd->fd->secret->md.osfd, &statbuf) == -1) { + _PR_MD_MAP_FSTAT_ERROR(errno); + return -1; + } + file_nbytes_to_send = statbuf.st_size - sfd->file_offset; + } else { + file_nbytes_to_send = sfd->file_nbytes; + } + + if ((sfd->hlen != 0 || sfd->tlen != 0) + && sd->secret->md.tcp_nodelay == 0) { + tcp_cork = 1; + if (setsockopt(sd->secret->md.osfd, SOL_TCP, TCP_CORK, + &tcp_cork, sizeof tcp_cork) == 0) { + tcp_cork_enabled = PR_TRUE; + } else { + syserrno = errno; + if (syserrno != EINVAL) { + _PR_MD_MAP_SETSOCKOPT_ERROR(syserrno); + return -1; + } + /* + * The most likely reason for the EINVAL error is that + * TCP_NODELAY is set (with a function other than + * PR_SetSocketOption). This is not fatal, so we keep + * on going. + */ + PR_LOG(_pr_io_lm, PR_LOG_WARNING, + ("pt_LinuxSendFile: " + "setsockopt(TCP_CORK) failed with EINVAL\n")); + } + } + + if (sfd->hlen != 0) { + count = PR_Send(sd, sfd->header, sfd->hlen, 0, timeout); + if (count == -1) { + goto failed; + } + } + + if (file_nbytes_to_send != 0) { + offset = sfd->file_offset; + do { + rv = sendfile(sd->secret->md.osfd, sfd->fd->secret->md.osfd, + &offset, file_nbytes_to_send); + } while (rv == -1 && (syserrno = errno) == EINTR); + if (rv == -1) { + if (syserrno != EAGAIN && syserrno != EWOULDBLOCK) { + _MD_linux_map_sendfile_error(syserrno); + count = -1; + goto failed; + } + rv = 0; + } + PR_ASSERT(rv == offset - sfd->file_offset); + count += rv; + + if (rv < file_nbytes_to_send) { + pt_Continuation op; + + op.arg1.osfd = sd->secret->md.osfd; + op.in_fd = sfd->fd->secret->md.osfd; + op.offset = offset; + op.count = file_nbytes_to_send - rv; + op.result.code = count; + op.timeout = timeout; + op.function = pt_linux_sendfile_cont; + op.event = POLLOUT | POLLPRI; + count = pt_Continue(&op); + syserrno = op.syserrno; + if (count == -1) { + pt_MapError(_MD_linux_map_sendfile_error, syserrno); + goto failed; + } + } + } + + if (sfd->tlen != 0) { + rv = PR_Send(sd, sfd->trailer, sfd->tlen, 0, timeout); + if (rv == -1) { + count = -1; + goto failed; + } + count += rv; + } + +failed: + if (tcp_cork_enabled) { + tcp_cork = 0; + if (setsockopt(sd->secret->md.osfd, SOL_TCP, TCP_CORK, + &tcp_cork, sizeof tcp_cork) == -1 && count != -1) { + _PR_MD_MAP_SETSOCKOPT_ERROR(errno); + count = -1; + } + } + if (count != -1) { + if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) { + PR_Close(sd); + } + PR_ASSERT(count == sfd->hlen + sfd->tlen + file_nbytes_to_send); + } + return count; +} +#endif /* LINUX */ + #ifdef AIX extern int _pr_aix_send_file_use_disabled; #endif @@ -2465,6 +2687,8 @@ static PRInt32 pt_SendFile( #else return(pt_SolarisDispatchSendFile(sd, sfd, flags, timeout)); #endif /* HAVE_SENDFILEV */ +#elif defined(LINUX) + return(pt_LinuxSendFile(sd, sfd, flags, timeout)); #else return(PR_EmulateSendFile(sd, sfd, flags, timeout)); #endif @@ -2728,6 +2952,12 @@ static PRStatus pt_SetSocketOption(PRFileDesc *fd, const PRSocketOptionData *dat rv = setsockopt( fd->secret->md.osfd, level, name, (char*)&value, sizeof(PRIntn)); +#ifdef LINUX + /* for pt_LinuxSendFile */ + if (name == TCP_NODELAY && rv == 0) { + fd->secret->md.tcp_nodelay = value; + } +#endif break; } case PR_SockOpt_McastLoopback: @@ -3086,27 +3316,27 @@ static PRFileDesc *pt_SetMethods( return fd; } /* pt_SetMethods */ -PR_IMPLEMENT(const PRIOMethods*) PR_GetFileMethods() +PR_IMPLEMENT(const PRIOMethods*) PR_GetFileMethods(void) { return &_pr_file_methods; } /* PR_GetFileMethods */ -PR_IMPLEMENT(const PRIOMethods*) PR_GetPipeMethods() +PR_IMPLEMENT(const PRIOMethods*) PR_GetPipeMethods(void) { return &_pr_pipe_methods; } /* PR_GetPipeMethods */ -PR_IMPLEMENT(const PRIOMethods*) PR_GetTCPMethods() +PR_IMPLEMENT(const PRIOMethods*) PR_GetTCPMethods(void) { return &_pr_tcp_methods; } /* PR_GetTCPMethods */ -PR_IMPLEMENT(const PRIOMethods*) PR_GetUDPMethods() +PR_IMPLEMENT(const PRIOMethods*) PR_GetUDPMethods(void) { return &_pr_udp_methods; } /* PR_GetUDPMethods */ -static const PRIOMethods* PR_GetSocketPollFdMethods() +static const PRIOMethods* PR_GetSocketPollFdMethods(void) { return &_pr_socketpollfd_methods; } /* PR_GetSocketPollFdMethods */ @@ -3116,11 +3346,6 @@ PR_IMPLEMENT(PRFileDesc*) PR_AllocFileDesc( { PRFileDesc *fd = _PR_Getfd(); - /* - * Assert that the file descriptor is small enough to fit in the - * fd_set passed to select - */ - PR_ASSERT(osfd < FD_SETSIZE); if (NULL == fd) goto failed; fd->methods = methods; @@ -3149,6 +3374,12 @@ PR_IMPLEMENT(PRBool) _pr_test_ipv6_socket() { PRInt32 osfd; + /* + * HP-UX only: HP-UX IPv6 Porting Guide (dated February 2001) + * suggests that we call open("/dev/ip6", O_RDWR) to determine + * whether IPv6 APIs and the IPv6 stack are on the system. + * Our portable test below seems to work fine, so I am using it. + */ osfd = socket(AF_INET6, SOCK_STREAM, 0); if (osfd != -1) { close(osfd); @@ -3206,6 +3437,9 @@ PR_IMPLEMENT(PRFileDesc*) PR_Socket(PRInt32 domain, PRInt32 type, PRInt32 proto) fd = pt_SetMethods(osfd, ftype, PR_FALSE, PR_FALSE); if (fd == NULL) close(osfd); } +#ifdef _PR_STRICT_ADDR_LEN + if (fd != NULL) fd->secret->af = domain; +#endif #if defined(_PR_INET6_PROBE) || !defined(_PR_INET6) if (fd != NULL) { /* @@ -3598,6 +3832,7 @@ static PRInt32 _pr_poll_with_poll( { /* make poll() ignore this entry */ syspoll[index].fd = -1; + pds[index].out_flags = 0; } } if (0 == ready) @@ -3805,43 +4040,65 @@ static PRInt32 _pr_poll_with_select( { if (0 == ready) { + PRBool add_to_rd = PR_FALSE; + PRBool add_to_wr = PR_FALSE; + PRBool add_to_ex = PR_FALSE; + selectfd[index] = bottom->secret->md.osfd; if (in_flags_read & PR_POLL_READ) { pds[index].out_flags |= _PR_POLL_READ_SYS_READ; - FD_SET(bottom->secret->md.osfd, &rd); - rdp = &rd; + add_to_rd = PR_TRUE; } if (in_flags_read & PR_POLL_WRITE) { pds[index].out_flags |= _PR_POLL_READ_SYS_WRITE; - FD_SET(bottom->secret->md.osfd, &wr); - wrp = ≀ + add_to_wr = PR_TRUE; } if (in_flags_write & PR_POLL_READ) { pds[index].out_flags |= _PR_POLL_WRITE_SYS_READ; - FD_SET(bottom->secret->md.osfd, &rd); - rdp = &rd; + add_to_rd = PR_TRUE; } if (in_flags_write & PR_POLL_WRITE) { pds[index].out_flags |= _PR_POLL_WRITE_SYS_WRITE; - FD_SET(bottom->secret->md.osfd, &wr); - wrp = ≀ + add_to_wr = PR_TRUE; + } + if (pds[index].in_flags & PR_POLL_EXCEPT) + { + add_to_ex = PR_TRUE; + } + if ((selectfd[index] > maxfd) && + (add_to_rd || add_to_wr || add_to_ex)) + { + maxfd = selectfd[index]; + /* + * If maxfd is too large to be used with + * select, fall back to calling poll. + */ + if (maxfd >= FD_SETSIZE) + break; + } + if (add_to_rd) + { + FD_SET(bottom->secret->md.osfd, &rd); + rdp = &rd; + } + if (add_to_wr) + { + FD_SET(bottom->secret->md.osfd, &wr); + wrp = ≀ + } + if (add_to_ex) + { + FD_SET(bottom->secret->md.osfd, &ex); + exp = &ex; } - if (pds[index].in_flags & PR_POLL_EXCEPT) { - FD_SET(bottom->secret->md.osfd, &ex); - exp = &ex; - } - if ((selectfd[index] > maxfd) && - (pds[index].out_flags || - (pds[index].in_flags & PR_POLL_EXCEPT))) - maxfd = selectfd[index]; } } else @@ -3859,10 +4116,14 @@ static PRInt32 _pr_poll_with_select( } } } + else + { + pds[index].out_flags = 0; + } } if (0 == ready) { - if ((maxfd + 1) > FD_SETSIZE) + if (maxfd >= FD_SETSIZE) { /* * maxfd too large to be used with select, fall back to @@ -4017,14 +4278,14 @@ PR_IMPLEMENT(PRDirEntry*) PR_ReadDir(PRDir *dir, PRDirFlags flags) return &dir->d; } /* PR_ReadDir */ -PR_IMPLEMENT(PRFileDesc*) PR_NewUDPSocket() +PR_IMPLEMENT(PRFileDesc*) PR_NewUDPSocket(void) { PRIntn domain = PF_INET; return PR_Socket(domain, SOCK_DGRAM, 0); } /* PR_NewUDPSocket */ -PR_IMPLEMENT(PRFileDesc*) PR_NewTCPSocket() +PR_IMPLEMENT(PRFileDesc*) PR_NewTCPSocket(void) { PRIntn domain = PF_INET; @@ -4122,7 +4383,7 @@ PR_IMPLEMENT(PRStatus) PR_SetFDInheritable( { return PR_FAILURE; } - fd->secret->inheritable = inheritable; + fd->secret->inheritable = (_PRTriStateBool) inheritable; } return PR_SUCCESS; } @@ -4158,6 +4419,9 @@ PR_IMPLEMENT(PRFileDesc*) PR_ImportTCPSocket(PRInt32 osfd) if (!_pr_initialized) _PR_ImplicitInitialization(); fd = pt_SetMethods(osfd, PR_DESC_SOCKET_TCP, PR_FALSE, PR_TRUE); if (NULL == fd) close(osfd); +#ifdef _PR_STRICT_ADDR_LEN + if (NULL != fd) fd->secret->af = PF_INET; +#endif return fd; } /* PR_ImportTCPSocket */ @@ -4552,4 +4816,39 @@ retry: } #endif /* defined(_PR_PTHREADS) */ +#ifdef MOZ_UNICODE +/* ================ UTF16 Interfaces ================================ */ +PR_IMPLEMENT(PRFileDesc*) PR_OpenFileUTF16( + const PRUnichar *name, PRIntn flags, PRIntn mode) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return NULL; +} + +PR_IMPLEMENT(PRStatus) PR_CloseDirUTF16(PRDir *dir) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return PR_FAILURE; +} + +PR_IMPLEMENT(PRDirUTF16*) PR_OpenDirUTF16(const PRUnichar *name) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return NULL; +} + +PR_IMPLEMENT(PRDirEntryUTF16*) PR_ReadDirUTF16(PRDirUTF16 *dir, PRDirFlags flags) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return NULL; +} + +PR_IMPLEMENT(PRStatus) PR_GetFileInfo64UTF16(const PRUnichar *fn, PRFileInfo64 *info) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return PR_FAILURE; +} +/* ================ UTF16 Interfaces ================================ */ +#endif /* MOZ_UNICODE */ + /* ptio.c */ diff --git a/pr/src/pthreads/ptsynch.c b/pr/src/pthreads/ptsynch.c index 4400e8df..17334af3 100644 --- a/pr/src/pthreads/ptsynch.c +++ b/pr/src/pthreads/ptsynch.c @@ -71,6 +71,13 @@ void _PR_InitLocks(void) rv = _PT_PTHREAD_MUTEXATTR_INIT(&_pt_mattr); PR_ASSERT(0 == rv); +#ifdef LINUX +#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) + rv = pthread_mutexattr_settype(&_pt_mattr, PTHREAD_MUTEX_ADAPTIVE_NP); + PR_ASSERT(0 == rv); +#endif +#endif + rv = _PT_PTHREAD_CONDATTR_INIT(&_pt_cvar_attr); PR_ASSERT(0 == rv); } @@ -1041,7 +1048,7 @@ PR_IMPLEMENT(PRStatus) PRP_TryLock(PRLock *lock) return (PT_TRYLOCK_SUCCESS == rv) ? PR_SUCCESS : PR_FAILURE; } /* PRP_TryLock */ -PR_IMPLEMENT(PRCondVar*) PRP_NewNakedCondVar() +PR_IMPLEMENT(PRCondVar*) PRP_NewNakedCondVar(void) { PRCondVar *cv; diff --git a/pr/src/pthreads/ptthread.c b/pr/src/pthreads/ptthread.c index dc8cc127..7fc2ad4d 100644 --- a/pr/src/pthreads/ptthread.c +++ b/pr/src/pthreads/ptthread.c @@ -607,9 +607,9 @@ PR_IMPLEMENT(PRStatus) PR_JoinThread(PRThread *thred) return (0 == rv) ? PR_SUCCESS : PR_FAILURE; } /* PR_JoinThread */ -PR_IMPLEMENT(void) PR_DetachThread() { } /* PR_DetachThread */ +PR_IMPLEMENT(void) PR_DetachThread(void) { } /* PR_DetachThread */ -PR_IMPLEMENT(PRThread*) PR_GetCurrentThread() +PR_IMPLEMENT(PRThread*) PR_GetCurrentThread(void) { void *thred; @@ -724,25 +724,25 @@ PR_IMPLEMENT(PRStatus) PR_Interrupt(PRThread *thred) return PR_SUCCESS; } /* PR_Interrupt */ -PR_IMPLEMENT(void) PR_ClearInterrupt() +PR_IMPLEMENT(void) PR_ClearInterrupt(void) { PRThread *me = PR_CurrentThread(); me->state &= ~PT_THREAD_ABORTED; } /* PR_ClearInterrupt */ -PR_IMPLEMENT(void) PR_BlockInterrupt() +PR_IMPLEMENT(void) PR_BlockInterrupt(void) { PRThread *me = PR_CurrentThread(); _PT_THREAD_BLOCK_INTERRUPT(me); } /* PR_BlockInterrupt */ -PR_IMPLEMENT(void) PR_UnblockInterrupt() +PR_IMPLEMENT(void) PR_UnblockInterrupt(void) { PRThread *me = PR_CurrentThread(); _PT_THREAD_UNBLOCK_INTERRUPT(me); } /* PR_UnblockInterrupt */ -PR_IMPLEMENT(PRStatus) PR_Yield() +PR_IMPLEMENT(PRStatus) PR_Yield(void) { static PRBool warning = PR_TRUE; if (warning) warning = _PR_Obsolete( @@ -908,7 +908,7 @@ void _PR_InitThreads( PR_SetThreadPriority(thred, priority); } /* _PR_InitThreads */ -PR_IMPLEMENT(PRStatus) PR_Cleanup() +PR_IMPLEMENT(PRStatus) PR_Cleanup(void) { PRThread *me = PR_CurrentThread(); PR_LOG(_pr_thread_lm, PR_LOG_MIN, ("PR_Cleanup: shutting down NSPR")); @@ -920,7 +920,12 @@ PR_IMPLEMENT(PRStatus) PR_Cleanup() PR_WaitCondVar(pt_book.cv, PR_INTERVAL_NO_TIMEOUT); PR_Unlock(pt_book.ml); + _PR_CleanupMW(); + _PR_CleanupDtoa(); + _PR_CleanupCallOnce(); + _PR_ShutdownLinker(); _PR_LogCleanup(); + _PR_CleanupNet(); /* Close all the fd's before calling _PR_CleanupIO */ _PR_CleanupIO(); @@ -1026,7 +1031,7 @@ static void null_signal_handler(PRIntn sig); * conflict with the use of these two signals in our GC support. * So we don't know how to support GC on Linux pthreads. */ -static void init_pthread_gc_support() +static void init_pthread_gc_support(void) { PRIntn rv; @@ -1066,14 +1071,14 @@ static void init_pthread_gc_support() #endif /* defined(_PR_DCETHREADS) */ } -PR_IMPLEMENT(void) PR_SetThreadGCAble() +PR_IMPLEMENT(void) PR_SetThreadGCAble(void) { PR_Lock(pt_book.ml); PR_CurrentThread()->state |= PT_THREAD_GCABLE; PR_Unlock(pt_book.ml); } -PR_IMPLEMENT(void) PR_ClearThreadGCAble() +PR_IMPLEMENT(void) PR_ClearThreadGCAble(void) { PR_Lock(pt_book.ml); PR_CurrentThread()->state &= (~PT_THREAD_GCABLE); @@ -1086,12 +1091,6 @@ static PRBool suspendAllOn = PR_FALSE; static PRBool suspendAllSuspended = PR_FALSE; -/* Are all GCAble threads (except gc'ing thread) suspended? */ -PR_IMPLEMENT(PRBool) PR_SuspendAllSuspended() -{ - return suspendAllSuspended; -} /* PR_SuspendAllSuspended */ - PR_IMPLEMENT(PRStatus) PR_EnumerateThreads(PREnumerator func, void *arg) { PRIntn count = 0; @@ -1215,7 +1214,7 @@ static void suspend_signal_handler(PRIntn sig) while (me->suspend & PT_THREAD_SUSPENDED) { #if !defined(FREEBSD) && !defined(NETBSD) && !defined(OPENBSD) \ - && !defined(BSDI) && !defined(VMS) && !defined(UNIXWARE) /*XXX*/ + && !defined(BSDI) && !defined(VMS) && !defined(UNIXWARE) && !defined(DARWIN) /*XXX*/ PRIntn rv; sigwait(&sigwait_set, &rv); #endif @@ -1242,12 +1241,12 @@ static void suspend_signal_handler(PRIntn sig) ("End suspend_signal_handler thred = %X tid = %X\n", me, me->id)); } /* suspend_signal_handler */ -static void PR_SuspendSet(PRThread *thred) +static void pt_SuspendSet(PRThread *thred) { PRIntn rv; PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, - ("PR_SuspendSet thred %X thread id = %X\n", thred, thred->id)); + ("pt_SuspendSet thred %X thread id = %X\n", thred, thred->id)); /* @@ -1257,7 +1256,7 @@ static void PR_SuspendSet(PRThread *thred) PR_ASSERT((thred->suspend & PT_THREAD_SUSPENDED) == 0); PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, - ("doing pthread_kill in PR_SuspendSet thred %X tid = %X\n", + ("doing pthread_kill in pt_SuspendSet thred %X tid = %X\n", thred, thred->id)); #if defined(VMS) rv = thread_suspend(thred); @@ -1267,10 +1266,10 @@ static void PR_SuspendSet(PRThread *thred) PR_ASSERT(0 == rv); } -static void PR_SuspendTest(PRThread *thred) +static void pt_SuspendTest(PRThread *thred) { PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, - ("Begin PR_SuspendTest thred %X thread id = %X\n", thred, thred->id)); + ("Begin pt_SuspendTest thred %X thread id = %X\n", thred, thred->id)); /* @@ -1296,13 +1295,13 @@ static void PR_SuspendTest(PRThread *thred) #endif PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, - ("End PR_SuspendTest thred %X tid %X\n", thred, thred->id)); -} /* PR_SuspendTest */ + ("End pt_SuspendTest thred %X tid %X\n", thred, thred->id)); +} /* pt_SuspendTest */ -PR_IMPLEMENT(void) PR_ResumeSet(PRThread *thred) +static void pt_ResumeSet(PRThread *thred) { PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, - ("PR_ResumeSet thred %X thread id = %X\n", thred, thred->id)); + ("pt_ResumeSet thred %X thread id = %X\n", thred, thred->id)); /* * Clear the global state and set the thread state so that it will @@ -1322,12 +1321,12 @@ PR_IMPLEMENT(void) PR_ResumeSet(PRThread *thred) #endif #endif -} /* PR_ResumeSet */ +} /* pt_ResumeSet */ -PR_IMPLEMENT(void) PR_ResumeTest(PRThread *thred) +static void pt_ResumeTest(PRThread *thred) { PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, - ("Begin PR_ResumeTest thred %X thread id = %X\n", thred, thred->id)); + ("Begin pt_ResumeTest thred %X thread id = %X\n", thred, thred->id)); /* * Wait for the threads resume state to change @@ -1351,12 +1350,12 @@ PR_IMPLEMENT(void) PR_ResumeTest(PRThread *thred) thred->suspend &= ~PT_THREAD_RESUMED; PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ( - "End PR_ResumeTest thred %X tid %X\n", thred, thred->id)); -} /* PR_ResumeTest */ + "End pt_ResumeTest thred %X tid %X\n", thred, thred->id)); +} /* pt_ResumeTest */ static pthread_once_t pt_gc_support_control = PTHREAD_ONCE_INIT; -PR_IMPLEMENT(void) PR_SuspendAll() +PR_IMPLEMENT(void) PR_SuspendAll(void) { #ifdef DEBUG PRIntervalTime stime, etime; @@ -1379,7 +1378,7 @@ PR_IMPLEMENT(void) PR_SuspendAll() while (thred != NULL) { if ((thred != me) && _PT_IS_GCABLE_THREAD(thred)) - PR_SuspendSet(thred); + pt_SuspendSet(thred); thred = thred->next; } @@ -1388,7 +1387,7 @@ PR_IMPLEMENT(void) PR_SuspendAll() while (thred != NULL) { if ((thred != me) && _PT_IS_GCABLE_THREAD(thred)) - PR_SuspendTest(thred); + pt_SuspendTest(thred); thred = thred->next; } @@ -1402,7 +1401,7 @@ PR_IMPLEMENT(void) PR_SuspendAll() #endif } /* PR_SuspendAll */ -PR_IMPLEMENT(void) PR_ResumeAll() +PR_IMPLEMENT(void) PR_ResumeAll(void) { #ifdef DEBUG PRIntervalTime stime, etime; @@ -1421,7 +1420,7 @@ PR_IMPLEMENT(void) PR_ResumeAll() while (thred != NULL) { if ((thred != me) && _PT_IS_GCABLE_THREAD(thred)) - PR_ResumeSet(thred); + pt_ResumeSet(thred); thred = thred->next; } @@ -1429,7 +1428,7 @@ PR_IMPLEMENT(void) PR_ResumeAll() while (thred != NULL) { if ((thred != me) && _PT_IS_GCABLE_THREAD(thred)) - PR_ResumeTest(thred); + pt_ResumeTest(thred); thred = thred->next; } |