📄 w16sock.c
字号:
if ( _PR_PENDING_INTERRUPT(me)) { me->flags &= ~_PR_INTERRUPT; PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); } else { PR_SetError(PR_IO_TIMEOUT_ERROR, 0); } rv = -1; goto done; } else if (_PR_PENDING_INTERRUPT(me)) { me->flags &= ~_PR_INTERRUPT; PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); rv = -1; goto done; } } else if ((err == WSAEINTR) && (!_PR_PENDING_INTERRUPT(me))){ continue; } else { break; } } if (rv < 0) { _PR_MD_MAP_SENDTO_ERROR(err); }done: return rv;}PRInt32_PR_MD_RECVFROM(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout){ PRInt32 osfd = fd->secret->md.osfd; PRThread *me = _PR_MD_CURRENT_THREAD(); PRInt32 rv, err; while ((*addrlen = PR_NETADDR_SIZE(addr)), ((rv = recvfrom(osfd, buf, amount, flags, (struct sockaddr FAR *) addr,(int FAR *)addrlen)) == -1)) { err = WSAGetLastError(); if ( err == WSAEWOULDBLOCK ) { if (fd->secret->nonblocking) { break; } if (_PR_WaitForFD(osfd, PR_POLL_READ, timeout) == 0) { if ( _PR_PENDING_INTERRUPT(me)) { me->flags &= ~_PR_INTERRUPT; PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); } else { PR_SetError(PR_IO_TIMEOUT_ERROR, 0); } rv = -1; goto done; } else if (_PR_PENDING_INTERRUPT(me)) { me->flags &= ~_PR_INTERRUPT; PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); rv = -1; goto done; } } else if ((err == WSAEINTR) && (!_PR_PENDING_INTERRUPT(me))){ continue; } else { break; } } if (rv < 0) { _PR_MD_MAP_RECVFROM_ERROR(err); }done: return(rv);}PRInt32_PR_MD_WRITEV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, PRIntervalTime timeout){ int index; int sent = 0; int rv; for (index=0; index < iov_size; index++) {/* * XXX To be fixed * should call PR_Send */ rv = _PR_MD_SEND(fd, iov[index].iov_base, iov[index].iov_len, 0, timeout); if (rv > 0) sent += rv; if ( rv != iov[index].iov_len ) { if (sent <= 0) return -1; return -1; } } return sent;}PRInt32_PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how){PRInt32 rv; rv = shutdown(fd->secret->md.osfd, how); if (rv < 0) _PR_MD_MAP_SHUTDOWN_ERROR(WSAGetLastError()); return rv;}PRStatus_PR_MD_GETSOCKNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *len){ PRInt32 rv; rv = getsockname((SOCKET)fd->secret->md.osfd, (struct sockaddr *)addr, (int *)len); if (rv==0) return PR_SUCCESS; else { _PR_MD_MAP_GETSOCKNAME_ERROR(WSAGetLastError()); return PR_FAILURE; }}PRStatus_PR_MD_GETPEERNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *len){ PRInt32 rv; rv = getpeername((SOCKET)fd->secret->md.osfd, (struct sockaddr *)addr, (int*)len); if (rv==0) return PR_SUCCESS; else { _PR_MD_MAP_GETPEERNAME_ERROR(WSAGetLastError()); return PR_FAILURE; }}PRStatus_PR_MD_GETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen){ PRInt32 rv; rv = getsockopt((SOCKET)fd->secret->md.osfd, level, optname, optval, (int*)optlen); if (rv==0) return PR_SUCCESS; else { _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError()); return PR_FAILURE; }}PRStatus_PR_MD_SETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, const char* optval, PRInt32 optlen){ PRInt32 rv; rv = setsockopt((SOCKET)fd->secret->md.osfd, level, optname, optval, optlen); if (rv==0) return PR_SUCCESS; else { _PR_MD_MAP_SETSOCKOPT_ERROR(WSAGetLastError()); return PR_FAILURE; }}void_PR_MD_MAKE_NONBLOCK(PRFileDesc *f){ return; // do nothing!}/*** Wait for I/O on a single descriptor. * * return 0, if timed-out, else return 1*/PRInt32_PR_WaitForFD(PRInt32 osfd, PRUintn how, PRIntervalTime timeout){ _PRWin16PollDesc *pd; PRPollQueue *pq; PRIntn is; PRInt32 rv = 1; PRThread *me = _PR_MD_CURRENT_THREAD(); PR_ASSERT(!(me->flags & _PR_IDLE_THREAD)); pd = &me->md.thr_pd; pq = &me->md.thr_pq; if (timeout == PR_INTERVAL_NO_WAIT) return 0; pd->osfd = osfd; pd->in_flags = how; pd->out_flags = 0; pq->pds = pd; pq->npds = 1; _PR_INTSOFF(is); _PR_MD_IOQ_LOCK(); _PR_THREAD_LOCK(me); if (_PR_PENDING_INTERRUPT(me)) { _PR_THREAD_UNLOCK(me); _PR_MD_IOQ_UNLOCK(); return 0; } pq->thr = me; pq->on_ioq = PR_TRUE; pq->timeout = timeout; _PR_ADD_TO_IOQ((*pq), me->cpu); if (how == PR_POLL_READ) { FD_SET(osfd, &_PR_FD_READ_SET(me->cpu)); (_PR_FD_READ_CNT(me->cpu))[osfd]++; } else if (how == PR_POLL_WRITE) { FD_SET(osfd, &_PR_FD_WRITE_SET(me->cpu)); (_PR_FD_WRITE_CNT(me->cpu))[osfd]++; } else { FD_SET(osfd, &_PR_FD_EXCEPTION_SET(me->cpu)); (_PR_FD_EXCEPTION_CNT(me->cpu))[osfd]++; } if (_PR_IOQ_MAX_OSFD(me->cpu) < osfd) _PR_IOQ_MAX_OSFD(me->cpu) = osfd; if (_PR_IOQ_TIMEOUT(me->cpu) > timeout) _PR_IOQ_TIMEOUT(me->cpu) = timeout; _PR_THREAD_LOCK(me); _PR_SLEEPQ_LOCK(me->cpu); _PR_ADD_SLEEPQ(me, timeout); me->state = _PR_IO_WAIT; me->io_pending = PR_TRUE; me->io_suspended = PR_FALSE; _PR_SLEEPQ_UNLOCK(me->cpu); _PR_THREAD_UNLOCK(me); _PR_MD_IOQ_UNLOCK(); _PR_MD_WAIT(me, timeout); me->io_pending = PR_FALSE; me->io_suspended = PR_FALSE; /* ** If we timed out the pollq might still be on the ioq. Remove it ** before continuing. */ if (pq->on_ioq) { _PR_INTSOFF(is); _PR_MD_IOQ_LOCK(); /* * Need to check pq.on_ioq again */ if (pq->on_ioq) { PR_REMOVE_LINK(&pq->links); if (how == PR_POLL_READ) { if ((--(_PR_FD_READ_CNT(me->cpu))[osfd]) == 0) FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu)); } else if (how == PR_POLL_WRITE) { if ((--(_PR_FD_WRITE_CNT(me->cpu))[osfd]) == 0) FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu)); } else { if ((--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd]) == 0) FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu)); } } _PR_MD_IOQ_UNLOCK(); rv = 0; } _PR_FAST_INTSON(is); return(rv);}/* * Unblock threads waiting for I/O * used when interrupting threads * * NOTE: The thread lock should held when this function is called. * On return, the thread lock is released. */void _PR_Unblock_IO_Wait(PRThread *thr){ int pri = thr->priority; _PRCPU *cpu = thr->cpu; PR_ASSERT(thr->flags & (_PR_ON_SLEEPQ | _PR_ON_PAUSEQ)); _PR_SLEEPQ_LOCK(cpu); _PR_DEL_SLEEPQ(thr, PR_TRUE); _PR_SLEEPQ_UNLOCK(cpu); PR_ASSERT(!(thr->flags & _PR_IDLE_THREAD)); thr->state = _PR_RUNNABLE; _PR_RUNQ_LOCK(cpu); _PR_ADD_RUNQ(thr, cpu, pri); _PR_RUNQ_UNLOCK(cpu); _PR_THREAD_UNLOCK(thr); _PR_MD_WAKEUP_WAITER(thr);}/*** Scan through io queue and find any bad fd's that triggered the error** from _MD_SELECT*/static void FindBadFDs(void){ PRCList *q; PRThread *me = _MD_CURRENT_THREAD(); int sockOpt; int sockOptLen = sizeof(sockOpt); PR_ASSERT(!_PR_IS_NATIVE_THREAD(me)); q = (_PR_IOQ(me->cpu)).next; _PR_IOQ_MAX_OSFD(me->cpu) = -1; _PR_IOQ_TIMEOUT(me->cpu) = PR_INTERVAL_NO_TIMEOUT; while (q != &_PR_IOQ(me->cpu)) { PRPollQueue *pq = _PR_POLLQUEUE_PTR(q); PRBool notify = PR_FALSE; _PRWin16PollDesc *pds = pq->pds; _PRWin16PollDesc *epds = pds + pq->npds; PRInt32 pq_max_osfd = -1; q = q->next; for (; pds < epds; pds++) { PRInt32 osfd = pds->osfd; pds->out_flags = 0; PR_ASSERT(osfd >= 0 || pds->in_flags == 0); if (pds->in_flags == 0) { continue; /* skip this fd */ } if ( getsockopt(osfd, (int)SOL_SOCKET, SO_TYPE, (char*)&sockOpt, &sockOptLen) == SOCKET_ERROR ) { if ( WSAGetLastError() == WSAENOTSOCK ) { PR_LOG(_pr_io_lm, PR_LOG_MAX, ("file descriptor %d is bad", osfd)); pds->out_flags = PR_POLL_NVAL; notify = PR_TRUE; } } if (osfd > pq_max_osfd) { pq_max_osfd = osfd; } } if (notify) { PRIntn pri; PR_REMOVE_LINK(&pq->links); pq->on_ioq = PR_FALSE; /* * Decrement the count of descriptors for each desciptor/event * because this I/O request is being removed from the * ioq */ pds = pq->pds; for (; pds < epds; pds++) { PRInt32 osfd = pds->osfd; PRInt16 in_flags = pds->in_flags; PR_ASSERT(osfd >= 0 || in_flags == 0); if (in_flags & PR_POLL_READ) { if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0) FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu)); } if (in_flags & PR_POLL_WRITE) { if (--(_PR_FD_WRITE_CNT(me->cpu))[osfd] == 0) FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu)); } if (in_flags & PR_POLL_EXCEPT) { if (--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd] == 0) FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu)); } } _PR_THREAD_LOCK(pq->thr); if (pq->thr->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) { _PRCPU *cpu = pq->thr->cpu; _PR_SLEEPQ_LOCK(pq->thr->cpu); _PR_DEL_SLEEPQ(pq->thr, PR_TRUE); _PR_SLEEPQ_UNLOCK(pq->thr->cpu);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -