summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--content/fetch.c2
-rw-r--r--monkey/Makefile.target3
-rw-r--r--monkey/main.c77
-rw-r--r--monkey/poll.c140
-rw-r--r--monkey/poll.h26
-rw-r--r--monkey/schedule.c284
-rw-r--r--monkey/schedule.h34
7 files changed, 282 insertions, 284 deletions
diff --git a/content/fetch.c b/content/fetch.c
index 2307676d3..47e6fc88e 100644
--- a/content/fetch.c
+++ b/content/fetch.c
@@ -379,7 +379,7 @@ fetcher_add(lwc_string *scheme, const struct fetcher_operation_table *ops)
return NSERROR_OK;
}
-/* exported interface documented in content/fetch.h */
+/* exported interface documented in content/fetchers.h */
nserror fetcher_fdset(fd_set *read_fd_set,
fd_set *write_fd_set,
fd_set *except_fd_set,
diff --git a/monkey/Makefile.target b/monkey/Makefile.target
index 281e82b98..3c7b093af 100644
--- a/monkey/Makefile.target
+++ b/monkey/Makefile.target
@@ -33,7 +33,6 @@ LDFLAGS += -lm
# non optional pkg-configed libs
$(eval $(call pkg_config_find_and_add,libcurl,Curl ))
$(eval $(call pkg_config_find_and_add,openssl,OpenSSL))
-$(eval $(call pkg_config_find_and_add,glib-2.0,GLib2))
# optional pkg-config configured libraries
$(eval $(call pkg_config_find_and_add_enabled,NSSVG,libsvgtiny,SVG))
@@ -58,7 +57,7 @@ endif
# S_MONKEY are sources purely for the MONKEY build
S_MONKEY := main.c utils.c filetype.c schedule.c bitmap.c plot.c browser.c \
- download.c 401login.c cert.c font.c poll.c dispatch.c fetch.c
+ download.c 401login.c cert.c font.c dispatch.c fetch.c
S_MONKEY := $(addprefix monkey/,$(S_MONKEY))
diff --git a/monkey/main.c b/monkey/main.c
index 9610ffff6..9569f9754 100644
--- a/monkey/main.c
+++ b/monkey/main.c
@@ -19,6 +19,10 @@
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
#include "utils/config.h"
#include "utils/log.h"
@@ -26,12 +30,12 @@
#include "utils/filepath.h"
#include "utils/nsoption.h"
#include "content/urldb.h"
+#include "content/fetchers.h"
#include "content/fetchers/resource.h"
#include "content/hlcache.h"
#include "desktop/gui_misc.h"
#include "desktop/netsurf.h"
-#include "monkey/poll.h"
#include "monkey/dispatch.h"
#include "monkey/browser.h"
#include "monkey/cert.h"
@@ -238,6 +242,70 @@ static struct gui_browser_table monkey_browser_table = {
.login = gui_401login_open,
};
+static void monkey_run(void)
+{
+ fd_set read_fd_set, write_fd_set, exc_fd_set;
+ int max_fd;
+ int rdy_fd;
+ int schedtm;
+ struct timeval tv;
+ struct timeval* timeout;
+
+ while (!monkey_done) {
+
+ /* clears fdset */
+ fetcher_fdset(&read_fd_set, &write_fd_set, &exc_fd_set, &max_fd);
+
+ /* add stdin to the set */
+ if (max_fd < 0) {
+ max_fd = 0;
+ }
+ FD_SET(0, &read_fd_set);
+ FD_SET(0, &exc_fd_set);
+
+ /* discover the next scheduled event time */
+ schedtm = monkey_schedule_run();
+
+ /* setup timeout */
+ switch (schedtm) {
+ case -1:
+ LOG("Iterate blocking");
+ fprintf(stdout, "GENERIC POLL BLOCKING\n");
+ timeout = NULL;
+ break;
+
+ case 0:
+ LOG("Iterate immediate");
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ timeout = &tv;
+ break;
+
+ default:
+ LOG("Iterate non-blocking");
+ fprintf(stdout, "GENERIC POLL TIMED\n");
+ tv.tv_sec = schedtm / 1000; /* miliseconds to seconds */
+ tv.tv_usec = (schedtm % 1000) * 1000; /* remainder to microseconds */
+ timeout = &tv;
+ break;
+ }
+
+ rdy_fd = select(max_fd + 1,
+ &read_fd_set,
+ &write_fd_set,
+ &exc_fd_set,
+ timeout);
+ if (rdy_fd < 0) {
+ monkey_done = true;
+ } else if (rdy_fd > 0) {
+ if (FD_ISSET(0, &read_fd_set)) {
+ monkey_process_command();
+ }
+ }
+ }
+
+}
+
int
main(int argc, char **argv)
{
@@ -300,8 +368,6 @@ main(int argc, char **argv)
urldb_load(nsoption_charp(url_file));
urldb_load_cookies(nsoption_charp(cookie_file));
- monkey_prepare_input();
-
ret = monkey_register_handler("QUIT", quit_handler);
if (ret != NSERROR_OK) {
die("quit handler failed to register");
@@ -313,10 +379,7 @@ main(int argc, char **argv)
}
fprintf(stdout, "GENERIC STARTED\n");
-
- while (!monkey_done) {
- monkey_poll();
- }
+ monkey_run();
fprintf(stdout, "GENERIC CLOSING_DOWN\n");
monkey_kill_browser_windows();
diff --git a/monkey/poll.c b/monkey/poll.c
deleted file mode 100644
index 3ec31af86..000000000
--- a/monkey/poll.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright 2011 Daniel Silverstone <dsilvers@digital-scurf.org>
- *
- * This file is part of NetSurf, http://www.netsurf-browser.org/
- *
- * NetSurf is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * NetSurf is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <assert.h>
-#include <stdlib.h>
-
-#include "content/hlcache.h"
-#include "content/fetchers.h"
-
-#include "monkey/schedule.h"
-#include "monkey/dispatch.h"
-#include "monkey/poll.h"
-
-#ifdef DEBUG_POLL_LOOP
-#include "utils/log.h"
-#else
-#define LOG(fmt, args...) ((void) 0)
-#endif
-
-
-#include <glib.h>
-
-typedef struct {
- GSource gs;
- GPollFD pf;
-} MonkeySource;
-
-static gboolean monkey_source_prepare(GSource *source,
- gint *timeout_)
-{
- *timeout_ = -1;
- return FALSE;
-}
-
-
-static gboolean monkey_source_check(GSource *source)
-{
- MonkeySource *ms = (MonkeySource *)source;
- if (ms->pf.revents & G_IO_IN) {
- return TRUE;
- }
- return FALSE;
-}
-
-static gboolean monkey_source_dispatch(GSource *source,
- GSourceFunc callback,
- gpointer user_data)
-{
- monkey_process_command();
- return TRUE;
-}
-
-static void monkey_source_finalize(GSource *source)
-{
-
-}
-
-GSourceFuncs monkey_source_funcs = {
- .prepare = monkey_source_prepare,
- .check = monkey_source_check,
- .dispatch = monkey_source_dispatch,
- .finalize = monkey_source_finalize,
-};
-
-void
-monkey_prepare_input(void)
-{
- MonkeySource *gs = (MonkeySource *)g_source_new(&monkey_source_funcs, sizeof *gs);
- gs->pf.fd = 0;
- gs->pf.events = G_IO_IN | G_IO_ERR;
- g_source_add_poll((GSource *)gs, &gs->pf);
- g_source_attach((GSource *)gs, NULL);
-}
-
-void monkey_poll(void)
-{
- fd_set read_fd_set, write_fd_set, exc_fd_set;
- int max_fd;
- GPollFD *fd_list[1000];
- unsigned int fd_count = 0;
- bool block = true;
-
- fetcher_fdset(&read_fd_set, &write_fd_set, &exc_fd_set, &max_fd);
- for (int i = 0; i <= max_fd; i++) {
- if (FD_ISSET(i, &read_fd_set)) {
- GPollFD *fd = malloc(sizeof *fd);
- fd->fd = i;
- fd->events = G_IO_IN | G_IO_HUP | G_IO_ERR;
- g_main_context_add_poll(0, fd, 0);
- fd_list[fd_count++] = fd;
- LOG("Want to read %d", i);
- }
- if (FD_ISSET(i, &write_fd_set)) {
- GPollFD *fd = malloc(sizeof *fd);
- fd->fd = i;
- fd->events = G_IO_OUT | G_IO_ERR;
- g_main_context_add_poll(0, fd, 0);
- fd_list[fd_count++] = fd;
- LOG("Want to write %d", i);
- }
- if (FD_ISSET(i, &exc_fd_set)) {
- GPollFD *fd = malloc(sizeof *fd);
- fd->fd = i;
- fd->events = G_IO_ERR;
- g_main_context_add_poll(0, fd, 0);
- fd_list[fd_count++] = fd;
- LOG("Want to check %d", i);
- }
- }
-
- schedule_run();
-
- LOG("Iterate %sblocking", block ? "" : "non-");
- if (block) {
- fprintf(stdout, "GENERIC POLL BLOCKING\n");
- }
- g_main_context_iteration(g_main_context_default(), block);
-
- for (unsigned int i = 0; i != fd_count; i++) {
- g_main_context_remove_poll(0, fd_list[i]);
- free(fd_list[i]);
- }
-
-}
-
diff --git a/monkey/poll.h b/monkey/poll.h
deleted file mode 100644
index 2b14e61bd..000000000
--- a/monkey/poll.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2011 Daniel Silverstone <dsilvers@digital-scurf.org>
- *
- * This file is part of NetSurf, http://www.netsurf-browser.org/
- *
- * NetSurf is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * NetSurf is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NETSURF_MONKEY_POLL_H
-#define NETSURF_MONKEY_POLL_H 1
-
-void monkey_prepare_input(void);
-
-void monkey_poll(void);
-
-#endif /* NETSURF_MONKEY_POLL_H */
diff --git a/monkey/schedule.c b/monkey/schedule.c
index d6f8e65dc..b3b335900 100644
--- a/monkey/schedule.c
+++ b/monkey/schedule.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2006-2007 Daniel Silverstone <dsilvers@digital-scurf.org>
+ * Copyright 2012 Vincent Sanders <vince@netsurf-browser.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -16,128 +16,208 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <glib.h>
+#include <sys/time.h>
+#include <time.h>
#include <stdlib.h>
-#include <stdbool.h>
-#include "utils/errors.h"
+#include "utils/log.h"
#include "monkey/schedule.h"
-#undef DEBUG_MONKEY_SCHEDULE
-
-#ifdef DEBUG_MONKEY_SCHEDULE
-#include "utils/log.h"
+#ifdef DEBUG_SCHEDULER
+#define SRLOG(x...) LOG(x)
#else
-#define LOG(fmt, args...) ((void) 0)
+#define SRLOG(x...) ((void) 0)
#endif
-/** Killable callback closure embodiment. */
-typedef struct {
- void (*callback)(void *); /**< The callback function. */
- void *context; /**< The context for the callback. */
- bool callback_killed; /**< Whether or not this was killed. */
-} _nsgtk_callback_t;
-
-/** List of callbacks which have occurred and are pending running. */
-static GList *pending_callbacks = NULL;
-/** List of callbacks which are queued to occur in the future. */
-static GList *queued_callbacks = NULL;
-/** List of callbacks which are about to be run in this ::schedule_run. */
-static GList *this_run = NULL;
-
-static gboolean
-nsgtk_schedule_generic_callback(gpointer data)
+/* linked list of scheduled callbacks */
+static struct nscallback *schedule_list = NULL;
+
+/**
+ * scheduled callback.
+ */
+struct nscallback
{
- _nsgtk_callback_t *cb = (_nsgtk_callback_t *)(data);
- if (cb->callback_killed) {
- /* This callback instance has been killed. */
- LOG("CB at %p already dead.", cb);
- }
- queued_callbacks = g_list_remove(queued_callbacks, cb);
- LOG("CB %p(%p) now pending run", cb->callback, cb->context);
- pending_callbacks = g_list_append(pending_callbacks, cb);
- return FALSE;
+ struct nscallback *next;
+ struct timeval tv;
+ void (*callback)(void *p);
+ void *p;
+};
+
+/**
+ * Unschedule a callback.
+ *
+ * \param callback callback function
+ * \param p user parameter, passed to callback function
+ *
+ * All scheduled callbacks matching both callback and p are removed.
+ */
+static nserror schedule_remove(void (*callback)(void *p), void *p)
+{
+ struct nscallback *cur_nscb;
+ struct nscallback *prev_nscb;
+ struct nscallback *unlnk_nscb;
+
+ /* check there is something on the list to remove */
+ if (schedule_list == NULL) {
+ return NSERROR_OK;
+ }
+
+ SRLOG("removing %p, %p", callback, p);
+
+ cur_nscb = schedule_list;
+ prev_nscb = NULL;
+
+ while (cur_nscb != NULL) {
+ if ((cur_nscb->callback == callback) &&
+ (cur_nscb->p == p)) {
+ /* item to remove */
+
+ SRLOG("callback entry %p removing %p(%p)",
+ cur_nscb, cur_nscb->callback, cur_nscb->p);
+
+ /* remove callback */
+ unlnk_nscb = cur_nscb;
+ cur_nscb = unlnk_nscb->next;
+
+ if (prev_nscb == NULL) {
+ schedule_list = cur_nscb;
+ } else {
+ prev_nscb->next = cur_nscb;
+ }
+ free (unlnk_nscb);
+ } else {
+ /* move to next element */
+ prev_nscb = cur_nscb;
+ cur_nscb = prev_nscb->next;
+ }
+ }
+
+ return NSERROR_OK;
}
-static void
-nsgtk_schedule_kill_callback(void *_target, void *_match)
+/* exported function documented in framebuffer/schedule.h */
+nserror monkey_schedule(int tival, void (*callback)(void *p), void *p)
{
- _nsgtk_callback_t *target = (_nsgtk_callback_t *)_target;
- _nsgtk_callback_t *match = (_nsgtk_callback_t *)_match;
- if ((target->callback == match->callback) &&
- (target->context == match->context)) {
- LOG("Found match for %p(%p), killing.", target->callback, target->context);
- target->callback = NULL;
- target->context = NULL;
- target->callback_killed = true;
- }
+ struct nscallback *nscb;
+ struct timeval tv;
+ nserror ret;
+
+ /* ensure uniqueness of the callback and context */
+ ret = schedule_remove(callback, p);
+ if ((tival < 0) || (ret != NSERROR_OK)) {
+ return ret;
+ }
+
+ SRLOG("Adding %p(%p) in %d", callback, p, tival);
+
+ tv.tv_sec = tival / 1000; /* miliseconds to seconds */
+ tv.tv_usec = (tival % 1000) * 1000; /* remainder to microseconds */
+
+ nscb = calloc(1, sizeof(struct nscallback));
+
+ gettimeofday(&nscb->tv, NULL);
+ timeradd(&nscb->tv, &tv, &nscb->tv);
+
+ nscb->callback = callback;
+ nscb->p = p;
+
+ /* add to list front */
+ nscb->next = schedule_list;
+ schedule_list = nscb;
+
+ return NSERROR_OK;
}
-static void
-schedule_remove(void (*callback)(void *p), void *p)
+/* exported function documented in framebuffer/schedule.h */
+int monkey_schedule_run(void)
{
- _nsgtk_callback_t cb_match = {
- .callback = callback,
- .context = p,
- };
-
- g_list_foreach(queued_callbacks,
- nsgtk_schedule_kill_callback, &cb_match);
- g_list_foreach(pending_callbacks,
- nsgtk_schedule_kill_callback, &cb_match);
- g_list_foreach(this_run,
- nsgtk_schedule_kill_callback, &cb_match);
+ struct timeval tv;
+ struct timeval nexttime;
+ struct timeval rettime;
+ struct nscallback *cur_nscb;
+ struct nscallback *prev_nscb;
+ struct nscallback *unlnk_nscb;
+
+ if (schedule_list == NULL)
+ return -1;
+
+ /* reset enumeration to the start of the list */
+ cur_nscb = schedule_list;
+ prev_nscb = NULL;
+ nexttime = cur_nscb->tv;
+
+ gettimeofday(&tv, NULL);
+
+ while (cur_nscb != NULL) {
+ if (timercmp(&tv, &cur_nscb->tv, >)) {
+ /* scheduled time */
+
+ /* remove callback */
+ unlnk_nscb = cur_nscb;
+
+ if (prev_nscb == NULL) {
+ schedule_list = unlnk_nscb->next;
+ } else {
+ prev_nscb->next = unlnk_nscb->next;
+ }
+
+ unlnk_nscb->callback(unlnk_nscb->p);
+
+ free(unlnk_nscb);
+
+ /* need to deal with callback modifying the list. */
+ if (schedule_list == NULL)
+ return -1; /* no more callbacks scheduled */
+
+ /* reset enumeration to the start of the list */
+ cur_nscb = schedule_list;
+ prev_nscb = NULL;
+ nexttime = cur_nscb->tv;
+ } else {
+ /* if the time to the event is sooner than the
+ * currently recorded soonest event record it
+ */
+ if (timercmp(&nexttime, &cur_nscb->tv, >)) {
+ nexttime = cur_nscb->tv;
+ }
+ /* move to next element */
+ prev_nscb = cur_nscb;
+ cur_nscb = prev_nscb->next;
+ }
+ }
+
+ /* make rettime relative to now */
+ timersub(&nexttime, &tv, &rettime);
+
+ SRLOG("returning time to next event as %ldms",
+ (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000));
+
+ /* return next event time in milliseconds (24days max wait) */
+ return (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000);
}
-nserror monkey_schedule(int t, void (*callback)(void *p), void *p)
+void monkey_schedule_list(void)
{
- _nsgtk_callback_t *cb;
+ struct timeval tv;
+ struct nscallback *cur_nscb;
- /* Kill any pending schedule of this kind. */
- schedule_remove(callback, p);
- if (t < 0) {
- return NSERROR_OK;
- }
+ gettimeofday(&tv, NULL);
- cb = malloc(sizeof(_nsgtk_callback_t));
- cb->callback = callback;
- cb->context = p;
- cb->callback_killed = false;
- /* Prepend is faster right now. */
- LOG("queued a callback to %p(%p) for %d msecs time", callback, p, t);
- queued_callbacks = g_list_prepend(queued_callbacks, cb);
- g_timeout_add(t, nsgtk_schedule_generic_callback, cb);
+ LOG("schedule list at %ld:%ld", tv.tv_sec, tv.tv_usec);
- return NSERROR_OK;
+ cur_nscb = schedule_list;
+ while (cur_nscb != NULL) {
+ LOG("Schedule %p at %ld:%ld",
+ cur_nscb, cur_nscb->tv.tv_sec, cur_nscb->tv.tv_usec);
+ cur_nscb = cur_nscb->next;
+ }
}
-bool
-schedule_run(void)
-{
- /* Capture this run of pending callbacks into the list. */
- this_run = pending_callbacks;
-
- if (this_run == NULL)
- return false; /* Nothing to do */
-
- /* Clear the pending list. */
- pending_callbacks = NULL;
-
- LOG("Captured a run of %d callbacks to fire.", g_list_length(this_run));
-
- /* Run all the callbacks which made it this far. */
- while (this_run != NULL) {
- _nsgtk_callback_t *cb = (_nsgtk_callback_t *)(this_run->data);
- this_run = g_list_remove(this_run, this_run->data);
- if (!cb->callback_killed) {
- LOG("CB DO %p(%p)", cb->callback, cb->context);
- cb->callback(cb->context);
- } else {
- LOG("CB %p(%p) already dead, dropping", cb->callback, cb->context);
- }
- free(cb);
- }
- return true;
-}
+
+/*
+ * Local Variables:
+ * c-basic-offset:2
+ * End:
+ */
diff --git a/monkey/schedule.h b/monkey/schedule.h
index 44ef9bf3b..14fad8247 100644
--- a/monkey/schedule.h
+++ b/monkey/schedule.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Daniel Silverstone <dsilvers@digital-scurf.org>
+ * Copyright 2008 Vincent Sanders <vince@simtec.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -16,11 +16,33 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NETSURF_GTK_CALLBACK_H
-#define NETSURF_GTK_CALLBACK_H 1
+#ifndef NETSURF_MONKEY_SCHEDULE_H
+#define NETSURF_MONKEY_SCHEDULE_H
-nserror monkey_schedule(int t, void (*callback)(void *p), void *p);
+/**
+ * Schedule a callback.
+ *
+ * \param tival interval before the callback should be made in ms
+ * \param callback callback function
+ * \param p user parameter, passed to callback function
+ *
+ * The callback function will be called as soon as possible after t ms have
+ * passed.
+ */
+
+nserror monkey_schedule(int tival, void (*callback)(void *p), void *p);
-bool schedule_run(void);
+/**
+ * Process scheduled callbacks up to current time.
+ *
+ * @return The number of milliseconds untill the next scheduled event
+ * or -1 for no event.
+ */
+int monkey_schedule_run(void);
+
+/**
+ * Log a list of all scheduled callbacks.
+ */
+void monkey_schedule_list(void);
-#endif /* NETSURF_GTK_CALLBACK_H */
+#endif