From patchwork Fri Oct 5 14:21:49 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [Ada] Fix race condition in freeing tasks Date: Fri, 05 Oct 2012 04:21:49 -0000 From: Arnaud Charlet X-Patchwork-Id: 189489 Message-Id: <20121005142149.GA5858@adacore.com> To: gcc-patches@gcc.gnu.org This patch fixes a subtle race condition where the master task and the child task may free the child task concurrently. Found by code reading. Tested on x86_64-pc-linux-gnu, committed on trunk 2012-10-05 Arnaud Charlet * s-tassta.adb: Update comments. (Vulnerable_Complete_Master): If Free_On_Termination is set, do nothing, and let the task free itself if not already done. Index: s-tassta.adb =================================================================== --- s-tassta.adb (revision 192066) +++ s-tassta.adb (working copy) @@ -1905,7 +1905,16 @@ C := All_Tasks_List; P := null; while C /= null loop - if C.Common.Parent = Self_ID and then C.Master_of_Task >= CM then + -- If Free_On_Termination is set, do nothing here, and let + -- the task free itself if not already done, otherwise we + -- risk a race condition where Vulnerable_Free_Task is called + -- in the loop below, while the task calls Free_Task itself, + -- in Terminate_Task. + + if C.Common.Parent = Self_ID + and then C.Master_of_Task >= CM + and then not C.Free_On_Termination + then if P /= null then P.Common.All_Tasks_Link := C.Common.All_Tasks_Link; else @@ -2088,9 +2097,7 @@ -- is called from Expunge_Unactivated_Tasks. -- For tasks created by elaboration of task object declarations it is - -- called from the finalization code of the Task_Wrapper procedure. It is - -- also called from Ada.Unchecked_Deallocation, for objects that are or - -- contain tasks. + -- called from the finalization code of the Task_Wrapper procedure. procedure Vulnerable_Free_Task (T : Task_Id) is begin