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.9 required=5.0 tests=BAYES_00,XPRIO autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,a31b00ad713d92f9,start X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news2.google.com!news.glorb.com!news-peer-lilac.gradwell.net!not-for-mail From: "Phil Slater" Newsgroups: comp.lang.ada Subject: Impossible problem? A protected buffer to queue objects of a class-wide type Date: Wed, 11 Apr 2007 12:34:15 +0100 X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2900.3028 X-RFC2646: Format=Flowed; Original X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.3028 Message-ID: <461cc46d$1_1@glkas0286.greenlnk.net> X-Original-NNTP-Posting-Host: glkas0286.greenlnk.net NNTP-Posting-Host: 20.133.0.1 X-Trace: 1176291267 news.gradwell.net 757 dnews/20.133.0.1:44464 X-Complaints-To: news-abuse@gradwell.net Xref: g2news1.google.com comp.lang.ada:14907 Date: 2007-04-11T12:34:15+01:00 List-Id: I've hit a brick wall. Every strategy I try doesn't work. I need to write a generic package that exports a protected queue type that will act as a buffer for objects of a class-wide type. My strategy is that when objects join the queue they are copied onto the heap, and an access-to-class-wide value is put onto the queue (could be array-based or linked-list-based - I don't mind). To retrieve an item from the queue, an access-to-class-wide value is removed from the queue, the heap object it designates is copied onto the stack, the heap object is deallocated, then the copy is returned. The crux of the problem goes like this: (a) for the client code to retrieve an item, it needs to call a function; it can't be done through a procedure or entry "out" parameter since I can't declare an uninitialised variable of the class-wide type to pass as an actual parameter. So the client code needs to do something like this: declare Next_In_Line : Item'class := My_Buffer.Dequeue; -- My_Buffer is the protected queue (b) To support this call, Dequeue must be written as a function. As such, it cannot change the protected queue. What I need is the "entry" functionality, since I want the Dequeue to wait if the queue is empty, and I want the item to be removed from the queue as well as retrieved. (c) In a non-concurrent environment, I would simply write two separate operations on the queue: a function Read_Next_Item and a procedure Delete_Next_Item, which the client code would call in turn. However, that's no good in a concurrent environment - two tasks could both call Read_Next_Item before the first has had a chance to call Delete_Next_Item, so the same item is read twice and the following item is skipped. I really do want all the heap operations through the access-to-class-wide type to be hidden away in the package - I did consider writing a protected buffer with an entry whose out parameter was an access-to-class-wide type, but this is highly unsatisfactory as it puts the onus for deallocating heap space into the client code - very messy. I cannot see a way through this problem, and am astounded that a language of this calibre seems to have rules that conspire together to make it appear impossible. What have I missed?