[M3devel] to share code between Join and AlertJoin or not?
Jay K
jay.krell at cornell.edu
Sat Dec 12 16:25:44 CET 2009
Here's a case where it is not clear if the code is worth sharing:
Join and AlertJoin share XJoin:
PROCEDURE XJoin (t: T; alertable: BOOLEAN): REFANY RAISES {Alerted} =
VAR (* The order of the handles is important. *)
handles := ARRAY [0..1] OF HANDLE {t.act.handle, NIL(*alertEvent*)};
wait: DWORD;
BEGIN
IF t.joined # 0 THEN Die(ThisLine(), "attempt to join with thread twice") END;
IF alertable THEN
handles[1] := GetActivation().alertEvent;
END;
wait := WaitForMultipleObjects(1 + ORD(alertable), ADR(handles[0]), 0, INFINITE);
<* ASSERT wait # WAIT_TIMEOUT *>
<* ASSERT wait = WAIT_OBJECT_0 OR wait = (WAIT_OBJECT_0 + 1) *>
IF wait = WAIT_OBJECT_0 THEN
t.joined := 1;
RETURN t.result;
ELSE
<* ASSERT wait = WAIT_OBJECT_0 + 1 *>
<* ASSERT alertable *>
RAISE Alerted;
END;
END XJoin;
PROCEDURE Join(t: T): REFANY =
<*FATAL Alerted*>
BEGIN
IF DEBUG THEN ThreadDebug.Join(t); END;
RETURN XJoin(t, alertable := FALSE);
END Join;
PROCEDURE AlertJoin(t: T): REFANY RAISES {Alerted} =
BEGIN
IF DEBUG THEN ThreadDebug.AlertJoin(t); END;
RETURN XJoin(t, alertable := TRUE);
END AlertJoin;
OR without code sharing, it'd go like:
PROCEDURE Join(t: T): REFANY =
VAR wait: DWORD;
BEGIN
IF t.joined # 0 THEN Die(ThisLine(), "attempt to join with thread twice") END;
wait := WaitForSingleObject(t.act.handle, INFINITE);
<* ASSERT wait = WAIT_OBJECT_0 *>
t.joined := 1;
RETURN t.result;
END Join;
PROCEDURE AlertJoin (t: T): REFANY RAISES {Alerted} =
VAR (* The order of the handles is important. *)
handles := ARRAY [0..1] OF HANDLE {t.act.handle, GetActivation().alertEvent};
wait: DWORD;
BEGIN
IF t.joined # 0 THEN Die(ThisLine(), "attempt to join with thread twice") END;
wait := WaitForMultipleObjects(2, ADR(handles[0]), 0, INFINITE);
<* ASSERT wait # WAIT_TIMEOUT *>
<* ASSERT wait = WAIT_OBJECT_0 OR wait = (WAIT_OBJECT_0 + 1) *>
IF wait = WAIT_OBJECT_0 THEN
t.joined := 1;
RETURN t.result;
ELSE
<* ASSERT wait = WAIT_OBJECT_0 + 1 *>
RAISE Alerted;
END;
END AlertJoin;
anyone have strong feelings either way?
If we used win32 alertable waits, then the case for code sharing would be stronger, it'd go like:
PROCEDURE XJoin (t: T; alertable: BOOLEAN): REFANY RAISES {Alerted} =
VAR wait: DWORD;
BEGIN
IF t.joined # 0 THEN Die(ThisLine(), "attempt to join with thread twice") END;
wait := WaitForSingleObjectEx(t.act.handle, INFINITE, ORD(alertable));
<* ASSERT wait = WAIT_OBJECT_0 OR wait = WAIT_IO_COMPLETION*>
IF wait = WAIT_OBJECT_0 THEN
t.joined := 1;
RETURN t.result;
ELSE
<* ASSERT alertable *>
RAISE Alerted;
END;
END XJoin;
- Jay
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20091212/92a0868b/attachment-0001.html>
More information about the M3devel
mailing list