summaryrefslogtreecommitdiff
path: root/pr/src/pthreads
diff options
context:
space:
mode:
Diffstat (limited to 'pr/src/pthreads')
-rw-r--r--pr/src/pthreads/Makefile.in5
-rw-r--r--pr/src/pthreads/ptio.c413
-rw-r--r--pr/src/pthreads/ptsynch.c9
-rw-r--r--pr/src/pthreads/ptthread.c73
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 = &wr;
+ 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 = &wr;
+ 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 = &wr;
+ }
+ 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;
}