Exemple #1
0
PR_IMPLEMENT(PROffset64) _amigaos_LSeek64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence)
{
    PROffset64 rv, where;

    if (offset > 0xffffffff)
    {
	PR_SetError(PR_FILE_TOO_BIG_ERROR, 0);
	return -1;
	}

    switch (whence)
    {
    case PR_SEEK_SET:
	where = SEEK_SET;
        break;
    case PR_SEEK_CUR:
	where = SEEK_CUR;
	break;
    case PR_SEEK_END:
	where = SEEK_END;
	break;
    default:
	PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
	return -1;
    }

    rv = (PROffset64)lseek(fd->secret->md.osfd, (PROffset32)offset, where);

    if (rv == -1)
    {
        _PR_MD_MAP_LSEEK_ERROR(_MD_ERRNO());
    }

    return rv;
}
Exemple #2
0
PR_IMPLEMENT(PRInt32) _amigaos_Access(const char *name, PRAccessHow how)
{
    PRInt32 rv;
    int mode;

    switch (how)
    {
    case PR_ACCESS_WRITE_OK:
	mode = W_OK;
	break;
    case PR_ACCESS_READ_OK:
	mode = R_OK;
	break;
    case PR_ACCESS_EXISTS:
	mode = F_OK;
	break;
     default:
 	PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
        return -1;
    }

    rv = access(name, mode);

    if (rv < 0)
    {
	_PR_MD_MAP_ACCESS_ERROR(_MD_ERRNO());
    }

    return rv;
}
Exemple #3
0
PRStatus
_MD_wait_process (PRProcess *process, PRInt32 *exitCode)
{
	PRStatus retVal = PR_SUCCESS;
	int ret, status;
	
	/* Ignore interruptions */
	do {
		ret = waitpid(process->md.pid, &status, 0);
	} while (ret == -1 && errno == EINTR);

	/*
	 * waitpid() cannot return 0 because we did not invoke it
	 * with the WNOHANG option.
	 */ 
	PR_ASSERT(0 != ret);

	if (ret < 0) {
                PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
		return PR_FAILURE;
	}

	/* If child process exited normally, return child exit code */
	if (WIFEXITED(status)) {
		*exitCode = WEXITSTATUS(status);
	} else {
		PR_ASSERT(WIFSIGNALED(status));
		*exitCode = _PR_SIGNALED_EXITSTATUS;
	}		

	PR_DELETE(process);
	return PR_SUCCESS;
}
Exemple #4
0
/*
** PR_GetNumberOfProcessors()
** 
** Implementation notes:
**   Every platform does it a bit different.
**     numCpus is the returned value.
**   for each platform's "if defined" section
**     declare your local variable
**     do your thing, assign to numCpus
**   order of the if defined()s may be important,
**     especially for unix variants. Do platform
**     specific implementations before XP_UNIX.
** 
*/
PR_IMPLEMENT(PRInt32) PR_GetNumberOfProcessors( void )
{
    PRInt32     numCpus;
#if defined(WIN32)
    SYSTEM_INFO     info;

    GetSystemInfo( &info );
    numCpus = info.dwNumberOfProcessors;
#elif defined(BEOS)
    system_info sysInfo;

    get_system_info(&sysInfo);
    numCpus = sysInfo.cpu_count;
#elif defined(OS2)
    DosQuerySysInfo( QSV_NUMPROCESSORS, QSV_NUMPROCESSORS, &numCpus, sizeof(numCpus));
#elif defined(_PR_HAVE_SYSCTL)
    int mib[2];
    int rc;
    size_t len = sizeof(numCpus);

    mib[0] = CTL_HW;
    mib[1] = HW_NCPU;
    rc = sysctl( mib, 2, &numCpus, &len, NULL, 0 );
    if ( -1 == rc )  {
        numCpus = -1; /* set to -1 for return value on error */
        _PR_MD_MAP_DEFAULT_ERROR( _MD_ERRNO() );
    }
#elif defined(HPUX)
    numCpus = mpctl( MPC_GETNUMSPUS, 0, 0 );
    if ( numCpus < 1 )  {
        numCpus = -1; /* set to -1 for return value on error */
        _PR_MD_MAP_DEFAULT_ERROR( _MD_ERRNO() );
    }
#elif defined(IRIX)
    numCpus = sysconf( _SC_NPROC_ONLN );
#elif defined(RISCOS) || defined(SYMBIAN)
    numCpus = 1;
#elif defined(XP_UNIX)
    numCpus = sysconf( _SC_NPROCESSORS_ONLN );
#else
#error "An implementation is required"
#endif
    return(numCpus);
} /* end PR_GetNumberOfProcessors() */
Exemple #5
0
PRStatus
_PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable)
{
    APIRET rc = 0;
    ULONG flags;
    switch (fd->methods->file_type)
    {
        case PR_DESC_PIPE:
        case PR_DESC_FILE:
            rc = DosQueryFHState((HFILE)fd->secret->md.osfd, &flags);
            if (rc != NO_ERROR) {
                PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
                return PR_FAILURE;
            }

            if (inheritable)
              flags &= ~OPEN_FLAGS_NOINHERIT;
            else
              flags |= OPEN_FLAGS_NOINHERIT;

            /* Mask off flags DosSetFHState don't want. */
            flags &= (OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_NOINHERIT);
            rc = DosSetFHState((HFILE)fd->secret->md.osfd, flags);
            if (rc != NO_ERROR) {
                PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
                return PR_FAILURE;
            }
            break;

        case PR_DESC_LAYERED:
            /* what to do here? */
            PR_SetError(PR_UNKNOWN_ERROR, 87 /*ERROR_INVALID_PARAMETER*/);
            return PR_FAILURE;

        case PR_DESC_SOCKET_TCP:
        case PR_DESC_SOCKET_UDP:
            /* These are global on OS/2. */
            break;
    }

    return PR_SUCCESS;
}
Exemple #6
0
PR_IMPLEMENT(PRInt32) _amigaos_FSync(PRFileDesc *fd)
{
    PRInt32 rv, err;

    rv = fsync(fd->secret->md.osfd);
    if (rv == -1)
    {
        err = _MD_ERRNO();
        _PR_MD_MAP_FSYNC_ERROR(err);
    }
    return(rv);
}
Exemple #7
0
PR_IMPLEMENT(PRInt32) _amigaos_Write(PRFileDesc *fd, const void *buffer, PRInt32 len)
{
    PRInt32 rv;

    rv = write(fd->secret->md.osfd, buffer, (size_t)len);

    if (rv < 0)
    {
	_PR_MD_MAP_WRITE_ERROR(_MD_ERRNO());
    }

    return (PRInt32)rv;
}
Exemple #8
0
PR_IMPLEMENT(PRInt32) _amigaos_Read(PRFileDesc *fd, void *buffer, PRInt32 len)
{
    PRInt32 rv;

    rv = (PRInt32)read(fd->secret->md.osfd, buffer, (size_t)len);

    if (rv < 0)
    {
	_PR_MD_MAP_READ_ERROR(_MD_ERRNO());
    }

    return (PRInt32)rv;
}
Exemple #9
0
PR_IMPLEMENT(PRInt32) _amigaos_CloseFile(PRInt32 osfd)
{
    PRInt32 rv;

    rv = close(osfd);

    if (rv == -1)
    {
	_PR_MD_MAP_CLOSE_ERROR(_MD_ERRNO());
    }

    return rv;
}
Exemple #10
0
PR_IMPLEMENT(PRInt32) _amigaos_Stat(const char *name, struct stat *sb)
{
    PRInt32 rv;

    rv = stat(name, sb);

    if (rv < 0)
    {
	_PR_MD_MAP_STAT_ERROR(_MD_ERRNO());
    }

    return rv;
}
Exemple #11
0
PR_IMPLEMENT(PRInt32) _amigaos_Delete(const char *name)
{
    PRInt32 rv;

    rv = unlink(name);

    if (rv < 0)
    {
	_PR_MD_MAP_UNLINK_ERROR(_MD_ERRNO());
    }

    return rv;
}
Exemple #12
0
PR_IMPLEMENT(PRInt32) _amigaos_Getopenfileinfo64(const PRFileDesc *fd, PRFileInfo64 *info)
{
    struct stat sb;
    PRInt32 rv;

    rv = fstat(fd->secret->md.osfd, &sb);

    if (rv < 0)
    {
        _PR_MD_MAP_FSTAT_ERROR(_MD_ERRNO());
    }
    else if (NULL != info)
    {
        rv = _amigaos_convert_stat_to_fileinfo64(&sb, info);
    }
    return rv;
}
Exemple #13
0
PR_IMPLEMENT(PRInt32) _amigaos_Getfileinfo64(const char *fn, PRFileInfo64 *info)
{
    PRInt32 rv;
    struct stat sb;

    rv = stat(fn, &sb);

    if (rv < 0)
    {
        _PR_MD_MAP_STAT_ERROR(_MD_ERRNO());
    }
    else if (NULL != info)
    {
        rv = _amigaos_convert_stat_to_fileinfo64(&sb, info);
    }
    return rv;
}
Exemple #14
0
PR_IMPLEMENT(PRStatus) _amigaos_UnlockFile(PRInt32 f)
{
    // TODO: same doubts as the above two. - HJF -
    PRInt32 rv;
    struct flock arg;

    arg.l_type = F_UNLCK;
    arg.l_whence = SEEK_SET;
    arg.l_start = 0;
    arg.l_len = 0;  /* until EOF */

    rv = fcntl(f, F_SETLK, &arg);
    if (rv == 0)
	return PR_SUCCESS;

    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
    return PR_FAILURE;
}
Exemple #15
0
PR_IMPLEMENT(PRInt32) _amigaos_Rename(const char *from, const char *to)
{
    PRInt32 rv;

    if (access(to, F_OK) == 0)
    {
	PR_SetError(PR_FILE_EXISTS_ERROR, 0);
	return -1;
    }

    rv = rename(from, to);
    if (rv < 0)
    {
	_PR_MD_MAP_RENAME_ERROR(_MD_ERRNO());
    }

    return rv;
}
Exemple #16
0
PR_IMPLEMENT(PRStatus) _amigaos_TLockFile(PRInt32 f)
{
    // TODO: I have my doubts this works (see above)   - HJF -
    PRInt32 rv;
    struct flock arg;

    arg.l_type = F_WRLCK;
    arg.l_whence = SEEK_SET;
    arg.l_start = 0;
    arg.l_len = 0;  /* until EOF */

    rv = fcntl(f, F_SETLK, &arg);
    if (rv == 0)
	return PR_SUCCESS;

    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
    return PR_FAILURE;
}
Exemple #17
0
PR_IMPLEMENT(PRInt32) _amigaos_Open(const char *name, PRIntn flags, PRIntn mode)
{
    PRInt32 osflags;
    PRInt32 rv;

    if (flags & PR_RDWR)
    {
    	osflags = O_RDWR;
    }
    else if (flags & PR_WRONLY)
    {
    	osflags = O_WRONLY;
    }
    else
    {
    	osflags = O_RDONLY;
    }

    if (flags & PR_EXCL)
	osflags |= O_EXCL;

    if (flags & PR_APPEND)
	osflags |= O_APPEND;

    if (flags & PR_TRUNCATE)
	osflags |= O_TRUNC;

    if (flags & PR_SYNC)
	osflags |= O_SYNC;

    if (flags & PR_CREATE_FILE)
	osflags |= O_CREAT;

    rv = open(name, osflags, mode);

    if (rv < 0)
    {
	_PR_MD_MAP_OPEN_ERROR(_MD_ERRNO());
    }

    return rv;
}
Exemple #18
0
void _PR_InitLinker(void)
{
    PRLibrary *lm = NULL;
#if defined(XP_UNIX) || defined(XP_AMIGAOS)
    void *h;
#endif

    if (!pr_linker_lock) {
        pr_linker_lock = PR_NewNamedMonitor("linker-lock");
    }
    PR_EnterMonitor(pr_linker_lock);

#if defined(XP_PC)
    lm = PR_NEWZAP(PRLibrary);
    lm->name = strdup("Executable");
#if defined(XP_OS2)
    lm->dlh = NULLHANDLE;
#else
    /* A module handle for the executable. */
    lm->dlh = GetModuleHandle(NULL);
#endif /* ! XP_OS2 */

    lm->refCount    = 1;
    lm->staticTable = NULL;
    pr_exe_loadmap  = lm;
    pr_loadmap      = lm;

#elif defined(XP_UNIX) || defined(XP_AMIGAOS)
#ifdef HAVE_DLL
#if defined(USE_DLFCN) && !defined(NO_DLOPEN_NULL)
    h = dlopen(0, RTLD_LAZY);
    if (!h) {
        char *error;

        DLLErrorInternal(_MD_ERRNO());
        error = (char*)PR_MALLOC(PR_GetErrorTextLength());
        (void) PR_GetErrorText(error);
        fprintf(stderr, "failed to initialize shared libraries [%s]\n",
            error);
        PR_DELETE(error);
        abort();/* XXX */
    }
#elif defined(USE_HPSHL)
    h = NULL;
    /* don't abort with this NULL */
#elif defined(USE_MACH_DYLD) || defined(NO_DLOPEN_NULL)
    h = NULL; /* XXXX  toshok */ /* XXXX  vlad */
#else
#error no dll strategy
#endif /* USE_DLFCN */

    lm = PR_NEWZAP(PRLibrary);
    if (lm) {
        lm->name = strdup("a.out");
        lm->refCount = 1;
        lm->dlh = h;
        lm->staticTable = NULL;
    }
    pr_exe_loadmap = lm;
    pr_loadmap = lm;
#endif /* HAVE_DLL */
#endif /* XP_UNIX */

    if (lm) {
        PR_LOG(_pr_linker_lm, PR_LOG_MIN,
            ("Loaded library %s (init)", lm->name));
    }

    PR_ExitMonitor(pr_linker_lock);
}
Exemple #19
0
PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
{
#ifdef BSD_SELECT
    fd_set rd, wt, ex;
#else
    int rd, wt, ex;
    int* socks;
    unsigned long msecs;
    int i, j;
#endif
    PRFileDesc *bottom;
    PRPollDesc *pd, *epd;
    PRInt32 maxfd = -1, ready, err;
    PRIntervalTime remaining, elapsed, start;

#ifdef BSD_SELECT
    struct timeval tv, *tvp = NULL;

    FD_ZERO(&rd);
    FD_ZERO(&wt);
    FD_ZERO(&ex);
#else
    rd = 0;
    wt = 0;
    ex = 0;
    socks = (int) PR_MALLOC( npds * 3 * sizeof(int) );
    
    if (!socks)
    {
        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
        return -1;
    }
#endif

    ready = 0;
    for (pd = pds, epd = pd + npds; pd < epd; pd++)
    {
        PRInt16 in_flags_read = 0, in_flags_write = 0;
        PRInt16 out_flags_read = 0, out_flags_write = 0;

        if ((NULL != pd->fd) && (0 != pd->in_flags))
        {
            if (pd->in_flags & PR_POLL_READ)
            {
                in_flags_read = (pd->fd->methods->poll)(
                    pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read);
            }
            if (pd->in_flags & PR_POLL_WRITE)
            {
                in_flags_write = (pd->fd->methods->poll)(
                    pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write);
            }
            if ((0 != (in_flags_read & out_flags_read)) ||
                (0 != (in_flags_write & out_flags_write)))
            {
                /* this one's ready right now */
                if (0 == ready)
                {
                    /*
                     * We will have to return without calling the
                     * system poll/select function.  So zero the
                     * out_flags fields of all the poll descriptors
                     * before this one.
                     */
                    PRPollDesc *prev;
                    for (prev = pds; prev < pd; prev++)
                    {
                        prev->out_flags = 0;
                    }
                }
                ready += 1;
                pd->out_flags = out_flags_read | out_flags_write;
            }
            else
            {
                pd->out_flags = 0;  /* pre-condition */

                /* make sure this is an NSPR supported stack */
                bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
                PR_ASSERT(NULL != bottom);  /* what to do about that? */
                if ((NULL != bottom) &&
                    (_PR_FILEDESC_OPEN == bottom->secret->state))
                {
                    if (0 == ready)
                    {
                        PRInt32 osfd = bottom->secret->md.osfd;
                        if (osfd > maxfd) 
                            maxfd = osfd;
                        if (in_flags_read & PR_POLL_READ)
                        {
                            pd->out_flags |= _PR_POLL_READ_SYS_READ;
#ifdef BSD_SELECT
                            FD_SET(osfd, &rd);
#else
                            socks[rd] = osfd;
                            rd++;              
#endif
                        }
                        if (in_flags_read & PR_POLL_WRITE)
                        {
                            pd->out_flags |= _PR_POLL_READ_SYS_WRITE;
#ifdef BSD_SELECT
                            FD_SET(osfd, &wt);
#else
                            socks[npds+wt] = osfd;
                            wt++;              
#endif
                        }
                        if (in_flags_write & PR_POLL_READ)
                        {
                            pd->out_flags |= _PR_POLL_WRITE_SYS_READ;
#ifdef BSD_SELECT
                            FD_SET(osfd, &rd);
#else
                            socks[rd] = osfd;
                            rd++;              
#endif
                        }
                        if (in_flags_write & PR_POLL_WRITE)
                        {
                            pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE;
#ifdef BSD_SELECT
                            FD_SET(osfd, &wt);
#else
                            socks[npds+wt] = osfd;
                            wt++;              
#endif
                        }
                        if (pd->in_flags & PR_POLL_EXCEPT)
                        {
#ifdef BSD_SELECT
                            FD_SET(osfd, &ex);
#else
                            socks[npds*2+ex] = osfd;
                            ex++;
#endif
                        }
                    }
                }
                else
                {
                    if (0 == ready)
                    {
                        PRPollDesc *prev;
                        for (prev = pds; prev < pd; prev++)
                        {
                            prev->out_flags = 0;
                        }
                    }
                    ready += 1;  /* this will cause an abrupt return */
                    pd->out_flags = PR_POLL_NVAL;  /* bogii */
                }
            }
        }
        else
        {
            pd->out_flags = 0;
        }
    }

    if (0 != ready)
    {
#ifndef BSD_SELECT
        PR_Free(socks);
#endif
        return ready;  /* no need to block */
    }

    remaining = timeout;
    start = PR_IntervalNow();

retry:
#ifdef BSD_SELECT
    if (timeout != PR_INTERVAL_NO_TIMEOUT)
    {
        PRInt32 ticksPerSecond = PR_TicksPerSecond();
        tv.tv_sec = remaining / ticksPerSecond;
        tv.tv_usec = PR_IntervalToMicroseconds( remaining % ticksPerSecond );
        tvp = &tv;
    }

    ready = bsdselect(maxfd + 1, &rd, &wt, &ex, tvp);
#else
    switch (timeout)
    {
        case PR_INTERVAL_NO_WAIT:
            msecs = 0;
            break;
        case PR_INTERVAL_NO_TIMEOUT:
            msecs = -1;
            break;
        default:
            msecs = PR_IntervalToMilliseconds(remaining);
    }

     /* compact array */
    for( i = rd, j = npds; j < npds+wt; i++,j++ )
        socks[i] = socks[j];
    for( i = rd+wt, j = npds*2; j < npds*2+ex; i++,j++ )
        socks[i] = socks[j];
    
    ready = os2_select(socks, rd, wt, ex, msecs);
#endif

    if (ready == -1 && errno == EINTR)
    {
        if (timeout == PR_INTERVAL_NO_TIMEOUT)
            goto retry;
        else
        {
            elapsed = (PRIntervalTime) (PR_IntervalNow() - start);
            if (elapsed > timeout)
                ready = 0;  /* timed out */
            else
            {
                remaining = timeout - elapsed;
                goto retry;
            }
        }
    }

    /*
    ** Now to unravel the select sets back into the client's poll
    ** descriptor list. Is this possibly an area for pissing away
    ** a few cycles or what?
    */
    if (ready > 0)
    {
        ready = 0;
        for (pd = pds, epd = pd + npds; pd < epd; pd++)
        {
            PRInt16 out_flags = 0;
            if ((NULL != pd->fd) && (0 != pd->in_flags))
            {
                PRInt32 osfd;
                bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
                PR_ASSERT(NULL != bottom);

                osfd = bottom->secret->md.osfd;

#ifdef BSD_SELECT
                if (FD_ISSET(osfd, &rd))
#else
                if( IsSocketSet(osfd, socks, 0, rd) )        
#endif
                {
                    if (pd->out_flags & _PR_POLL_READ_SYS_READ)
                        out_flags |= PR_POLL_READ;
                    if (pd->out_flags & _PR_POLL_WRITE_SYS_READ)
                        out_flags |= PR_POLL_WRITE;
                } 

#ifdef BSD_SELECT
                if (FD_ISSET(osfd, &wt))
#else
                if( IsSocketSet(osfd, socks, rd, wt) )        
#endif
                {
                    if (pd->out_flags & _PR_POLL_READ_SYS_WRITE)
                        out_flags |= PR_POLL_READ;
                    if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE)
                        out_flags |= PR_POLL_WRITE;
                } 

#ifdef BSD_SELECT
                if (FD_ISSET(osfd, &ex))
#else
                if( IsSocketSet(osfd, socks, rd+wt, ex) )        
#endif
                {
                    out_flags |= PR_POLL_EXCEPT;
                }
            }
            pd->out_flags = out_flags;
            if (out_flags) ready++;
        }
        PR_ASSERT(ready > 0);
    }
    else if (ready < 0)
    {
        err = _MD_ERRNO();
        if (err == EBADF)
        {
            /* Find the bad fds */
            int optval;
            int optlen = sizeof(optval);
            ready = 0;
            for (pd = pds, epd = pd + npds; pd < epd; pd++)
            {
                pd->out_flags = 0;
                if ((NULL != pd->fd) && (0 != pd->in_flags))
                {
                    bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
                    if (getsockopt(bottom->secret->md.osfd, SOL_SOCKET,
                        SO_TYPE, (char *) &optval, &optlen) == -1)
                    {
                        PR_ASSERT(sock_errno() == ENOTSOCK);
                        if (sock_errno() == ENOTSOCK)
                        {
                            pd->out_flags = PR_POLL_NVAL;
                            ready++;
                        }
                    }
                }
            }
            PR_ASSERT(ready > 0);
        }
        else
            _PR_MD_MAP_SELECT_ERROR(err);
    }

#ifndef BSD_SELECT
    PR_Free(socks);
#endif
    return ready;
}
Exemple #20
0
static PRInt32 NativeThreadSelect(
    PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
{
    /*
     * This code is almost a duplicate of w32poll.c's _PR_MD_PR_POLL().
     */
    fd_set rd, wt, ex;
    PRFileDesc *bottom;
    PRPollDesc *pd, *epd;
    PRInt32 maxfd = -1, ready, err;
    PRIntervalTime remaining, elapsed, start;

    struct timeval tv, *tvp = NULL;

    FD_ZERO(&rd);
    FD_ZERO(&wt);
    FD_ZERO(&ex);

    ready = 0;
    for (pd = pds, epd = pd + npds; pd < epd; pd++)
    {
        PRInt16 in_flags_read = 0, in_flags_write = 0;
        PRInt16 out_flags_read = 0, out_flags_write = 0;

        if ((NULL != pd->fd) && (0 != pd->in_flags))
        {
            if (pd->in_flags & PR_POLL_READ)
            {
                in_flags_read = (pd->fd->methods->poll)(
                    pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read);
            }
            if (pd->in_flags & PR_POLL_WRITE)
            {
                in_flags_write = (pd->fd->methods->poll)(
                    pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write);
            }
            if ((0 != (in_flags_read & out_flags_read))
            || (0 != (in_flags_write & out_flags_write)))
            {
                /* this one's ready right now */
                if (0 == ready)
                {
                    /*
                     * We will have to return without calling the
                     * system poll/select function.  So zero the
                     * out_flags fields of all the poll descriptors
                     * before this one.
                     */
                    PRPollDesc *prev;
                    for (prev = pds; prev < pd; prev++)
                    {
                        prev->out_flags = 0;
                    }
                }
                ready += 1;
                pd->out_flags = out_flags_read | out_flags_write;
            }
            else
            {
                pd->out_flags = 0;  /* pre-condition */

                /* make sure this is an NSPR supported stack */
                bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
                PR_ASSERT(NULL != bottom);  /* what to do about that? */
                if ((NULL != bottom)
                && (_PR_FILEDESC_OPEN == bottom->secret->state))
                {
                    if (0 == ready)
                    {
                        PRInt32 osfd = bottom->secret->md.osfd;
                        if (osfd > maxfd) maxfd = osfd;
                        if (in_flags_read & PR_POLL_READ)
                        {
                            pd->out_flags |= _PR_POLL_READ_SYS_READ;
                            FD_SET(osfd, &rd);
                        }
                        if (in_flags_read & PR_POLL_WRITE)
                        {
                            pd->out_flags |= _PR_POLL_READ_SYS_WRITE;
                            FD_SET(osfd, &wt);
                        }
                        if (in_flags_write & PR_POLL_READ)
                        {
                            pd->out_flags |= _PR_POLL_WRITE_SYS_READ;
                            FD_SET(osfd, &rd);
                        }
                        if (in_flags_write & PR_POLL_WRITE)
                        {
                            pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE;
                            FD_SET(osfd, &wt);
                        }
                        if (pd->in_flags & PR_POLL_EXCEPT) FD_SET(osfd, &ex);
                    }
                }
                else
                {
                    if (0 == ready)
                    {
                        PRPollDesc *prev;
                        for (prev = pds; prev < pd; prev++)
                        {
                            prev->out_flags = 0;
                        }
                    }
                    ready += 1;  /* this will cause an abrupt return */
                    pd->out_flags = PR_POLL_NVAL;  /* bogii */
                }
            }
        }
        else
        {
            pd->out_flags = 0;
        }
    }

    if (0 != ready) return ready;  /* no need to block */

    remaining = timeout;
    start = PR_IntervalNow();

retry:
    if (timeout != PR_INTERVAL_NO_TIMEOUT)
    {
        PRInt32 ticksPerSecond = PR_TicksPerSecond();
        tv.tv_sec = remaining / ticksPerSecond;
        tv.tv_usec = PR_IntervalToMicroseconds( remaining % ticksPerSecond );
        tvp = &tv;
    }

    ready = _MD_SELECT(maxfd + 1, &rd, &wt, &ex, tvp);

    if (ready == -1 && errno == EINTR)
    {
        if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry;
        else
        {
            elapsed = (PRIntervalTime) (PR_IntervalNow() - start);
            if (elapsed > timeout) ready = 0;  /* timed out */
            else
            {
                remaining = timeout - elapsed;
                goto retry;
            }
        }
    }

    /*
    ** Now to unravel the select sets back into the client's poll
    ** descriptor list. Is this possibly an area for pissing away
    ** a few cycles or what?
    */
    if (ready > 0)
    {
        ready = 0;
        for (pd = pds, epd = pd + npds; pd < epd; pd++)
        {
            PRInt16 out_flags = 0;
            if ((NULL != pd->fd) && (0 != pd->in_flags))
            {
                PRInt32 osfd;
                bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
                PR_ASSERT(NULL != bottom);

                osfd = bottom->secret->md.osfd;

                if (FD_ISSET(osfd, &rd))
                {
                    if (pd->out_flags & _PR_POLL_READ_SYS_READ)
                        out_flags |= PR_POLL_READ;
                    if (pd->out_flags & _PR_POLL_WRITE_SYS_READ)
                        out_flags |= PR_POLL_WRITE;
                } 
                if (FD_ISSET(osfd, &wt))
                {
                    if (pd->out_flags & _PR_POLL_READ_SYS_WRITE)
                        out_flags |= PR_POLL_READ;
                    if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE)
                        out_flags |= PR_POLL_WRITE;
                } 
                if (FD_ISSET(osfd, &ex)) out_flags |= PR_POLL_EXCEPT;
            }
            pd->out_flags = out_flags;
            if (out_flags) ready++;
        }
        PR_ASSERT(ready > 0);
    }
    else if (ready < 0)
    {
        err = _MD_ERRNO();
        if (err == EBADF)
        {
            /* Find the bad fds */
            ready = 0;
            for (pd = pds, epd = pd + npds; pd < epd; pd++)
            {
                pd->out_flags = 0;
                if ((NULL != pd->fd) && (0 != pd->in_flags))
                {
                    bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
                    if (fcntl(bottom->secret->md.osfd, F_GETFL, 0) == -1)
                    {
                        pd->out_flags = PR_POLL_NVAL;
                        ready++;
                    }
                }
            }
            PR_ASSERT(ready > 0);
        }
        else _PR_MD_MAP_SELECT_ERROR(err);
    }

    return ready;
}  /* NativeThreadSelect */
Exemple #21
0
/*
** PR_GetNumberOfProcessors()
** 
** Implementation notes:
**   Every platform does it a bit different.
**     numCpus is the returned value.
**   for each platform's "if defined" section
**     declare your local variable
**     do your thing, assign to numCpus
**   order of the if defined()s may be important,
**     especially for unix variants. Do platform
**     specific implementations before XP_UNIX.
** 
*/
PR_IMPLEMENT(PRInt32) PR_GetNumberOfProcessors( void )
{
    PRInt32     numCpus;
#if defined(WIN32)
    SYSTEM_INFO     info;

    GetSystemInfo( &info );
    numCpus = info.dwNumberOfProcessors;
#elif defined(BEOS)
    system_info sysInfo;

    get_system_info(&sysInfo);
    numCpus = sysInfo.cpu_count;
#elif defined(OS2)
    DosQuerySysInfo( QSV_NUMPROCESSORS, QSV_NUMPROCESSORS, &numCpus, sizeof(numCpus));
#elif defined(_PR_HAVE_SYSCTL)
    int mib[2];
    int rc;
    size_t len = sizeof(numCpus);

    mib[0] = CTL_HW;
    mib[1] = HW_NCPU;
    rc = sysctl( mib, 2, &numCpus, &len, NULL, 0 );
    if ( -1 == rc )  {
        numCpus = -1; /* set to -1 for return value on error */
        _PR_MD_MAP_DEFAULT_ERROR( _MD_ERRNO() );
    }
#elif defined(HPUX)
    numCpus = mpctl( MPC_GETNUMSPUS, 0, 0 );
    if ( numCpus < 1 )  {
        numCpus = -1; /* set to -1 for return value on error */
        _PR_MD_MAP_DEFAULT_ERROR( _MD_ERRNO() );
    }
#elif defined(IRIX)
    numCpus = sysconf( _SC_NPROC_ONLN );
#elif defined(RISCOS) || defined(SYMBIAN)
    numCpus = 1;
#elif defined(LINUX)
    /* for the benefit of devices with advanced power-saving, that
       actually hotplug their cpus in heavy load, try to figure out
       the real number of CPUs */
    char buf[MAX_LINE];
    FILE *fin;
    const char *cpu_present = "/sys/devices/system/cpu/present";
    size_t strsize;
    numCpus = 0;
    fin = fopen(cpu_present, "r");
    if (fin != NULL) {
        if (fgets(buf, MAX_LINE, fin) != NULL) {
            /* check that the format is what we expect */
            if (buf[0] == '0') {
                strsize = strlen(buf);
                if (strsize == 1) {
                    /* single core */
                    numCpus = 1;
                } else if (strsize >= 3 && strsize <= 5) {
                    /* should be of the form 0-999 */
                    /* parse the part after the 0-, note count is 0-based */
                    if (buf[1] == '-' && isdigit(buf[2])) {
                        numCpus = 1 + atoi(buf + 2);
                    }
                }
            }
        }
        fclose(fin);
    }
    /* if that fails, fall back to more standard methods */
    if (!numCpus) {
        numCpus = sysconf( _SC_NPROCESSORS_CONF );
    }
#elif defined(XP_UNIX)
    numCpus = sysconf( _SC_NPROCESSORS_CONF );
#else
#error "An implementation is required"
#endif
    return(numCpus);
} /* end PR_GetNumberOfProcessors() */