<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Verdana
}
--></style>
</head>
<body class='hmmessage'>
Here's a case where it is not clear if the code is worth sharing:<BR>
<BR>
<BR>
Join and AlertJoin share XJoin:<BR>
<BR>
<BR>
PROCEDURE XJoin (t: T; alertable: BOOLEAN): REFANY RAISES {Alerted} =<BR> VAR (* The order of the handles is important. *)<BR> handles := ARRAY [0..1] OF HANDLE {t.act.handle, NIL(*alertEvent*)};<BR> wait: DWORD;<BR> BEGIN<BR> IF t.joined # 0 THEN Die(ThisLine(), "attempt to join with thread twice") END;<BR> IF alertable THEN<BR> handles[1] := GetActivation().alertEvent;<BR> END;<BR> wait := WaitForMultipleObjects(1 + ORD(alertable), ADR(handles[0]), 0, INFINITE);<BR> <* ASSERT wait # WAIT_TIMEOUT *><BR> <* ASSERT wait = WAIT_OBJECT_0 OR wait = (WAIT_OBJECT_0 + 1) *><BR> IF wait = WAIT_OBJECT_0 THEN<BR> t.joined := 1;<BR> RETURN t.result;<BR> ELSE<BR> <* ASSERT wait = WAIT_OBJECT_0 + 1 *><BR> <* ASSERT alertable *><BR> RAISE Alerted;<BR> END;<BR> END XJoin;<BR>
<BR>
<BR>
PROCEDURE Join(t: T): REFANY =<BR> <*FATAL Alerted*><BR> BEGIN<BR> IF DEBUG THEN ThreadDebug.Join(t); END;<BR> RETURN XJoin(t, alertable := FALSE);<BR> END Join;<BR>
PROCEDURE AlertJoin(t: T): REFANY RAISES {Alerted} =<BR> BEGIN<BR> IF DEBUG THEN ThreadDebug.AlertJoin(t); END;<BR> RETURN XJoin(t, alertable := TRUE);<BR> END AlertJoin;<BR>
<BR>
<BR>
OR without code sharing, it'd go like:<BR>
<BR>
<BR>
PROCEDURE Join(t: T): REFANY =<BR> VAR wait: DWORD;<BR> BEGIN<BR> IF t.joined # 0 THEN Die(ThisLine(), "attempt to join with thread twice") END;<BR> wait := WaitForSingleObject(t.act.handle, INFINITE);<BR> <* ASSERT wait = WAIT_OBJECT_0 *><BR> t.joined := 1;<BR> RETURN t.result;<BR> END Join;<BR>
<BR>
<BR>PROCEDURE AlertJoin (t: T): REFANY RAISES {Alerted} =<BR> VAR (* The order of the handles is important. *)<BR> handles := ARRAY [0..1] OF HANDLE {t.act.handle, GetActivation().alertEvent};<BR> wait: DWORD;<BR> BEGIN<BR> IF t.joined # 0 THEN Die(ThisLine(), "attempt to join with thread twice") END;<BR> wait := WaitForMultipleObjects(2, ADR(handles[0]), 0, INFINITE);<BR> <* ASSERT wait # WAIT_TIMEOUT *><BR> <* ASSERT wait = WAIT_OBJECT_0 OR wait = (WAIT_OBJECT_0 + 1) *><BR> IF wait = WAIT_OBJECT_0 THEN<BR> t.joined := 1;<BR> RETURN t.result;<BR> ELSE<BR> <* ASSERT wait = WAIT_OBJECT_0 + 1 *><BR> RAISE Alerted;<BR> END;<BR> END AlertJoin;<BR><BR>
<BR>anyone have strong feelings either way?<BR>
<BR>
<BR>
If we used win32 alertable waits, then the case for code sharing would be stronger, it'd go like:<BR>
<BR>
<BR>
<BR>
PROCEDURE XJoin (t: T; alertable: BOOLEAN): REFANY RAISES {Alerted} =<BR> VAR wait: DWORD;<BR> BEGIN<BR> IF t.joined # 0 THEN Die(ThisLine(), "attempt to join with thread twice") END;<BR> wait := WaitForSingleObjectEx(t.act.handle, INFINITE, ORD(alertable));<BR> <* ASSERT wait = WAIT_OBJECT_0 OR wait = WAIT_IO_COMPLETION*><BR> IF wait = WAIT_OBJECT_0 THEN<BR> t.joined := 1;<BR> RETURN t.result;<BR> ELSE<BR> <* ASSERT alertable *><BR> RAISE Alerted;<BR> END;<BR> END XJoin;<BR>
<BR>
<BR> - Jay<BR> </body>
</html>