diff options
author | pixel <pixel> | 2006-01-31 17:02:38 +0000 |
---|---|---|
committer | pixel <pixel> | 2006-01-31 17:02:38 +0000 |
commit | 6daac4eb3604736e20e8af5733f698eb144f0c2a (patch) | |
tree | 7a684f120b20e0aae0ecbedcaad480cdae581200 /lib/TaskMan.cc | |
parent | 6634b5d65d21b826830d7601178453a0a3084e8d (diff) |
Way too much changes - all over.
Diffstat (limited to 'lib/TaskMan.cc')
-rw-r--r-- | lib/TaskMan.cc | 120 |
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; |