timer and Mac frame changes to avoid ptr chains that intefere with GC-based accounting

svn: r5794
This commit is contained in:
Matthew Flatt 2007-03-19 22:06:13 +00:00
parent cbe41955f1
commit 8a04cf4fb3
5 changed files with 84 additions and 55 deletions

View File

@ -1405,7 +1405,10 @@ XSRC_EXTRA_DIR_wx_mac = macxsrc
gen-deps:
../../mzscheme/mzscheme@MMM@ -qr "$(srcdir)/gen-deps.ss"
@INCLUDEDEP@ mrmain.dd
@INCLUDEDEP@ mred.dd
@INCLUDEDEP@ mredx.dd
@INCLUDEDEP@ mredmac.dd
@INCLUDEDEP@ wb_item.dd
@INCLUDEDEP@ wb_panel.dd
@INCLUDEDEP@ wb_timer.dd

View File

@ -244,7 +244,7 @@ static MrEdContext *mred_only_context;
static int only_context_just_once = 0;
static MrEdContext *user_main_context;
static MrEdContextFramesRef mred_frames; /* list of all frames (weak link to invisible ones) */
static wxTimer *mred_timers;
static Scheme_Hash_Table *timer_contexts;
int mred_eventspace_param;
int mred_event_dispatch_param;
Scheme_Type mred_eventspace_type;
@ -306,6 +306,7 @@ static int mark_eventspace_val(void *p)
gcMARK_TYPED(Scheme_Thread_Cell_Table *, c->main_break_cell);
gcMARK_TYPED(wxTimer *, c->timer);
gcMARK_TYPED(wxTimer **, c->timers);
gcMARK_TYPED(void *, c->alt_data);
@ -339,6 +340,7 @@ static int fixup_eventspace_val(void *p)
gcFIXUP_TYPED(Scheme_Thread_Cell_Table *, c->main_break_cell);
gcFIXUP_TYPED(wxTimer *, c->timer);
gcFIXUP_TYPED(wxTimer **, c->timers);
gcFIXUP_TYPED(void *, c->alt_data);
@ -675,11 +677,10 @@ static void kill_eventspace(Scheme_Object *ec, void *)
}
{
wxTimer *t, *next;
for (t = mred_timers; t; t = next) {
next = t->next;
if (t->context == (void *)c)
t->Stop();
wxTimer *t;
while (c->timers) {
t = c->timers;
t->Stop();
}
}
@ -865,6 +866,24 @@ static void UnchainContextsList()
}
}
static wxTimer *GlobalFirstTimer()
{
wxTimer *timer = NULL;
int i;
for (i = timer_contexts->size; i--; ) {
if (timer_contexts->vals[i]) {
MrEdContext *c = (MrEdContext *)timer_contexts->keys[i];
if (c->ready && c->timers) {
if (!timer)
timer = c->timers;
else if (c->timers->expiration < timer->expiration)
timer = c->timers;
}
}
}
return timer;
}
#ifdef wx_xt
void wxUnhideAllCursors()
{
@ -980,7 +999,6 @@ void *MrEdForEachFrame(ForEachFrameProc fp, void *data)
static int check_eventspace_inactive(void *_c)
{
MrEdContext *c = (MrEdContext *)_c;
wxTimer *timer = mred_timers;
if (c->nested_avail)
return 0;
@ -992,11 +1010,8 @@ static int check_eventspace_inactive(void *_c)
return 0;
/* Any running timers for the eventspace? */
while (timer) {
if (((MrEdContext *)timer->context) == c)
return 0;
timer = timer->next;
}
if (c->timers)
return 0;
/* Any top-level windows visible in this eventspace */
{
@ -1053,16 +1068,12 @@ int mred_in_restricted_context()
static wxTimer *TimerReady(MrEdContext *c)
{
wxTimer *timer = mred_timers;
wxTimer *timer;
if (c) {
while (timer && (timer->context != (void *)c)) {
timer = timer->next;
}
timer = c->timers;
} else {
while (timer && !((MrEdContext *)timer->context)->ready) {
timer = timer->next;
}
timer = GlobalFirstTimer();
}
if (timer) {
@ -1529,7 +1540,9 @@ static int try_dispatch(Scheme_Object *do_it)
if (try_q_callback(do_it, 2))
return 1;
if ((timer = TimerReady(NULL))) {
timer = TimerReady(NULL);
if (timer) {
if (!do_it)
return 1;
if (SCHEME_FALSEP(do_it))
@ -1738,11 +1751,9 @@ static void MrEdSleep(float secs, void *fds)
now = scheme_get_inexact_milliseconds();
{
wxTimer *timer = mred_timers;
wxTimer *timer;
while (timer && !((MrEdContext *)timer->context)->ready) {
timer = timer->next;
}
timer = GlobalFirstTimer();
if (timer) {
double done = timer->expiration;
@ -1817,7 +1828,7 @@ Bool wxTimer::Start(int millisec, Bool _one_shot)
{
double now;
if (prev || next || (mred_timers == this))
if (prev || next || (((MrEdContext *)context)->timers == this))
return FALSE;
if (((MrEdContext *)context)->killed)
@ -1831,8 +1842,8 @@ Bool wxTimer::Start(int millisec, Bool _one_shot)
now = scheme_get_inexact_milliseconds();
expiration = now + interval;
if (mred_timers) {
wxTimer *t = mred_timers;
if (((MrEdContext *)context)->timers) {
wxTimer *t = ((MrEdContext *)context)->timers;
while (1) {
int later;
@ -1846,7 +1857,7 @@ Bool wxTimer::Start(int millisec, Bool _one_shot)
if (prev)
prev->next = this;
else
mred_timers = this;
((MrEdContext *)context)->timers = this;
return TRUE;
}
@ -1858,8 +1869,10 @@ Bool wxTimer::Start(int millisec, Bool _one_shot)
}
t = t->next;
}
} else
mred_timers = this;
} else {
((MrEdContext *)context)->timers = this;
scheme_hash_set(timer_contexts, (Scheme_Object *)context, scheme_true);
}
return TRUE;
}
@ -1867,8 +1880,11 @@ Bool wxTimer::Start(int millisec, Bool _one_shot)
void wxTimer::Dequeue(void)
{
if (!prev) {
if (mred_timers == this)
mred_timers = next;
if (((MrEdContext *)context)->timers == this) {
((MrEdContext *)context)->timers = next;
if (!next)
scheme_hash_set(timer_contexts, (Scheme_Object *)context, NULL);
}
}
if (prev)
@ -2791,11 +2807,6 @@ Scheme_Object *OBJDump(int, Scheme_Object *[])
(long)GC_changing_list_current - (long)GC_changing_list_start);
# endif
wxTimer *timer;
for (c = 0, timer = mred_timers; timer; timer = timer->next)
c++;
PRINT_IT("Timers: %d\n", c);
Scheme_Thread *p;
for (c = 0, p = scheme_first_thread; p; p = p->next)
c++;
@ -3232,7 +3243,8 @@ wxFrame *MrEdApp::OnInit(void)
#endif
wxREGGLOB(mred_frames);
wxREGGLOB(mred_timers);
wxREGGLOB(timer_contexts);
timer_contexts = scheme_make_hash_table(SCHEME_hash_ptr);
#ifdef LIBGPP_REGEX_HACK
new WXGC_PTRS Regex("a", 0);

View File

@ -68,6 +68,8 @@ typedef struct MrEdContext {
wxTimer *timer;
MrEdEvent event;
wxTimer *timers;
/* Alternate condition for nested event loop pending some condition */
wxDispatch_Check_Fun alternate;
void *alt_data;

View File

@ -1075,15 +1075,19 @@ void wxFrame::Show(Bool show)
cUserHidden = !show;
if (window_parent) {
wxChildList *cl;
cl = window_parent->GetChildren();
cl->Show(this, show);
}
if (cParentArea) {
wxChildList *cl;
cl = cParentArea->Windows();
cl->Show(this, show);
/* Don't try to adjust the screen's window list, because it
doesn't keep a list of children. */
if (0) {
if (window_parent) {
wxChildList *cl;
cl = window_parent->GetChildren();
cl->Show(this, show);
}
if (cParentArea) {
wxChildList *cl;
cl = cParentArea->Windows();
cl->Show(this, show);
}
}
tlw = wxTopLevelWindows(ContextWindow());
tlw->Show(this, show);

View File

@ -152,16 +152,24 @@ wxWindow::wxWindow // Constructor (given parentScreen; i.e., this is frame)
InitDefaults();
cParentArea = parentScreen->ClientArea();
wl = cParentArea->Windows();
wl->Append(this);
/* See note on screen's list of children below */
if (0) {
wl = cParentArea->Windows();
wl->Append(this);
}
window_parent = parentScreen;
window_parent->AddChild(this);
// Frames are initially hidden!
cl = window_parent->GetChildren();
cl->Show(this, FALSE);
wl->Show(this, FALSE);
/* The screen doesn't realy have a use for a list of children,
and keeping this list means that there's a GC path from
any frame to any other frame (which is bad for GC accounting) */
if (0) {
window_parent->AddChild(this);
// Frames are initially hidden!
cl = window_parent->GetChildren();
cl->Show(this, FALSE);
wl->Show(this, FALSE);
}
cMacDC = NULL; // will set cMacDC later