From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00,URI_HEX autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,e53617e6821a1c7e X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-05-01 05:33:38 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!headwall.stanford.edu!fu-berlin.de!uni-berlin.de!212.97.175.23!not-for-mail From: Jano Newsgroups: comp.lang.ada Subject: Re: Suspicious reentrant semaphore Date: Thu, 1 May 2003 14:33:52 +0200 Message-ID: References: NNTP-Posting-Host: 212.97.175.23 X-Trace: fu-berlin.de 1051792416 13495403 212.97.175.23 (16 [49872]) X-Newsreader: MicroPlanet Gravity v2.50 Xref: archiver1.google.com comp.lang.ada:36801 Date: 2003-05-01T14:33:52+02:00 List-Id: Dmitry A. Kazakov dice... > The requeue statement does the trick in case you want to use a parameter > value in a barrier. You could add one more private entry and requeue to it > if the task is not the owner: Dmitry: I love this suggestion specially because is the first time I'm going to employ requeue (never before I faced the necessity). Here is the new version of my package. I've also slightly changed the release logic to obtain exceptions instead of deadlocks in case of wrong use: ---------------- SPEC --------------------- with Ada.Finalization; use Ada; with Ada.Task_identification; package Adagio.Monitor is use Ada.Task_identification; Use_error : Exception; protected type Semaphore is entry P (Owner : Task_id); procedure V (Owner : Task_id); private entry Safe_P (Owner : Task_id); Caller : Task_id := Null_task_id; -- Requester In_use : Natural := 0; -- Times requested end Semaphore; type Semaphore_access is access all Semaphore; -- Use: -- S : aliased Semaphore; -- declare -- M : Object(S'access); -- begin -- Exclusive_work; -- end; type Object (S : access Semaphore) is new Finalization.Limited_Controlled with null record; procedure Initialize (this : in out Object); procedure Finalize (this : in out Object); end Adagio.Monitor; ------------------ BODY ----------------------- package body Adagio.Monitor is protected body Semaphore is entry P (Owner : Task_id) when true is begin if Owner = Caller then In_use := In_use + 1; else requeue Safe_P with abort; end if; end P; entry Safe_P (Owner : Task_id) when In_use = 0 is begin Caller := Owner; In_use := 1; end Safe_P; procedure V (Owner : Task_id) is begin if Owner /= Caller then raise Use_error; else In_use:= In_use - 1; if In_use = 0 then Caller := Null_task_id; end if; end if; end V; end Semaphore; -- Get procedure Initialize(this: in out Object) is begin this.S.P (Current_task); end Initialize; -- Release procedure Finalize(this: in out Object) is begin this.S.V (Current_task); end Finalize; end Adagio.Monitor; -- ------------------------- Jano 402450.at.cepsz.unizar.es -------------------------