Stop win32 frontend using 100% cpu time when idle
svn path=/trunk/netsurf/; revision=11633
This commit is contained in:
parent
42990ed9ec
commit
3c414e7668
|
@ -50,7 +50,7 @@ char *strchrnul(const char *s, int c);
|
|||
#define HAVE_INETATON
|
||||
#if (defined(_WIN32))
|
||||
#undef HAVE_INETATON
|
||||
#include <winsock.h>
|
||||
#include <winsock2.h>
|
||||
#define EAFNOSUPPORT WSAEAFNOSUPPORT
|
||||
int inet_aton(const char *cp, struct in_addr *inp);
|
||||
#else
|
||||
|
|
|
@ -91,6 +91,31 @@ typedef struct
|
|||
#define nsmkdir(dir, mode) mkdir((dir))
|
||||
#endif
|
||||
|
||||
#ifndef timeradd
|
||||
#define timeradd(a, aa, result) \
|
||||
do { \
|
||||
(result)->tv_sec = (a)->tv_sec + (aa)->tv_sec; \
|
||||
(result)->tv_usec = (a)->tv_usec + (aa)->tv_usec; \
|
||||
if ((result)->tv_usec >= 1000000) { \
|
||||
++(result)->tv_sec; \
|
||||
(result)->tv_usec -= 1000000; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef timersub
|
||||
#define timersub(a, aa, result) \
|
||||
do { \
|
||||
(result)->tv_sec = (a)->tv_sec - (aa)->tv_sec; \
|
||||
(result)->tv_usec = (a)->tv_usec - (aa)->tv_usec; \
|
||||
if ((result)->tv_usec < 0) { \
|
||||
--(result)->tv_sec; \
|
||||
(result)->tv_usec += 1000000; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Private-word-capable realloc() implementation which
|
||||
* behaves as most NS libraries expect in the face of
|
||||
|
|
|
@ -143,20 +143,40 @@ void gui_multitask(void)
|
|||
|
||||
void gui_poll(bool active)
|
||||
{
|
||||
MSG Msg;
|
||||
if (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE) != 0) {
|
||||
/* if (!((current_gui == NULL) ||
|
||||
(TranslateAccelerator(current_gui->main,
|
||||
current_gui->acceltable, &Msg)))) {
|
||||
TranslateMessage(&Msg);
|
||||
}
|
||||
*/
|
||||
TranslateMessage(&Msg);
|
||||
DispatchMessage(&Msg);
|
||||
MSG Msg; /* message from system */
|
||||
BOOL bRet; /* message fetch result */
|
||||
int timeout; /* timeout in miliseconds */
|
||||
UINT timer_id = 0;
|
||||
|
||||
/* run the scheduler and discover how long to wait for the next event */
|
||||
timeout = schedule_run();
|
||||
|
||||
/* if active set timeout so message is not waited for */
|
||||
if (active)
|
||||
timeout = 0;
|
||||
|
||||
if (timeout == 0) {
|
||||
bRet = PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE);
|
||||
} else {
|
||||
if (timeout > 0) {
|
||||
/* set up a timer to ensure we get woken */
|
||||
timer_id = SetTimer(NULL, 0, timeout, NULL);
|
||||
}
|
||||
|
||||
/* wait for a message */
|
||||
bRet = GetMessage(&Msg, NULL, 0, 0);
|
||||
|
||||
/* if a timer was sucessfully created remove it */
|
||||
if (timer_id != 0) {
|
||||
KillTimer(NULL, timer_id);
|
||||
}
|
||||
}
|
||||
|
||||
schedule_run();
|
||||
|
||||
if (bRet > 0) {
|
||||
TranslateMessage(&Msg);
|
||||
DispatchMessage(&Msg);
|
||||
}
|
||||
}
|
||||
|
||||
/* obtain gui window structure from windows window handle */
|
||||
|
|
|
@ -20,32 +20,20 @@
|
|||
#include <time.h>
|
||||
|
||||
#include "desktop/browser.h"
|
||||
#include "windows/schedule.h"
|
||||
#include "framebuffer/schedule.h"
|
||||
|
||||
#include "utils/log.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
/* linked list of scheduled callbacks */
|
||||
static struct nscallback *schedule_list = NULL;
|
||||
|
||||
#ifndef timeradd
|
||||
#define timeradd(a, aa, result) \
|
||||
do {\
|
||||
(result)->tv_sec = (a)->tv_sec + (aa)->tv_sec;\
|
||||
(result)->tv_usec = (a)->tv_usec + (aa)->tv_usec;\
|
||||
if ((result)->tv_usec >= 1000000)\
|
||||
{\
|
||||
++(result)->tv_sec;\
|
||||
(result)->tv_usec -= 1000000;\
|
||||
}\
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* scheduled callback.
|
||||
*/
|
||||
struct nscallback
|
||||
{
|
||||
struct nscallback *next;
|
||||
struct nscallback *next;
|
||||
struct timeval tv;
|
||||
void (*callback)(void *p);
|
||||
void *p;
|
||||
|
@ -57,7 +45,7 @@ struct nscallback
|
|||
*
|
||||
* \param tival interval before the callback should be made / cs
|
||||
* \param callback callback function
|
||||
* \param p user parameter, passed to callback function
|
||||
* \param p user parameter, passed to callback function
|
||||
*
|
||||
* The callback function will be called as soon as possible after t cs have
|
||||
* passed.
|
||||
|
@ -68,8 +56,8 @@ void schedule(int cs_ival, void (*callback)(void *p), void *p)
|
|||
struct nscallback *nscb;
|
||||
struct timeval tv;
|
||||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = cs_ival * 10000;
|
||||
tv.tv_sec = cs_ival / 100; /* cs to seconds */
|
||||
tv.tv_usec = (cs_ival % 100) * 10000; /* remainder to microseconds */
|
||||
|
||||
nscb = calloc(1, sizeof(struct nscallback));
|
||||
|
||||
|
@ -81,128 +69,158 @@ void schedule(int cs_ival, void (*callback)(void *p), void *p)
|
|||
nscb->callback = callback;
|
||||
nscb->p = p;
|
||||
|
||||
/* add to list front */
|
||||
nscb->next = schedule_list;
|
||||
schedule_list = nscb;
|
||||
/* add to list front */
|
||||
nscb->next = schedule_list;
|
||||
schedule_list = nscb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unschedule a callback.
|
||||
*
|
||||
* \param callback callback function
|
||||
* \param p user parameter, passed to callback function
|
||||
* \param p user parameter, passed to callback function
|
||||
*
|
||||
* All scheduled callbacks matching both callback and p are removed.
|
||||
*/
|
||||
|
||||
void schedule_remove(void (*callback)(void *p), void *p)
|
||||
{
|
||||
struct nscallback *cur_nscb;
|
||||
struct nscallback *prev_nscb;
|
||||
struct nscallback *unlnk_nscb;
|
||||
struct nscallback *cur_nscb;
|
||||
struct nscallback *prev_nscb;
|
||||
struct nscallback *unlnk_nscb;
|
||||
|
||||
if (schedule_list == NULL)
|
||||
return;
|
||||
if (schedule_list == NULL)
|
||||
return;
|
||||
|
||||
LOG(("removing %p, %p", callback, p));
|
||||
|
||||
cur_nscb = schedule_list;
|
||||
prev_nscb = NULL;
|
||||
cur_nscb = schedule_list;
|
||||
prev_nscb = NULL;
|
||||
|
||||
while (cur_nscb != NULL) {
|
||||
if ((cur_nscb->callback == callback) &&
|
||||
(cur_nscb->p == p)) {
|
||||
/* item to remove */
|
||||
|
||||
LOG(("callback entry %p removing %p(%p)",
|
||||
cur_nscb, cur_nscb->callback, cur_nscb->p));
|
||||
while (cur_nscb != NULL) {
|
||||
if ((cur_nscb->callback == callback) &&
|
||||
(cur_nscb->p == p)) {
|
||||
/* item to remove */
|
||||
|
||||
/* remove callback */
|
||||
unlnk_nscb = cur_nscb;
|
||||
cur_nscb = unlnk_nscb->next;
|
||||
LOG(("callback entry %p removing %p(%p)",
|
||||
cur_nscb, cur_nscb->callback, cur_nscb->p));
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process events up to current time.
|
||||
* Process scheduled callbacks up to current time.
|
||||
*
|
||||
* @return The number of milliseconds untill the next scheduled event
|
||||
* or -1 for no event.
|
||||
*/
|
||||
|
||||
bool schedule_run(void)
|
||||
int
|
||||
schedule_run(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
struct nscallback *cur_nscb;
|
||||
struct nscallback *prev_nscb;
|
||||
struct nscallback *unlnk_nscb;
|
||||
struct timeval nexttime;
|
||||
struct timeval rettime;
|
||||
struct nscallback *cur_nscb;
|
||||
struct nscallback *prev_nscb;
|
||||
struct nscallback *unlnk_nscb;
|
||||
|
||||
if (schedule_list == NULL)
|
||||
return false;
|
||||
if (schedule_list == NULL)
|
||||
return -1;
|
||||
|
||||
cur_nscb = schedule_list;
|
||||
prev_nscb = NULL;
|
||||
/* 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 */
|
||||
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;
|
||||
}
|
||||
|
||||
LOG(("callback entry %p running %p(%p)",
|
||||
unlnk_nscb, unlnk_nscb->callback, unlnk_nscb->p));
|
||||
/* call callback */
|
||||
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 */
|
||||
|
||||
/* remove callback */
|
||||
unlnk_nscb = cur_nscb;
|
||||
|
||||
if (prev_nscb == NULL) {
|
||||
schedule_list = unlnk_nscb->next;
|
||||
} else {
|
||||
prev_nscb->next = unlnk_nscb->next;
|
||||
}
|
||||
|
||||
LOG(("callback entry %p running %p(%p)",
|
||||
unlnk_nscb, unlnk_nscb->callback, unlnk_nscb->p));
|
||||
/* call callback */
|
||||
unlnk_nscb->callback(unlnk_nscb->p);
|
||||
|
||||
free (unlnk_nscb);
|
||||
|
||||
/* the callback might have modded the list, so start
|
||||
* again
|
||||
/* 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
|
||||
*/
|
||||
cur_nscb = schedule_list;
|
||||
prev_nscb = NULL;
|
||||
if (timercmp(&nexttime, &cur_nscb->tv, >)) {
|
||||
nexttime = cur_nscb->tv;
|
||||
}
|
||||
/* move to next element */
|
||||
prev_nscb = cur_nscb;
|
||||
cur_nscb = prev_nscb->next;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
/* move to next element */
|
||||
prev_nscb = cur_nscb;
|
||||
cur_nscb = prev_nscb->next;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
/* make rettime relative to now */
|
||||
timersub(&nexttime, &tv, &rettime);
|
||||
|
||||
#if DEBUG_SCHEDULER
|
||||
LOG(("returning time to next event as %ldms",(rettime.tv_sec * 1000) + (rettime.tv_usec / 1000)));
|
||||
#endif
|
||||
/* return next event time in milliseconds (24days max wait) */
|
||||
return (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000);
|
||||
}
|
||||
|
||||
void list_schedule(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
struct nscallback *cur_nscb;
|
||||
struct nscallback *cur_nscb;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
LOG(("schedule list at %ld:%ld", tv.tv_sec, tv.tv_usec));
|
||||
LOG(("schedule list at %ld:%ld", tv.tv_sec, tv.tv_usec));
|
||||
|
||||
cur_nscb = schedule_list;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* c-basic-offset:8
|
||||
* End:
|
||||
*/
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/*
|
||||
* Copyright 2008 Vincent Sanders <vince@simtec.co.uk>
|
||||
* Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net>
|
||||
*
|
||||
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
||||
*
|
||||
|
@ -17,10 +16,10 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _NETSURF_WINDOWS_SCHEDULE_H_
|
||||
#define _NETSURF_WINDOWS_SCHEDULE_H_
|
||||
#ifndef FRAMEBUFFER_SCHEDULE_H
|
||||
#define FRAMEBUFFER_SCHEDULE_H
|
||||
|
||||
int schedule_run(void);
|
||||
void list_schedule(void);
|
||||
bool schedule_run(void);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue