mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 21:57:35 +00:00
Kernel: Tidy up sys$select() to make it more readable.
This commit is contained in:
parent
6e4f0b3cc5
commit
bf905225e7
2 changed files with 45 additions and 73 deletions
|
@ -1294,10 +1294,17 @@ int Process::sys$sleep(unsigned seconds)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void kgettimeofday(timeval& tv)
|
timeval kgettimeofday()
|
||||||
{
|
{
|
||||||
|
timeval tv;
|
||||||
tv.tv_sec = RTC::boot_time() + PIT::seconds_since_boot();
|
tv.tv_sec = RTC::boot_time() + PIT::seconds_since_boot();
|
||||||
tv.tv_usec = PIT::ticks_this_second() * 1000;
|
tv.tv_usec = PIT::ticks_this_second() * 1000;
|
||||||
|
return tv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void kgettimeofday(timeval& tv)
|
||||||
|
{
|
||||||
|
tv = kgettimeofday();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Process::sys$gettimeofday(timeval* tv)
|
int Process::sys$gettimeofday(timeval* tv)
|
||||||
|
@ -1744,106 +1751,72 @@ clock_t Process::sys$times(tms* times)
|
||||||
|
|
||||||
int Process::sys$select(const Syscall::SC_select_params* params)
|
int Process::sys$select(const Syscall::SC_select_params* params)
|
||||||
{
|
{
|
||||||
|
// FIXME: Return -EINTR if a signal is caught.
|
||||||
|
// FIXME: Return -EINVAL if timeout is invalid.
|
||||||
if (!validate_read_typed(params))
|
if (!validate_read_typed(params))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (params->writefds && !validate_read_typed(params->writefds))
|
if (params->writefds && !validate_write_typed(params->writefds))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (params->readfds && !validate_read_typed(params->readfds))
|
if (params->readfds && !validate_write_typed(params->readfds))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (params->exceptfds && !validate_read_typed(params->exceptfds))
|
if (params->exceptfds && !validate_write_typed(params->exceptfds))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (params->timeout && !validate_read_typed(params->timeout))
|
if (params->timeout && !validate_read_typed(params->timeout))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
int nfds = params->nfds;
|
if (params->nfds < 0)
|
||||||
fd_set* writefds = params->writefds;
|
return -EINVAL;
|
||||||
fd_set* readfds = params->readfds;
|
|
||||||
fd_set* exceptfds = params->exceptfds;
|
|
||||||
auto* timeout = params->timeout;
|
|
||||||
|
|
||||||
// FIXME: Implement exceptfds support.
|
if (params->timeout && (params->timeout->tv_sec || params->timeout->tv_usec)) {
|
||||||
(void)exceptfds;
|
auto now = kgettimeofday();
|
||||||
|
AK::timeval_add(&now, params->timeout, ¤t->m_select_timeout);
|
||||||
if (timeout && (timeout->tv_sec || timeout->tv_usec)) {
|
|
||||||
struct timeval now;
|
|
||||||
kgettimeofday(now);
|
|
||||||
AK::timeval_add(&now, timeout, ¤t->m_select_timeout);
|
|
||||||
current->m_select_has_timeout = true;
|
current->m_select_has_timeout = true;
|
||||||
} else {
|
} else {
|
||||||
current->m_select_has_timeout = false;
|
current->m_select_has_timeout = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nfds < 0)
|
auto transfer_fds = [&] (auto* fds, auto& vector) -> int {
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
// FIXME: Return -EINTR if a signal is caught.
|
|
||||||
// FIXME: Return -EINVAL if timeout is invalid.
|
|
||||||
|
|
||||||
auto transfer_fds = [this, nfds] (fd_set* set, auto& vector) -> int {
|
|
||||||
vector.clear_with_capacity();
|
vector.clear_with_capacity();
|
||||||
if (!set)
|
if (!fds)
|
||||||
return 0;
|
return 0;
|
||||||
auto bitmap = Bitmap::wrap((byte*)set, FD_SETSIZE);
|
for (int fd = 0; fd < params->nfds; ++fd) {
|
||||||
for (int i = 0; i < nfds; ++i) {
|
if (FD_ISSET(fd, fds)) {
|
||||||
if (bitmap.get(i)) {
|
if (!file_descriptor(fd))
|
||||||
if (!file_descriptor(i))
|
|
||||||
return -EBADF;
|
return -EBADF;
|
||||||
vector.append(i);
|
vector.append(fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
if (int error = transfer_fds(params->writefds, current->m_select_write_fds))
|
||||||
int error = 0;
|
|
||||||
error = transfer_fds(writefds, current->m_select_write_fds);
|
|
||||||
if (error)
|
|
||||||
return error;
|
return error;
|
||||||
error = transfer_fds(readfds, current->m_select_read_fds);
|
if (int error = transfer_fds(params->readfds, current->m_select_read_fds))
|
||||||
if (error)
|
|
||||||
return error;
|
return error;
|
||||||
error = transfer_fds(exceptfds, current->m_select_exceptional_fds);
|
if (int error = transfer_fds(params->exceptfds, current->m_select_exceptional_fds))
|
||||||
if (error)
|
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
#if defined(DEBUG_IO) || defined(DEBUG_POLL_SELECT)
|
#if defined(DEBUG_IO) || defined(DEBUG_POLL_SELECT)
|
||||||
dbgprintf("%s<%u> selecting on (read:%u, write:%u), timeout=%p\n", name().characters(), pid(), current->m_select_read_fds.size(), current->m_select_write_fds.size(), timeout);
|
dbgprintf("%s<%u> selecting on (read:%u, write:%u), timeout=%p\n", name().characters(), pid(), current->m_select_read_fds.size(), current->m_select_write_fds.size(), params->timeout);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!timeout || current->m_select_has_timeout)
|
if (!params->timeout || current->m_select_has_timeout)
|
||||||
current->block(Thread::State::BlockedSelect);
|
current->block(Thread::State::BlockedSelect);
|
||||||
|
|
||||||
int markedfds = 0;
|
int marked_fd_count = 0;
|
||||||
|
auto mark_fds = [&] (auto* fds, auto& vector, auto should_mark) {
|
||||||
if (readfds) {
|
if (!fds)
|
||||||
memset(readfds, 0, sizeof(fd_set));
|
return;
|
||||||
auto bitmap = Bitmap::wrap((byte*)readfds, FD_SETSIZE);
|
FD_ZERO(fds);
|
||||||
for (int fd : current->m_select_read_fds) {
|
for (int fd : vector) {
|
||||||
auto* descriptor = file_descriptor(fd);
|
if (auto* descriptor = file_descriptor(fd); descriptor && should_mark(*descriptor)) {
|
||||||
if (!descriptor)
|
FD_SET(fd, fds);
|
||||||
continue;
|
++marked_fd_count;
|
||||||
if (descriptor->can_read()) {
|
|
||||||
bitmap.set(fd, true);
|
|
||||||
++markedfds;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
mark_fds(params->readfds, current->m_select_read_fds, [] (auto& descriptor) { return descriptor.can_read(); });
|
||||||
if (writefds) {
|
mark_fds(params->writefds, current->m_select_write_fds, [] (auto& descriptor) { return descriptor.can_write(); });
|
||||||
memset(writefds, 0, sizeof(fd_set));
|
// FIXME: We should also mark params->exceptfds as appropriate.
|
||||||
auto bitmap = Bitmap::wrap((byte*)writefds, FD_SETSIZE);
|
return marked_fd_count;
|
||||||
for (int fd : current->m_select_write_fds) {
|
|
||||||
auto* descriptor = file_descriptor(fd);
|
|
||||||
if (!descriptor)
|
|
||||||
continue;
|
|
||||||
if (descriptor->can_write()) {
|
|
||||||
bitmap.set(fd, true);
|
|
||||||
++markedfds;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: Check for exceptional conditions.
|
|
||||||
|
|
||||||
return markedfds;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Process::sys$poll(pollfd* fds, int nfds, int timeout)
|
int Process::sys$poll(pollfd* fds, int nfds, int timeout)
|
||||||
|
@ -1869,9 +1842,7 @@ int Process::sys$poll(pollfd* fds, int nfds, int timeout)
|
||||||
timeout -= 1000;
|
timeout -= 1000;
|
||||||
}
|
}
|
||||||
tvtimeout.tv_usec = timeout * 1000;
|
tvtimeout.tv_usec = timeout * 1000;
|
||||||
|
auto now = kgettimeofday();
|
||||||
struct timeval now;
|
|
||||||
kgettimeofday(now);
|
|
||||||
AK::timeval_add(&now, &tvtimeout, ¤t->m_select_timeout);
|
AK::timeval_add(&now, &tvtimeout, ¤t->m_select_timeout);
|
||||||
current->m_select_has_timeout = true;
|
current->m_select_has_timeout = true;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -22,6 +22,7 @@ class Region;
|
||||||
class VMObject;
|
class VMObject;
|
||||||
class ProcessTracer;
|
class ProcessTracer;
|
||||||
|
|
||||||
|
timeval kgettimeofday();
|
||||||
void kgettimeofday(timeval&);
|
void kgettimeofday(timeval&);
|
||||||
|
|
||||||
class Process : public InlineLinkedListNode<Process>
|
class Process : public InlineLinkedListNode<Process>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue