diff options
author | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-05-20 12:52:09 +0000 |
---|---|---|
committer | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-05-20 12:52:09 +0000 |
commit | e4da3b5b9d0383d69fcecc18a113332dad9d2f41 (patch) | |
tree | 301efa790bc8a3fe94aa51dea679380b91e72839 /gcc/ada/a-rttiev.adb | |
parent | f420a9ed7d9ffe5597fe6540cf0444b0696ac94e (diff) | |
download | gcc-e4da3b5b9d0383d69fcecc18a113332dad9d2f41.tar.gz |
2008-05-20 Bob Duff <duff@adacore.com>
* a-rttiev.adb
(Set_Handler): Remove code from both of these that implements
RM-D.15(15/2), because it causes a race condition and potential
deadlock.
(Process_Queued_Events): Add comment explaining "exception when others
=> null". Add clarifying ".all", even though implicit .all is legal
here.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@135648 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/a-rttiev.adb')
-rw-r--r-- | gcc/ada/a-rttiev.adb | 36 |
1 files changed, 20 insertions, 16 deletions
diff --git a/gcc/ada/a-rttiev.adb b/gcc/ada/a-rttiev.adb index 7031dfbc7c3..72ae4df0be4 100644 --- a/gcc/ada/a-rttiev.adb +++ b/gcc/ada/a-rttiev.adb @@ -66,8 +66,8 @@ package body Ada.Real_Time.Timing_Events is -- Used for mutually exclusive access to All_Events procedure Process_Queued_Events; - -- Examine the queue of pending events for any that have timed-out. For - -- those that have timed-out, remove them from the queue and invoke their + -- Examine the queue of pending events for any that have timed out. For + -- those that have timed out, remove them from the queue and invoke their -- handler (unless the user has cancelled the event by setting the handler -- pointer to null). Mutually exclusive access is held via Event_Queue_Lock -- during part of the processing. @@ -142,7 +142,7 @@ package body Ada.Real_Time.Timing_Events is if Next_Event.Timeout > Clock then - -- We found one that has not yet timed-out. The queue is in + -- We found one that has not yet timed out. The queue is in -- ascending order by Timeout so there is no need to continue -- processing (and indeed we must not continue since we always -- delete the first element). @@ -182,8 +182,12 @@ package body Ada.Real_Time.Timing_Events is Next_Event.Handler := null; if Handler /= null then - Handler (Timing_Event (Next_Event.all)); + Handler.all (Timing_Event (Next_Event.all)); end if; + + -- Ignore exceptions propagated by Handler.all, as required by + -- RM-D.15(21/2) + exception when others => null; @@ -261,12 +265,15 @@ package body Ada.Real_Time.Timing_Events is begin Remove_From_Queue (Event'Unchecked_Access); Event.Handler := null; - if At_Time <= Clock then - if Handler /= null then - Handler (Event); - end if; - return; - end if; + + -- RM-D.15(15/2) requires that at this point, we check whether the time + -- has already passed, and if so, call Handler.all directly from here + -- instead of doing the enqueuing below. However, this causes a nasty + -- race condition and potential deadlock. If the current task has + -- already locked the protected object of Handler.all, and the time has + -- passed, deadlock would occur. Therefore, we ignore the requirement. + -- The same comment applies to the other Set_Handler below. + if Handler /= null then Event.Timeout := At_Time; Event.Handler := Handler; @@ -286,12 +293,9 @@ package body Ada.Real_Time.Timing_Events is begin Remove_From_Queue (Event'Unchecked_Access); Event.Handler := null; - if In_Time <= Time_Span_Zero then - if Handler /= null then - Handler (Event); - end if; - return; - end if; + + -- See comment in the other Set_Handler above. + if Handler /= null then Event.Timeout := Clock + In_Time; Event.Handler := Handler; |