#endif
#include <fcntl.h>
-#include <signal.h>
#include <unistd.h>
-#include "sim/async.hh"
-#include "sim/host.hh"
+#include <csignal>
+
#include "base/misc.hh"
#include "base/pollevent.hh"
-#include "sim/root.hh"
+#include "base/types.hh"
+#include "sim/async.hh"
+#include "sim/core.hh"
+#include "sim/eventq.hh"
#include "sim/serialize.hh"
using namespace std;
{
pfd.fd = _fd;
pfd.events = _events;
+ pfd.revents = 0;
}
PollEvent::~PollEvent()
PollQueue::~PollQueue()
{
- removeHandler();
for (int i = 0; i < num_fds; i++)
setupAsyncIO(poll_fds[0].fd, false);
max_size *= 2;
} else {
max_size = 16;
- setupHandler();
}
poll_fds = new pollfd[max_size];
}
}
-struct sigaction PollQueue::oldio;
-struct sigaction PollQueue::oldalrm;
-bool PollQueue::handler = false;
-
void
PollQueue::setupAsyncIO(int fd, bool set)
{
else
flags &= ~(FASYNC);
- if (fcntl(fd, F_SETFL, flags) == -1)
- panic("Could not set up async IO");
-
if (set) {
if (fcntl(fd, F_SETOWN, getpid()) == -1)
panic("Could not set up async IO");
}
-}
-
-void
-PollQueue::setupHandler()
-{
- struct sigaction act;
-
- act.sa_handler = handleIO;
- sigemptyset(&act.sa_mask);
- act.sa_flags = SA_RESTART;
-
- if (sigaction(SIGIO, &act, &oldio) == -1)
- panic("could not do sigaction");
-
- act.sa_handler = handleALRM;
- sigemptyset(&act.sa_mask);
- act.sa_flags = SA_RESTART;
-
- if (sigaction(SIGALRM, &act, &oldalrm) == -1)
- panic("could not do sigaction");
-
- alarm(1);
-
- handler = true;
-}
-void
-PollQueue::removeHandler()
-{
- if (sigaction(SIGIO, &oldio, NULL) == -1)
- panic("could not remove handler");
-
- if (sigaction(SIGIO, &oldalrm, NULL) == -1)
- panic("could not remove handler");
-}
-
-void
-PollQueue::handleIO(int sig)
-{
- if (sig != SIGIO)
- panic("Wrong Handler");
-
- async_event = true;
- async_io = true;
-}
-
-void
-PollQueue::handleALRM(int sig)
-{
- if (sig != SIGALRM)
- panic("Wrong Handler");
+ if (fcntl(fd, F_SETFL, flags) == -1)
+ panic("Could not set up async IO");
- async_event = true;
- async_alarm = true;
- alarm(1);
+ // The file descriptor might already have events pending. We won't
+ // see them if they occurred before we set the FASYNC
+ // flag. Simulate a SIGIO to ensure that the FD will be polled in
+ // next iteration of the simulation loop. We could just poll it,
+ // but this is much simpler.
+ if (set) {
+ async_event = true;
+ async_io = true;
+ /* Wake up some event queue to handle event */
+ getEventQueue(0)->wakeup();
+ }
}
-