"xemacs(a)xemacs.org" removed; I don't think this is appropriate for the
newsgroup.
Also, ignore my previous post... :^)
>>>> "Andy" == Andy Piper
<andy(a)xemacs.org> writes:
Andy> This seems totally bogus since you are freeing the next
Andy> timeout without removing it from the list.
Right, and this should cause an exception.
Andy> I think what you are actually achieving is not freeing the
Andy> timeout in question, so my guess is from the comment than
Andy> having been free'd XEmacs still trys to convert it to an
Andy> event somehow.
I don't think so. The only way the rest of XEmacs ever refers to
these things is to pop them off the stack. I think what's happening
here is that somebody wrote some code expecting a queue discipline
from completed timeouts, but actually completed timeouts are in a
stack. If code called by timeout A "blocks" waiting for timeout B to
occur, then B will have already been popped from the stack. Oops!
But with Sinisa's patch, since the Blocktype allocator also uses the
stack discipline, current->next is going to be the next block
allocated. I'm not sure I really believe this ;-) but in theory
Sinisa's patch could (1) drop timeout C on the floor, and (2) allocate
timeout B into the timeout struct previously occupied by C. Then (3)
timeout A then B happen, and the top of stack looks like B -> A -> B.
(Of course it's circular, but this may not matter depending on the
details of the allocator ... I'm not sure how this would work. And
having multiple completed timeouts should generally be a rare thing,
anyway.)
Try this patch instead. Builds and runs (passes make check) for me,
but basically untested. N.B. I'm not sure we shouldn't try to find
and fix the code that expects queue behavior.
Index: src/ChangeLog
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/ChangeLog,v
retrieving revision 1.290.2.31
diff -u -U0 -r1.290.2.31 ChangeLog
--- src/ChangeLog 7 Nov 2002 06:04:21 -0000 1.290.2.31
+++ src/ChangeLog 13 Nov 2002 08:12:43 -0000
@@ -0,0 +1,9 @@
+2002-11-13 Stephen J. Turnbull <stephen(a)xemacs.org>
+
+ * event-Xt.c (Xt_timeout):
+ (Xt_timeout_callback):
+ (emacs_Xt_add_timeout):
+ (emacs_Xt_remove_timeout):
+ (Xt_timeout_to_emacs_event):
+ Turn completed_timeouts from a stack into a queue.
+
Index: src/event-Xt.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/event-Xt.c,v
retrieving revision 1.47.2.2
diff -u -r1.47.2.2 event-Xt.c
--- src/event-Xt.c 31 Oct 2002 15:07:39 -0000 1.47.2.2
+++ src/event-Xt.c 13 Nov 2002 08:12:53 -0000
@@ -2009,12 +2009,14 @@
/* Xt interval id's might not fit into an int (they're pointers, as it
happens), so we need to provide a conversion list. */
+/* pending_timeouts is a set (unordered), implemented as a stack.
+ completed_timeouts* is a queue. */
static struct Xt_timeout
{
int id;
XtIntervalId interval_id;
struct Xt_timeout *next;
-} *pending_timeouts, *completed_timeouts;
+} *pending_timeouts, *completed_timeouts_head, *completed_timeouts_tail;
static struct Xt_timeout_blocktype
{
@@ -2027,7 +2029,7 @@
{
struct Xt_timeout *timeout = (struct Xt_timeout *) closure;
struct Xt_timeout *t2 = pending_timeouts;
- /* Remove this one from the list of pending timeouts */
+ /* Remove this one from the set of pending timeouts */
if (t2 == timeout)
pending_timeouts = pending_timeouts->next;
else
@@ -2036,9 +2038,13 @@
assert (t2->next);
t2->next = t2->next->next;
}
- /* Add this one to the list of completed timeouts */
- timeout->next = completed_timeouts;
- completed_timeouts = timeout;
+ /* Add this one to the queue of completed timeouts */
+ timeout->next = NULL;
+ if (completed_timeouts_head)
+ completed_timeouts_tail->next = timeout;
+ else
+ completed_timeouts_head = timeout;
+ completed_timeouts_tail = timeout;
}
static int
@@ -2093,24 +2099,27 @@
XtRemoveTimeOut (timeout->interval_id);
}
- /* It could be that the Xt call back was already called but we didn't convert
- into an Emacs event yet */
- if (!timeout && completed_timeouts)
+ /* It could be that Xt_timeout_callback was already called but we didn't
+ convert into an Emacs event yet */
+ if (!timeout && completed_timeouts_head)
{
- /* Code duplication! */
- if (id == completed_timeouts->id)
+ /* Thank God for code duplication! */
+ if (id == completed_timeouts_head->id)
{
- timeout = completed_timeouts;
- completed_timeouts = completed_timeouts->next;
+ timeout = completed_timeouts_head;
+ completed_timeouts_head = completed_timeouts_head->next;
+ /* this may not be necessary? */
+ if (!completed_timeouts_head) completed_timeouts_tail = NULL;
}
else
{
- t2 = completed_timeouts;
+ t2 = completed_timeouts_head;
while (t2->next && t2->next->id != id) t2 = t2->next;
- if ( t2->next) /*found it */
+ if (t2->next) /* found it */
{
timeout = t2->next;
t2->next = t2->next->next;
+ if (!t2->next) completed_timeouts_tail = t2;
}
}
}
@@ -2125,9 +2134,11 @@
static void
Xt_timeout_to_emacs_event (Lisp_Event *emacs_event)
{
- struct Xt_timeout *timeout = completed_timeouts;
+ struct Xt_timeout *timeout = completed_timeouts_head;
assert (timeout);
- completed_timeouts = completed_timeouts->next;
+ completed_timeouts_head = completed_timeouts_head->next;
+ /* probably unnecessary */
+ if (!completed_timeouts_head) completed_timeouts_tail = NULL;
emacs_event->event_type = timeout_event;
/* timeout events have nil as channel */
emacs_event->timestamp = 0; /* #### wrong!! */
@@ -2699,7 +2710,7 @@
we_didnt_get_an_event:
while (NILP (dispatch_event_queue) &&
- !completed_timeouts &&
+ !completed_timeouts_head &&
!fake_event_occurred &&
!process_events_occurred &&
!tty_events_occurred)
@@ -2753,7 +2764,7 @@
if (!Xt_tty_to_emacs_event (emacs_event))
goto we_didnt_get_an_event;
}
- else if (completed_timeouts)
+ else if (completed_timeouts_head)
Xt_timeout_to_emacs_event (emacs_event);
else if (fake_event_occurred)
{
@@ -3412,7 +3423,8 @@
{
timeout_id_tick = 1;
- pending_timeouts = 0;
- completed_timeouts = 0;
+ pending_timeouts = NULL;
+ completed_timeouts_head = NULL; /* queue is empty */
+ completed_timeouts_tail = NULL; /* just to be picky */
event_stream = Xt_event_stream;
--
Institute of Policy and Planning Sciences
http://turnbull.sk.tsukuba.ac.jp
University of Tsukuba Tennodai 1-1-1 Tsukuba 305-8573 JAPAN
Ask not how you can "do" free software business;
ask what your business can "do for" free software.