20 #include "poll-syscalls.h" 21 #include "net-syscalls.h" 22 #include "pedigree/kernel/compiler.h" 23 #include "pedigree/kernel/utilities/assert.h" 25 #include "modules/system/vfs/Directory.h" 26 #include "modules/system/vfs/File.h" 27 #include "modules/system/vfs/LockedFile.h" 29 #include "modules/system/vfs/Symlink.h" 30 #include "modules/system/vfs/VFS.h" 31 #include "pedigree/kernel/process/Process.h" 32 #include "pedigree/kernel/processor/MemoryRegion.h" 33 #include "pedigree/kernel/processor/PhysicalMemoryManager.h" 34 #include "pedigree/kernel/processor/Processor.h" 35 #include "pedigree/kernel/processor/VirtualAddressSpace.h" 36 #include "pedigree/kernel/processor/types.h" 37 #include "pedigree/kernel/syscallError.h" 38 #include "pedigree/kernel/utilities/Tree.h" 39 #include "pedigree/kernel/utilities/utility.h" 41 #include "modules/subsys/posix/PollEvent.h" 42 #include "pedigree/kernel/Subsystem.h" 43 #include "modules/subsys/posix/FileDescriptor.h" 44 #include "modules/subsys/posix/PosixSubsystem.h" 46 extern void pollEventHandler(uint8_t *pBuffer);
59 int posix_poll(
struct pollfd *fds,
unsigned int nfds,
int timeout)
61 POLL_NOTICE(
"poll(" <<
Dec << nfds <<
", " << timeout <<
Hex <<
")");
63 reinterpret_cast<uintptr_t>(fds), nfds *
sizeof(
struct pollfd),
64 PosixSubsystem::SafeWrite))
66 POLL_NOTICE(
" -> invalid address");
67 SYSCALL_ERROR(InvalidArgument);
72 return posix_poll_safe(fds, nfds, timeout);
75 int posix_poll_safe(
struct pollfd *fds,
unsigned int nfds,
int timeout)
77 POLL_NOTICE(
"poll_safe(" <<
Dec << nfds <<
", " << timeout <<
Hex <<
")");
80 TimeoutType timeoutType;
81 size_t timeoutSecs = timeout / 1000;
82 size_t timeoutUSecs = (timeout % 1000) * 1000;
85 timeoutType = InfiniteTimeout;
92 else if (timeout == 0)
94 timeoutType = ReturnImmediately;
98 timeoutType = SpecificTimeout;
102 timeoutType = ReturnImmediately;
113 ERROR(
"No subsystem for this process!");
117 Thread *pThread =
nullptr;
123 bool bWillReturnImmediately = (timeoutType == ReturnImmediately);
134 for (
unsigned int i = 0; i < nfds; i++)
137 struct pollfd *me = &fds[i];
150 "poll: no such file descriptor (" <<
Dec << me->fd <<
")");
151 me->revents |= POLLNVAL;
156 bool checkWrite =
false;
160 for (
size_t j = 0; j < 2; ++j)
162 short event = POLLIN;
168 if (me->events & event)
176 me->revents |= event;
177 bWillReturnImmediately =
true;
180 else if (!bWillReturnImmediately)
201 me->revents |= event;
202 bWillReturnImmediately =
true;
213 bool checkingWrite = checkWrite;
214 bool checkingRead = !checkWrite;
215 bool checkingError =
false;
217 bool extraCheckingWrite = checkingWrite;
218 bool extraCheckingRead = checkingRead;
219 bool extraCheckingError = checkingError;
222 checkingRead, checkingWrite, checkingError, pSem);
225 bWillReturnImmediately = pollResult;
235 extraCheckingRead, extraCheckingWrite,
236 extraCheckingError,
nullptr);
239 bWillReturnImmediately = pollResult;
243 extraCheckingWrite =
false;
244 extraCheckingRead =
false;
245 extraCheckingError =
false;
248 if (bWillReturnImmediately)
250 if (checkingWrite || extraCheckingWrite)
252 me->revents |= POLLOUT;
255 if (checkingRead || extraCheckingRead)
257 me->revents |= POLLIN;
267 if (me->events & POLLERR)
269 POLL_NOTICE(
" -> POLLERR not yet supported");
275 while (!bWillReturnImmediately && !bError)
277 POLL_NOTICE(
" -> no fds ready yet, poll will block");
285 sem.acquireWithResult(1, timeoutSecs, timeoutUSecs);
288 if (result.hasValue())
299 while (sem.tryAcquire())
308 for (
size_t i = 0; i < nfds; ++i)
310 struct pollfd *me = &fds[i];
319 bool checkingWrite = me->events & POLLOUT;
320 bool checkingRead = me->events & POLLIN;
321 bool checkingError =
false;
324 checkingRead, checkingWrite, checkingError,
nullptr);
326 if (checkingWrite && (me->events & POLLOUT))
328 me->revents |= POLLOUT;
332 if (checkingRead && (me->events & POLLIN))
334 me->revents |= POLLIN;
351 if (result.error() == Semaphore::TimedOut)
354 POLL_NOTICE(
" -> poll interrupted by timeout");
359 POLL_NOTICE(
" -> poll interrupted by external event");
360 SYSCALL_ERROR(Interrupted);
379 for (
auto pEvent : events)
386 pThread->
cullEvent(EventNumbers::PollEvent);
389 for (
auto pEvent : events)
402 for (
size_t i = 0; i < nfds; ++i)
405 " -> pollfd[" << i <<
"]: fd=" << fds[i].fd
406 <<
", events=" << fds[i].events
407 <<
", revents=" << fds[i].revents);
409 if (fds[i].revents != 0)
427 POLL_NOTICE(
" -> " <<
Dec << ((bError) ? -1 : (
int) nRet) <<
Hex);
428 POLL_NOTICE(
" -> nRet is " << nRet <<
", error is " << bError);
430 return (bError) ? -1 : nRet;
void cullEvent(Event *pEvent)
void pushBack(const T &value)
void inhibitEvent(size_t eventNumber, bool bInhibit)
virtual int select(bool bWriting=false, int timeout=0)
void monitor(Thread *pThread, Event *pEvent)
SharedPointer< class NetworkSyscalls > networkImpl
Network syscall implementation for this descriptor (if it's a socket).
bool acquire(bool recurse=false, bool safe=true)
static ProcessorInformation & information()
File * file
Our open file pointer.
void cullMonitorTargets(Thread *pThread)
static bool checkAddress(uintptr_t addr, size_t extent, size_t flags)
Memory-mapped file interface.
Process * getParent() const