summaryrefslogtreecommitdiff
path: root/lib/TaskMan.cc
diff options
context:
space:
mode:
authorpixel <pixel>2006-01-31 17:02:38 +0000
committerpixel <pixel>2006-01-31 17:02:38 +0000
commit6daac4eb3604736e20e8af5733f698eb144f0c2a (patch)
tree7a684f120b20e0aae0ecbedcaad480cdae581200 /lib/TaskMan.cc
parent6634b5d65d21b826830d7601178453a0a3084e8d (diff)
Way too much changes - all over.
Diffstat (limited to 'lib/TaskMan.cc')
-rw-r--r--lib/TaskMan.cc120
1 files changed, 107 insertions, 13 deletions
diff --git a/lib/TaskMan.cc b/lib/TaskMan.cc
index 1dcf331..8b27e71 100644
--- a/lib/TaskMan.cc
+++ b/lib/TaskMan.cc
@@ -1,11 +1,13 @@
+#ifndef _WIN32
#include <signal.h>
#include <sys/wait.h>
#include <sys/poll.h>
+#include <sys/time.h>
+#include <unistd.h>
+#endif
#include <errno.h>
#include <string.h>
-#include <sys/time.h>
#include <sys/types.h>
-#include <unistd.h>
#include <vector>
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -13,8 +15,6 @@
#include "TaskMan.h"
#include "gettext.h"
-#define USE_POLL 1
-
TaskMan::TaskList_t TaskMan::TaskList;
TaskMan::TaskList_t TaskMan::Zombies;
std::vector<TaskMan::w4ha_t> TaskMan::w4ha;
@@ -33,6 +33,7 @@ sigset_t TaskMan::sigchildset;
static int got_sigchild = 0;
+#ifndef _WIN32
void taskman_sigchild(int sig) {
int status;
pid_t pid;
@@ -51,6 +52,90 @@ void taskman_sigchild(int sig) {
void taskman_sighole(int sig) {
signal(sig, taskman_sighole);
}
+#endif
+
+#ifdef _WIN32
+
+
+#define POLLIN 1 /* Set if data to read. */
+#define POLLPRI 2 /* Set if urgent data to read. */
+#define POLLOUT 4 /* Set if writing data wouldn't block. */
+#define POLLERR 8 /* An error occured. */
+#define POLLHUP 16 /* Shutdown or close happened. */
+#define POLLNVAL 32 /* Invalid file descriptor. */
+
+#define NPOLLFILE 64 /* Number of canonical fd's in one call to poll(). */
+
+/* The following values are defined by XPG4. */
+#define POLLRDNORM POLLIN
+#define POLLRDBAND POLLPRI
+#define POLLWRNORM POLLOUT
+#define POLLWRBAND POLLOUT
+
+struct pollfd {
+ int fd;
+ short events;
+ short revents;
+};
+
+int poll (struct pollfd *fds, unsigned int nfds, int timeout) {
+ fd_set read_fds, write_fds, except_fds;
+ struct timeval tv = { timeout / 1000, (timeout % 1000) * 1000 };
+ int max_fd = 0, i, retval, changedfds;
+
+ FD_ZERO(&read_fds);
+ FD_ZERO(&write_fds);
+ FD_ZERO(&except_fds);
+
+ for (int i = 0; i < nfds; i++) {
+ if (!fds[i].fd && !fds[i].events)
+ continue;
+
+ if (fds[i].fd > max_fd)
+ max_fd = fds[i].fd;
+
+ if (fds[i].events & POLLIN)
+ FD_SET(fds[i].fd, &read_fds);
+
+ if (fds[i].events & POLLOUT)
+ FD_SET(fds[i].fd, &write_fds);
+
+ FD_SET(fds[i].fd, &except_fds);
+
+ fds[i].revents = 0;
+ }
+
+ changedfds = retval = select(max_fd + 1, &read_fds, &write_fds, &except_fds, timeout < 0 ? NULL : &tv);
+
+ if (retval <= 0) {
+ // got timeout or error
+ return retval;
+ }
+
+ for (i = 0; i < nfds; i++) {
+ if (FD_ISSET(fds[i].fd, &read_fds)) {
+ fds[i].revents |= POLLIN;
+ changedfds--;
+ }
+
+ if (FD_ISSET(fds[i].fd, &write_fds)) {
+ fds[i].revents |= POLLOUT;
+ changedfds--;
+ }
+
+ if (FD_ISSET(fds[i].fd, &except_fds)) {
+ fds[i].revents |= POLLERR;
+ changedfds--;
+ }
+
+ if (changedfds <= 0)
+ break;
+ }
+
+ return retval;
+}
+
+#endif
int TaskMan::GotChild(pid_t pid, int status) {
int r = 0;
@@ -72,6 +157,7 @@ void TaskMan::Init() throw (GeneralException) {
throw GeneralException(_("Task Manager already initialised."));
}
+#ifndef _WIN32
signal(SIGCHLD, taskman_sigchild);
signal(SIGPIPE, taskman_sighole);
signal(SIGHUP, taskman_sighole);
@@ -79,7 +165,8 @@ void TaskMan::Init() throw (GeneralException) {
sigemptyset(&sigchildset);
sigaddset(&sigchildset, SIGCHLD);
sigprocmask(SIG_BLOCK, &sigchildset, 0);
-
+#endif
+
inited = true;
number = 0;
}
@@ -258,7 +345,7 @@ void TaskMan::MainLoop() throw (GeneralException) {
if (t->GetState() == TASK_DONE) {
TaskList.erase(p);
number--;
- p--;
+ p = TaskList.begin();
Zombies.push_back(t);
}
}
@@ -308,21 +395,26 @@ void TaskMan::MainLoop() throw (GeneralException) {
p->T->SetBurst();
no_burst = 0;
p->dirthy = true;
- if (!(p->flags & W4_STICKY)) {
- w4ha.erase(p);
- p--;
- }
q->fd = 0;
q->events = 0;
}
}
}
+ for (p = w4ha.begin(); p != w4ha.end(); p++) {
+ if (!p->T->IsStopped() && !p->ha->CanWatch() && !(p->flags & W4_STICKY)) {
+ w4ha.erase(p);
+ p = w4ha.begin();
+ }
+ }
}
-
+
+#ifndef _WIN32
sigprocmask(SIG_UNBLOCK, &sigchildset, 0);
+#endif
r = poll(ufsd, nfds, (no_burst) && !(Zombies.size()) && !(got_sigchild) ? -1: 0);
- sigprocmask(SIG_BLOCK, &sigchildset, 0);
-
+#ifndef _WIN32
+ sigprocmask(SIG_BLOCK, &sigchildset, 0);
+#endif
if (r < 0) {
if (errno != EINTR) {
throw GeneralException(String(_("Error during poll: ")) + strerror(errno));
@@ -330,7 +422,9 @@ void TaskMan::MainLoop() throw (GeneralException) {
} else if (r == 0) {
// timeout.
// **FIXME**
+#ifndef _WIN32
#warning FIXME
+#endif
} else {
int fd;
struct pollfd * q;