Scheduled events now signal when the scheduled time has passed.

The timer appears to stop signalling events occasionally - needs some investigation.

svn path=/trunk/netsurf/; revision=5287
This commit is contained in:
Chris Young 2008-09-08 18:14:14 +00:00
parent 7dd73c5b43
commit 9fc58606db
4 changed files with 77 additions and 16 deletions

View File

@ -88,7 +88,6 @@ struct gui_window *search_current_window = NULL;
struct MsgPort *sport;
struct MsgPort *appport;
struct MsgPort *msgport;
struct timerequest *tioreq;
struct Device *TimerBase;
struct TimerIFace *ITimer;
struct Library *PopupMenuBase = NULL;
@ -152,7 +151,7 @@ void gui_init(int argc, char** argv)
ASO_NoTrack,FALSE,
TAG_DONE);
OpenDevice("timer.device",UNIT_VBLANK,(struct IORequest *)tioreq,0);
OpenDevice("timer.device",UNIT_WAITUNTIL,(struct IORequest *)tioreq,0);
TimerBase = (struct Device *)tioreq->tr_node.io_Device;
ITimer = (struct TimerIFace *)GetInterface((struct Library *)TimerBase,"main",1,NULL);
@ -609,8 +608,7 @@ void ami_handle_msg(void)
break;
case WMHI_INTUITICK:
// these are only here to stop netsurf stalling waiting for an event
break;
break;
default:
// printf("class: %ld\n",(result & WMHI_CLASSMASK));
@ -737,6 +735,9 @@ void ami_handle_appmsg(void)
else
{
browser_window_mouse_click(gwin->bw, BROWSER_MOUSE_PRESS_1, x,y);
/* This bit pastes a plain text file into a form. Really we should be using
Datatypes for this to support more formats */
if(fh = FOpen(filename,MODE_OLDFILE,0))
{
while(len = FRead(fh,filename,1,1024))
@ -757,6 +758,9 @@ void ami_handle_appmsg(void)
}
}
ReplyMsg((struct Message *)appmsg);
if(gwin->redraw_required)
ami_do_redraw(gwin);
}
}
@ -764,8 +768,10 @@ void ami_get_msg(void)
{
ULONG winsignal = 1L << sport->mp_SigBit;
ULONG appsig = 1L << appport->mp_SigBit;
ULONG signalmask = winsignal | appsig;
ULONG schedulesig = 1L << msgport->mp_SigBit;
ULONG signalmask = winsignal | appsig | schedulesig;
ULONG signal;
struct Message *timermsg = NULL;
signal = Wait(signalmask);
@ -777,6 +783,11 @@ void ami_get_msg(void)
{
ami_handle_appmsg();
}
else if(signal & schedulesig)
{
while(GetMsg(msgport))
schedule_run();
}
}
void gui_multitask(void)
@ -791,15 +802,25 @@ void gui_multitask(void)
void gui_poll(bool active)
{
/* However, down here we are waiting for the user to do something or for a
scheduled event to kick in (scheduled events will be signalled using
timer.device in the future rather than inefficiently polled - currently
Intuition is sending IDCMP_INTUITICKS messages every 1/10s to our active
window which breaks us out of ami_get_msg - and schedule_run checks every
event, really they need to be sorted and/or when signalled the schedule
node should be part of the message) */
scheduled event to kick in (scheduled events are signalled using
timer.device, but NetSurf seems to still be wanting to run code. We ask
Intuition to send IDCMP_INTUITICKS messages every 1/10s to our active
window to break us out of ami_get_msg to stop NetSurf stalling (the active
variable seems to have no real bearing on reality, but is supposed to
indicate that NetSurf wants control back ASAP, so we poll in that case).
ami_get_msg();
schedule_run();
schedule_run checks every event, really they need to be sorted so only
the first event needs to be run on each signal. */
if(active)
{
gui_multitask();
schedule_run();
}
else
{
ami_get_msg();
}
}
void gui_quit(void)
@ -940,7 +961,7 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
WA_CustomScreen,scrn,
WA_ReportMouse,TRUE,
WA_IDCMP,IDCMP_MENUPICK | IDCMP_MOUSEMOVE | IDCMP_MOUSEBUTTONS |
IDCMP_NEWSIZE | IDCMP_VANILLAKEY | IDCMP_RAWKEY | IDCMP_GADGETUP | IDCMP_IDCMPUPDATE,
IDCMP_NEWSIZE | IDCMP_VANILLAKEY | IDCMP_RAWKEY | IDCMP_GADGETUP | IDCMP_IDCMPUPDATE | IDCMP_INTUITICKS,
// WINDOW_IconifyGadget, TRUE,
WINDOW_NewMenu,menu,
WINDOW_HorizProp,1,

View File

@ -20,6 +20,7 @@
#include <exec/lists.h>
#include <exec/nodes.h>
#include "amiga/object.h"
#include "amiga/schedule.h"
struct MinList *NewObjList(void)
{
@ -64,6 +65,9 @@ void FreeObjList(struct MinList *objlist)
while(nnode=(struct nsObject *)(node->dtz_Node.mln_Succ))
{
if(node->Type == AMINS_CALLBACK)
ami_remove_timer_event((struct nscallback *)node->objstruct);
DelObject(node);
node=nnode;
}

View File

@ -20,7 +20,6 @@
#include "amiga/object.h"
#include "amiga/schedule.h"
#include <proto/exec.h>
#include <proto/timer.h>
/**
* Schedule a callback.
@ -47,8 +46,23 @@ void schedule(int t, void (*callback)(void *p), void *p)
nscb->tv.tv_sec = 0;
nscb->tv.tv_micro = t*10000;
while(nscb->tv.tv_micro >= 1000000)
{
nscb->tv.tv_sec++;
nscb->tv.tv_micro -= 1000000;
}
GetSysTime(&tv);
AddTime(&nscb->tv,&tv);
AddTime(&nscb->tv,&tv); // now contains time when event occurs
nscb->treq = AllocVec(sizeof(struct timerequest),MEMF_CLEAR);
*nscb->treq = *tioreq;
nscb->treq->tr_node.io_Command=TR_ADDREQUEST;
nscb->treq->tr_time.tv_sec=nscb->tv.tv_sec; // secs
nscb->treq->tr_time.tv_micro=nscb->tv.tv_micro; // micro
SendIO((struct IORequest *)nscb->treq);
nscb->callback = callback;
nscb->p = p;
@ -76,9 +90,11 @@ void schedule_remove(void (*callback)(void *p), void *p)
while(nnode=(struct nsObject *)(node->dtz_Node.mln_Succ))
{
nscb = node->objstruct;
if(!nscb) continue;
if((nscb->callback == callback) && (nscb->p == p))
{
ami_remove_timer_event(nscb);
DelObject(node);
}
@ -115,6 +131,7 @@ void schedule_run(void)
{
callback = nscb->callback;
p = nscb->p;
ami_remove_timer_event(nscb);
DelObject(node);
callback(p);
}
@ -123,3 +140,17 @@ void schedule_run(void)
node=nnode;
}
}
void ami_remove_timer_event(struct nscallback *nscb)
{
if(!nscb) return;
if(nscb->treq)
{
if(CheckIO((struct IORequest *)nscb->treq)==0)
AbortIO((struct IORequest *)nscb->treq);
WaitIO((struct IORequest *)nscb->treq);
FreeVec(nscb->treq);
}
}

View File

@ -19,13 +19,18 @@
#ifndef AMIGA_SCHEDULE_H
#define AMIGA_SCHEDULE_H
#include <exec/lists.h>
#include <proto/timer.h>
struct MinList *schedule_list;
struct timerequest *tioreq;
struct nscallback
{
struct timeval tv;
void *callback;
void *p;
struct timerequest *treq;
};
void ami_remove_timer_event(struct nscallback *nscb);
#endif