Bugzilla bug #17223: implemented the PR_MSG_PEEK flag for PR_Recv() for

BeOS, Mac OS, OS/2, and Windows.  On BeOS, Mac OS, and NT, PR_MSG_PEEK
is emulated with a peek buffer in the NSPR file descriptors.
Modified files: _beos.h, _macos.h, _winnt.h, primpl.h, prsocket.c,
macsockotpt.c, os2sock.c, ntio.c, and w95sock.c


git-svn-id: svn://10.0.0.236/trunk@68299 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
wtc%netscape.com
2000-05-05 00:32:49 +00:00
parent 7a38d3a548
commit 97d2ae4fd2
9 changed files with 117 additions and 13 deletions

View File

@@ -68,6 +68,9 @@
#define _PR_GLOBAL_THREADS_ONLY
#define _PR_BTHREADS
#define _PR_NEED_FAKE_POLL
#define _PR_HAVE_PEEK_BUFFER
#define _PR_PEEK_BUFFER_MAX (16 * 1024)
#define _PR_FD_NEED_EMULATE_MSG_PEEK(fd) 1
/* Define threading functions and objects as native BeOS */
struct _MDThread {

View File

@@ -46,7 +46,9 @@
#include <setjmp.h>
#include <Errors.h>
#define _PR_EMULATE_MSG_PEEK
#define _PR_HAVE_PEEK_BUFFER
#define _PR_PEEK_BUFFER_MAX (16 * 1024)
#define _PR_FD_NEED_EMULATE_MSG_PEEK(fd) 1
struct _MDProcess {
PRInt8 notused;

View File

@@ -50,7 +50,10 @@
#define _PR_HAVE_ATOMIC_OPS
#define _PR_HAVE_ATOMIC_CAS
#define PR_HAVE_WIN32_NAMED_SHARED_MEMORY
#define _PR_EMULATE_MSG_PEEK
#define _PR_HAVE_PEEK_BUFFER
#define _PR_PEEK_BUFFER_MAX (32 * 1024)
#define _PR_FD_NEED_EMULATE_MSG_PEEK(fd) \
(!(fd)->secret->nonblocking && !(fd)->secret->inheritable)
/* --- Common User-Thread/Native-Thread Definitions --------------------- */

View File

@@ -1577,8 +1577,8 @@ struct PRFilePrivate {
PRBool inheritable;
PRFileDesc *next;
PRIntn lockCount;
#ifdef _PR_EMULATE_MSG_PEEK
char *peekBuf;
#ifdef _PR_HAVE_PEEK_BUFFER
char *peekBuffer;
PRInt32 peekBufSize;
PRInt32 peekBytes;
#endif

View File

@@ -543,6 +543,10 @@ PRIntervalTime timeout)
PRInt32 rv;
PRThread *me = _PR_MD_CURRENT_THREAD();
if ((flags != 0) && (flags != PR_MSG_PEEK)) {
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
return -1;
}
if (_PR_PENDING_INTERRUPT(me)) {
me->flags &= ~_PR_INTERRUPT;
PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
@@ -553,11 +557,61 @@ PRIntervalTime timeout)
return -1;
}
PR_LOG(_pr_io_lm, PR_LOG_MAX, ("recv: fd=%p osfd=%d buf=%p amount=%d",
fd, fd->secret->md.osfd, buf, amount));
PR_LOG(_pr_io_lm, PR_LOG_MAX, ("recv: fd=%p osfd=%d buf=%p amount=%d flags=%d",
fd, fd->secret->md.osfd, buf, amount, flags));
#ifdef _PR_HAVE_PEEK_BUFFER
if (fd->secret->peekBytes != 0) {
rv = (amount < fd->secret->peekBytes) ?
amount : fd->secret->peekBytes;
memcpy(buf, fd->secret->peekBuffer, rv);
if (flags == 0) {
/* consume the bytes in the peek buffer */
fd->secret->peekBytes -= rv;
if (fd->secret->peekBytes != 0) {
memmove(fd->secret->peekBuffer,
fd->secret->peekBuffer + rv,
fd->secret->peekBytes);
}
}
return rv;
}
/* allocate peek buffer, if necessary */
if ((PR_MSG_PEEK == flags) && _PR_FD_NEED_EMULATE_MSG_PEEK(fd)) {
PR_ASSERT(0 == fd->secret->peekBytes);
/* impose a max size on the peek buffer */
if (amount > _PR_PEEK_BUFFER_MAX) {
amount = _PR_PEEK_BUFFER_MAX;
}
if (fd->secret->peekBufSize < amount) {
if (fd->secret->peekBuffer) {
PR_Free(fd->secret->peekBuffer);
}
fd->secret->peekBufSize = amount;
fd->secret->peekBuffer = PR_Malloc(amount);
if (NULL == fd->secret->peekBuffer) {
fd->secret->peekBufSize = 0;
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
return -1;
}
}
}
#endif
rv = _PR_MD_RECV(fd, buf, amount, flags, timeout);
PR_LOG(_pr_io_lm, PR_LOG_MAX, ("recv -> %d, error = %d, os error = %d",
rv, PR_GetError(), PR_GetOSError()));
#ifdef _PR_HAVE_PEEK_BUFFER
if ((PR_MSG_PEEK == flags) && _PR_FD_NEED_EMULATE_MSG_PEEK(fd)) {
if (rv > 0) {
memcpy(fd->secret->peekBuffer, buf, me->md.blocked_io_bytes);
fd->secret->peekBytes = me->md.blocked_io_bytes;
}
}
#endif
return rv;
}
@@ -626,6 +680,15 @@ static PRStatus PR_CALLBACK SocketClose(PRFileDesc *fd)
fd->secret->state = _PR_FILEDESC_CLOSED;
}
#ifdef _PR_HAVE_PEEK_BUFFER
if (fd->secret->peekBuffer) {
PR_ASSERT(fd->secret->peekBufSize > 0);
PR_DELETE(fd->secret->peekBuffer);
fd->secret->peekBufSize = 0;
fd->secret->peekBytes = 0;
}
#endif
PR_FreeFileDesc(fd);
return PR_SUCCESS;
}
@@ -633,6 +696,11 @@ static PRStatus PR_CALLBACK SocketClose(PRFileDesc *fd)
static PRInt32 PR_CALLBACK SocketAvailable(PRFileDesc *fd)
{
PRInt32 rv;
#ifdef _PR_HAVE_PEEK_BUFFER
if (fd->secret->peekBytes != 0) {
return fd->secret->peekBytes;
}
#endif
rv = _PR_MD_SOCKETAVAILABLE(fd);
return rv;
}
@@ -640,6 +708,12 @@ static PRInt32 PR_CALLBACK SocketAvailable(PRFileDesc *fd)
static PRInt64 PR_CALLBACK SocketAvailable64(PRFileDesc *fd)
{
PRInt64 rv;
#ifdef _PR_HAVE_PEEK_BUFFER
if (fd->secret->peekBytes != 0) {
LL_I2L(rv, fd->secret->peekBytes);
return rv;
}
#endif
LL_I2L(rv, _PR_MD_SOCKETAVAILABLE(fd));
return rv;
}

View File

@@ -1349,7 +1349,8 @@ static PRInt32 SendReceiveStream(PRFileDesc *fd, void *buf, PRInt32 amount,
PRThread *me = _PR_MD_CURRENT_THREAD();
PRInt32 bytesLeft = amount;
PR_ASSERT(flags == 0);
PR_ASSERT(flags == 0 ||
(opCode == kSTREAM_RECEIVE && flags == PR_MSG_PEEK));
PR_ASSERT(opCode == kSTREAM_SEND || opCode == kSTREAM_RECEIVE);
if (endpoint == NULL) {

View File

@@ -320,8 +320,15 @@ _PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
int socks[1];
long lTimeout = -1;
#endif
int osflags;
while ((rv = recv( osfd, buf, amount, 0)) == -1)
if (0 == flags) {
osflags = 0;
} else {
PR_ASSERT(PR_MSG_PEEK == flags);
osflags = MSG_PEEK;
}
while ((rv = recv( osfd, buf, amount, osflags)) == -1)
{
if (((err = sock_errno()) == EWOULDBLOCK)
&& (!fd->secret->nonblocking))

View File

@@ -96,7 +96,7 @@ PRInt32 IsFileLocal(HANDLE hFile);
static PRInt32 _md_MakeNonblock(HANDLE);
PRInt32 _nt_nonblock_accept(PRFileDesc *fd, struct sockaddr_in *addr, int *len, PRIntervalTime);
PRInt32 _nt_nonblock_recv(PRFileDesc *fd, char *buf, int len, PRIntervalTime);
PRInt32 _nt_nonblock_recv(PRFileDesc *fd, char *buf, int len, int flags, PRIntervalTime);
PRInt32 _nt_nonblock_send(PRFileDesc *fd, char *buf, int len, PRIntervalTime);
PRInt32 _nt_nonblock_writev(PRFileDesc *fd, const PRIOVec *iov, int size, PRIntervalTime);
PRInt32 _nt_nonblock_sendto(PRFileDesc *, const char *, int, const struct sockaddr *, int, PRIntervalTime);
@@ -1729,7 +1729,7 @@ _PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
PR_ASSERT(0 != rv);
fd->secret->md.io_model_committed = PR_TRUE;
}
return _nt_nonblock_recv(fd, buf, amount, timeout);
return _nt_nonblock_recv(fd, buf, amount, flags, timeout);
}
if (me->io_suspended) {
@@ -3808,14 +3808,21 @@ retry:
return(rv);
}
PRInt32 _nt_nonblock_recv(PRFileDesc *fd, char *buf, int len, PRIntervalTime timeout)
PRInt32 _nt_nonblock_recv(PRFileDesc *fd, char *buf, int len, int flags, PRIntervalTime timeout)
{
PRInt32 osfd = fd->secret->md.osfd;
PRInt32 rv, err;
struct timeval tv, *tvp;
fd_set rd;
int osflags;
while ((rv = recv(osfd,buf,len,0)) == -1) {
if (0 == flags) {
osflags = 0;
} else {
PR_ASSERT(PR_MSG_PEEK == flags);
osflags = MSG_PEEK;
}
while ((rv = recv(osfd,buf,len,osflags)) == -1) {
if (((err = WSAGetLastError()) == WSAEWOULDBLOCK)
&& (!fd->secret->nonblocking)) {
FD_ZERO(&rd);

View File

@@ -171,8 +171,15 @@ _PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
{
PRInt32 osfd = fd->secret->md.osfd;
PRInt32 rv, err;
int osflags;
while ((rv = recv( osfd, buf, amount, 0)) == -1)
if (0 == flags) {
osflags = 0;
} else {
PR_ASSERT(PR_MSG_PEEK == flags);
osflags = MSG_PEEK;
}
while ((rv = recv( osfd, buf, amount, osflags)) == -1)
{
if (((err = WSAGetLastError()) == WSAEWOULDBLOCK)
&& (!fd->secret->nonblocking))