⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unix.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 5 页
字号:
                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);					if (pq->thr->flags & _PR_SUSPENDING) {					    /*					     * set thread state to SUSPENDED;					     * a Resume operation on the thread					     * will move it to the runQ					     */					    pq->thr->state = _PR_SUSPENDED;					    _PR_MISCQ_LOCK(pq->thr->cpu);					    _PR_ADD_SUSPENDQ(pq->thr, pq->thr->cpu);					    _PR_MISCQ_UNLOCK(pq->thr->cpu);					} else {						pri = pq->thr->priority;						pq->thr->state = _PR_RUNNABLE;						_PR_RUNQ_LOCK(cpu);						_PR_ADD_RUNQ(pq->thr, cpu, pri);						_PR_RUNQ_UNLOCK(cpu);						if (_pr_md_idle_cpus > 1)							_PR_MD_WAKEUP_WAITER(thred);					}                }                _PR_THREAD_UNLOCK(thred);                _PR_IOQ_OSFD_CNT(me->cpu) -= pq->npds;                PR_ASSERT(_PR_IOQ_OSFD_CNT(me->cpu) >= 0);            }        }    } else if (nfd == -1) {        PR_LOG(_pr_io_lm, PR_LOG_MAX, ("poll() failed with errno %d", errno));    }#else    if (nfd > 0) {        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;            _PRUnixPollDesc *pds = pq->pds;            _PRUnixPollDesc *epds = pds + pq->npds;            PRInt32 pq_max_osfd = -1;            q = q->next;            for (; pds < epds; pds++) {                PRInt32 osfd = pds->osfd;                PRInt16 in_flags = pds->in_flags;                PRInt16 out_flags = 0;                PR_ASSERT(osfd >= 0 || in_flags == 0);                if ((in_flags & _PR_UNIX_POLL_READ) && FD_ISSET(osfd, rp)) {                    out_flags |= _PR_UNIX_POLL_READ;                }                if ((in_flags & _PR_UNIX_POLL_WRITE) && FD_ISSET(osfd, wp)) {                    out_flags |= _PR_UNIX_POLL_WRITE;                }                if ((in_flags & _PR_UNIX_POLL_EXCEPT) && FD_ISSET(osfd, ep)) {                    out_flags |= _PR_UNIX_POLL_EXCEPT;                }                pds->out_flags = out_flags;                if (out_flags) {                    notify = PR_TRUE;                }                if (osfd > pq_max_osfd) {                    pq_max_osfd = osfd;                }            }            if (notify == PR_TRUE) {                PRIntn pri;                PRThread *thred;                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_UNIX_POLL_READ) {                        if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0)                            FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu));                    }                    if (in_flags & _PR_UNIX_POLL_WRITE) {                        if (--(_PR_FD_WRITE_CNT(me->cpu))[osfd] == 0)                            FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu));                    }                    if (in_flags & _PR_UNIX_POLL_EXCEPT) {                        if (--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd] == 0)                            FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));                    }                }                /*                 * Because this thread can run on a different cpu right                 * after being added to the run queue, do not dereference                 * pq                 */                 thred = pq->thr;                _PR_THREAD_LOCK(thred);                if (pq->thr->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) {                    _PRCPU *cpu = thred->cpu;                    _PR_SLEEPQ_LOCK(pq->thr->cpu);                    _PR_DEL_SLEEPQ(pq->thr, PR_TRUE);                    _PR_SLEEPQ_UNLOCK(pq->thr->cpu);					if (pq->thr->flags & _PR_SUSPENDING) {					    /*					     * set thread state to SUSPENDED;					     * a Resume operation on the thread					     * will move it to the runQ					     */					    pq->thr->state = _PR_SUSPENDED;					    _PR_MISCQ_LOCK(pq->thr->cpu);					    _PR_ADD_SUSPENDQ(pq->thr, pq->thr->cpu);					    _PR_MISCQ_UNLOCK(pq->thr->cpu);					} else {						pri = pq->thr->priority;						pq->thr->state = _PR_RUNNABLE;						pq->thr->cpu = cpu;						_PR_RUNQ_LOCK(cpu);						_PR_ADD_RUNQ(pq->thr, cpu, pri);						_PR_RUNQ_UNLOCK(cpu);						if (_pr_md_idle_cpus > 1)							_PR_MD_WAKEUP_WAITER(thred);					}                }                _PR_THREAD_UNLOCK(thred);            } else {                if (pq->timeout < _PR_IOQ_TIMEOUT(me->cpu))                    _PR_IOQ_TIMEOUT(me->cpu) = pq->timeout;                if (_PR_IOQ_MAX_OSFD(me->cpu) < pq_max_osfd)                    _PR_IOQ_MAX_OSFD(me->cpu) = pq_max_osfd;            }        }        if (_PR_IS_NATIVE_THREAD_SUPPORTED()) {            if ((FD_ISSET(_pr_md_pipefd[0], rp)) && (nfd == 1)) {                /*             * woken up by another thread; read all the data             * in the pipe to empty the pipe             */                while ((rv =                    read(_pr_md_pipefd[0], _pr_md_pipebuf, PIPE_BUF))                    == PIPE_BUF){                }                PR_ASSERT((rv > 0) ||                    ((rv == -1) && (errno == EAGAIN)));            }            if (_PR_IOQ_MAX_OSFD(me->cpu) < _pr_md_pipefd[0])                _PR_IOQ_MAX_OSFD(me->cpu) = _pr_md_pipefd[0];#ifdef	IRIX			if ((me->cpu->id == 0) && 						(FD_ISSET(_pr_irix_primoridal_cpu_fd[0], rp))) {				if (_pr_irix_process_exit) {					/*					 * process exit due to a call to PR_ProcessExit					 */					prctl(PR_SETEXITSIG, SIGKILL);					_exit(_pr_irix_process_exit_code);				} else {						while ((rv = read(_pr_irix_primoridal_cpu_fd[0],							_pr_md_pipebuf, PIPE_BUF)) == PIPE_BUF) {						}						PR_ASSERT(rv > 0);				}			}			if (me->cpu->id == 0) {				if (_PR_IOQ_MAX_OSFD(me->cpu) < _pr_irix_primoridal_cpu_fd[0])					_PR_IOQ_MAX_OSFD(me->cpu) = _pr_irix_primoridal_cpu_fd[0];			}#endif        }    } else if (nfd < 0) {        if (errno == EBADF) {            FindBadFDs();        } else {            PR_LOG(_pr_io_lm, PR_LOG_MAX, ("select() failed with errno %d",                errno));        }    } else {        PR_ASSERT(nfd == 0);        /*         * compute the new value of _PR_IOQ_TIMEOUT         */        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);            _PRUnixPollDesc *pds = pq->pds;            _PRUnixPollDesc *epds = pds + pq->npds;            PRInt32 pq_max_osfd = -1;            q = q->next;            for (; pds < epds; pds++) {                if (pds->osfd > pq_max_osfd) {                    pq_max_osfd = pds->osfd;                }            }            if (pq->timeout < _PR_IOQ_TIMEOUT(me->cpu))                _PR_IOQ_TIMEOUT(me->cpu) = pq->timeout;            if (_PR_IOQ_MAX_OSFD(me->cpu) < pq_max_osfd)                _PR_IOQ_MAX_OSFD(me->cpu) = pq_max_osfd;        }        if (_PR_IS_NATIVE_THREAD_SUPPORTED()) {            if (_PR_IOQ_MAX_OSFD(me->cpu) < _pr_md_pipefd[0])                _PR_IOQ_MAX_OSFD(me->cpu) = _pr_md_pipefd[0];        }    }#endif  /* _PR_USE_POLL */    _PR_MD_IOQ_UNLOCK();}void _MD_Wakeup_CPUs(){    PRInt32 rv, data;    data = 0;    rv = write(_pr_md_pipefd[1], &data, 1);    while ((rv < 0) && (errno == EAGAIN)) {        /*         * pipe full, read all data in pipe to empty it         */        while ((rv =            read(_pr_md_pipefd[0], _pr_md_pipebuf, PIPE_BUF))            == PIPE_BUF) {        }        PR_ASSERT((rv > 0) ||            ((rv == -1) && (errno == EAGAIN)));        rv = write(_pr_md_pipefd[1], &data, 1);    }}void _MD_InitCPUS(){    PRInt32 rv, flags;    PRThread *me = _MD_CURRENT_THREAD();    rv = pipe(_pr_md_pipefd);    PR_ASSERT(rv == 0);    _PR_IOQ_MAX_OSFD(me->cpu) = _pr_md_pipefd[0];#ifndef _PR_USE_POLL    FD_SET(_pr_md_pipefd[0], &_PR_FD_READ_SET(me->cpu));#endif    flags = fcntl(_pr_md_pipefd[0], F_GETFL, 0);    fcntl(_pr_md_pipefd[0], F_SETFL, flags | O_NONBLOCK);    flags = fcntl(_pr_md_pipefd[1], F_GETFL, 0);    fcntl(_pr_md_pipefd[1], F_SETFL, flags | O_NONBLOCK);}/*** Unix SIGALRM (clock) signal handler*/static void ClockInterruptHandler(){    int olderrno;    PRUintn pri;    _PRCPU *cpu = _PR_MD_CURRENT_CPU();    PRThread *me = _MD_CURRENT_THREAD();#ifdef SOLARIS    if (!me || _PR_IS_NATIVE_THREAD(me)) {        _pr_primordialCPU->u.missed[_pr_primordialCPU->where] |= _PR_MISSED_CLOCK;        return;    }#endif    if (_PR_MD_GET_INTSOFF() != 0) {        cpu->u.missed[cpu->where] |= _PR_MISSED_CLOCK;        return;    }    _PR_MD_SET_INTSOFF(1);    olderrno = errno;    _PR_ClockInterrupt();    errno = olderrno;    /*    ** If the interrupt wants a resched or if some other thread at    ** the same priority needs the cpu, reschedule.    */    pri = me->priority;    if ((cpu->u.missed[3] || (_PR_RUNQREADYMASK(me->cpu) >> pri))) {#ifdef _PR_NO_PREEMPT        cpu->resched = PR_TRUE;        if (pr_interruptSwitchHook) {            (*pr_interruptSwitchHook)(pr_interruptSwitchHookArg);        }#else /* _PR_NO_PREEMPT */        /*    ** Re-enable unix interrupts (so that we can use    ** setjmp/longjmp for context switching without having to    ** worry about the signal state)    */        sigprocmask(SIG_SETMASK, &empty_set, 0);        PR_LOG(_pr_sched_lm, PR_LOG_MIN, ("clock caused context switch"));        if(!(me->flags & _PR_IDLE_THREAD)) {            _PR_THREAD_LOCK(me);            me->state = _PR_RUNNABLE;            me->cpu = cpu;            _PR_RUNQ_LOCK(cpu);            _PR_ADD_RUNQ(me, cpu, pri);            _PR_RUNQ_UNLOCK(cpu);            _PR_THREAD_UNLOCK(me);        } else            me->state = _PR_RUNNABLE;        _MD_SWITCH_CONTEXT(me);        PR_LOG(_pr_sched_lm, PR_LOG_MIN, ("clock back from context switch"));#endif /* _PR_NO_PREEMPT */    }    /*     * Because this thread could be running on a different cpu after     * a context switch the current cpu should be accessed and the     * value of the 'cpu' variable should not be used.     */    _PR_MD_SET_INTSOFF(0);}/* * On HP-UX 9, we have to use the sigvector() interface to restart * interrupted system calls, because sigaction() does not have the * SA_RESTART flag. */#ifdef HPUX9static void HPUX9_ClockInterruptHandler(    int sig,    int code,    struct sigcontext *scp){    ClockInterruptHandler();    scp->sc_syscall_action = SIG_RESTART;}#endif /* HPUX9 *//* # of milliseconds per clock tick that we will use */#define MSEC_PER_TICK    50void _MD_StartInterrupts(){    char *eval;    if ((eval = getenv("NSPR_NOCLOCK")) != NULL) {        if (atoi(eval) == 0)            _nspr_noclock = 0;        else            _nspr_noclock = 1;    }#ifndef _PR_NO_CLOCK_TIMER    if (!_nspr_noclock) {        _MD_EnableClockInterrupts();    }#endif}void _MD_StopInterrupts(){    sigprocmask(SIG_BLOCK, &timer_set, 0);}void _MD_EnableClockInterrupts(){    struct itimerval itval;    extern PRUintn _pr_numCPU;#ifdef HPUX9    struct sigvec vec;    vec.sv_handler = (void (*)()) HPUX9_ClockInterruptHandler;    vec.sv_mask = 0;    vec.sv_flags = 0;    sigvector(SIGALRM, &vec, 0);#else    struct sigaction vtact;    vtact.sa_handler = (void (*)()) ClockInterruptHandler;    sigemptyset(&vtact.sa_mask);    vtact.sa_flags = SA_RESTART;    sigaction(SIGALRM, &vtact, 0);#endif /* HPUX9 */    PR_ASSERT(_pr_numCPU == 1);	itval.it_interval.tv_sec = 0;	itval.it_interval.tv_usec = MSEC_PER_TICK * PR_USEC_PER_MSEC;	itval.it_value = itval.it_interval;	setitimer(ITIMER_REAL, &itval, 0);}void _MD_DisableClockInterrupts(){    struct itimerval itval;    extern PRUintn _pr_numCPU;    PR_ASSERT(_pr_numCPU == 1);	itval.it_interval.tv_sec = 0;	itval.it_interval.tv_usec = 0;	itval.it_value = itval.it_interval;	setitimer(ITIMER_REAL, &itval, 0);}void _MD_BlockClockInterrupts(){    sigprocmask(SIG_BLOCK, &timer_set, 0);}void _MD_UnblockClockInterrupts(){    sigprocmask(SIG_UNBLOCK, &timer_set, 0);}void _MD_MakeNonblock(PRFileDesc *fd){    PRInt32 osfd = fd->secret->md.osfd;    int flags;    if (osfd <= 2) {        /* Don't mess around with stdin, stdout or stderr */        return;    }    flags = fcntl(osfd, F_GETFL, 0);    /*     * Use O_NONBLOCK (POSIX-style non-blocking I/O) whenever possible.     * On SunOS 4, we must use FNDELAY (BSD-style non-blocking I/O),     * otherwise connect() still blocks and can be 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -