From d21447d096a320a08b3efb2b8768fad0dcdcfd64 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Thu, 5 May 2016 22:28:51 +0100 Subject: move frontends into sub directory --- frontends/riscos/schedule.c | 163 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 frontends/riscos/schedule.c (limited to 'frontends/riscos/schedule.c') diff --git a/frontends/riscos/schedule.c b/frontends/riscos/schedule.c new file mode 100644 index 000000000..54308b7a9 --- /dev/null +++ b/frontends/riscos/schedule.c @@ -0,0 +1,163 @@ +/* + * Copyright 2004 James Bursa + * + * 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 . + */ + +/** \file + * Scheduled callback queue (implementation). + * + * The queue is simply implemented as a linked list. + */ + +#include +#include + +#include "oslib/os.h" +#include "utils/log.h" + +#include "riscos/gui.h" + + +/** Entry in the queue of scheduled callbacks. */ +struct sched_entry { + /** Preferred time for callback. */ + os_t time; + /** Function to call at the specified time. */ + void (*callback)(void *p); + /** User parameter for callback. */ + void *p; + /** Next (later) entry in queue. */ + struct sched_entry *next; +}; + +/** Queue of scheduled callbacks (sentinel at head). */ +static struct sched_entry sched_queue = { 0, 0, 0, 0 }; + +/** Items have been scheduled. */ +bool sched_active = false; +/** Time of soonest scheduled event (valid only if sched_active is true). */ +os_t sched_time; + +/** + * 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 sched_entry *entry, *prev; + + prev = &sched_queue; + + for (entry = prev->next; entry; entry = prev->next) { + if (entry->callback != callback || entry->p != p) { + prev = entry; + continue; + } + + prev->next = entry->next; + free(entry); + + /* There can only ever be one match, and we've found it */ + break; + } + + if (sched_queue.next) { + sched_active = true; + sched_time = sched_queue.next->time; + } else { + sched_active = false; + } + + return NSERROR_OK; +} + +/* exported function documented in riscos/gui.h */ +nserror riscos_schedule(int t, void (*callback)(void *p), void *p) +{ + struct sched_entry *entry; + struct sched_entry *queue; + os_t time; + nserror ret; + + ret = schedule_remove(callback, p); + if ((t < 0) || (ret != NSERROR_OK)) { + return ret; + } + + t = t / 10; /* convert to centiseconds */ + + time = os_read_monotonic_time() + t; + + entry = malloc(sizeof *entry); + if (!entry) { + LOG("malloc failed"); + return NSERROR_NOMEM; + } + + entry->time = time; + entry->callback = callback; + entry->p = p; + + for (queue = &sched_queue; + queue->next && queue->next->time <= time; + queue = queue->next) + ; + entry->next = queue->next; + queue->next = entry; + + sched_active = true; + sched_time = sched_queue.next->time; + + return NSERROR_OK; +} + + +/* exported function documented in riscos/gui.h */ +bool schedule_run(void) +{ + struct sched_entry *entry; + os_t now; + + now = os_read_monotonic_time(); + + while (sched_queue.next && sched_queue.next->time <= now) { + void (*callback)(void *p); + void *p; + + entry = sched_queue.next; + callback = entry->callback; + p = entry->p; + sched_queue.next = entry->next; + free(entry); + /* The callback may call riscos_schedule(), so leave + * the queue in a safe state. + */ + callback(p); + } + + if (sched_queue.next) { + sched_active = true; + sched_time = sched_queue.next->time; + } else + sched_active = false; + + return sched_active; +} -- cgit v1.2.3