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; }
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; }
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; }
/* ** 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() */
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; }
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); }
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; }
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; }
PR_IMPLEMENT(PRInt32) _amigaos_CloseFile(PRInt32 osfd) { PRInt32 rv; rv = close(osfd); if (rv == -1) { _PR_MD_MAP_CLOSE_ERROR(_MD_ERRNO()); } return rv; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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); }
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; }
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 */
/* ** 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() */