/usr/share/ada/adainclude/gnatcoll/gnatcoll-refcount-weakref.ads is in libgnatcoll1.6-dev 1.6gpl2014-6.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | ------------------------------------------------------------------------------
-- G N A T C O L L --
-- --
-- Copyright (C) 2010-2014, AdaCore --
-- --
-- This library is free software; you can redistribute it and/or modify it --
-- under terms of the GNU General Public License as published by the Free --
-- Software Foundation; either version 3, or (at your option) any later --
-- version. This library is distributed in the hope that it will be useful, --
-- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- --
-- TABILITY or FITNESS FOR A PARTICULAR PURPOSE. --
-- --
-- --
-- --
-- --
-- --
-- You should have received a copy of the GNU General Public License and --
-- a copy of the GCC Runtime Library Exception along with this program; --
-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
-- <http://www.gnu.org/licenses/>. --
-- --
------------------------------------------------------------------------------
-- By definition, an object can never be freed while there are references
-- to it.
-- However, this simple scheme fails in some cases. For instance, imagine
-- you want to cache some refcounted type into a map. The map would then
-- own a reference to the object, which is thus never freed while the map
-- exists (presumably for the life of your application).
-- A solution to this problem is the notion of "weak reference": these act
-- as containers that point to the element, without owning a reference to
-- them. When the element is destroyed (because its refcount can now reach
-- 0), the container is set to a special state that indicates the element
-- no longer exists.
-- With this scheme, the cache will still contain entries for the elements,
-- but those entries will return a Null_Ref when accessed.
pragma Ada_05;
package GNATCOLL.Refcount.Weakref is
type Weak_Refcounted
is abstract new GNATCOLL.Refcount.Refcounted with private;
-- A special refcounted type, which can manipulate weak references
overriding procedure Free (Self : in out Weak_Refcounted);
-- If you need to override this procedure in your own code, you need to
-- make sure you correctly call this inherited procedure.
type Proxy is new GNATCOLL.Refcount.Refcounted with record
Proxied : Refcounted_Access;
end record;
package Proxy_Pointers is new Smart_Pointers (Proxy);
-- An internal, implementation type.
--
-- A weak ref acts as a smart pointed with two level of indirection:
-- type My_Type is new GNATCOLL.Refcount.Weakref.Refcounted with ...;
-- package P is new Weakref_Pointers (My_Type);
-- R : P.Ref;
-- WR : P.Weak_Ref;
-- R now takes care of the reference counting for R.Data.
-- R.Data is an access to My_Type, freed automatically.
--
-- WR now takes care of the reference counting for a Proxy, whose Proxied
-- is set to R.Data. This does not hold a reference to R.Data. However,
-- R.Data holds a reference to the proxy.
-- As a result, the proxy is never freed while R.Data exists. But the
-- latter can be destroyed even when the proxy exists.
generic
type Encapsulated is abstract new Weak_Refcounted with private;
package Weakref_Pointers is
package Pointers is new Smart_Pointers (Encapsulated);
subtype Encapsulated_Access is Pointers.Encapsulated_Access;
subtype Ref is Pointers.Ref;
Null_Ref : constant Ref := Pointers.Null_Ref;
procedure Set (Self : in out Ref; Data : Encapsulated'Class)
renames Pointers.Set;
procedure Set (Self : in out Ref; Data : access Encapsulated'Class)
renames Pointers.Set;
function Get (P : Ref) return Encapsulated_Access
renames Pointers.Get;
function "=" (P1, P2 : Ref) return Boolean
renames Pointers."=";
function "=" (P1, P2 : Pointers.Encapsulated_Access) return Boolean
renames Pointers."=";
-- The manipulation of the smart pointers
subtype Weak_Ref is Proxy_Pointers.Ref;
Null_Weak_Ref : constant Weak_Ref := Weak_Ref (Proxy_Pointers.Null_Ref);
function "=" (P1, P2 : Weak_Ref) return Boolean
renames Proxy_Pointers."=";
function Get_Weak_Ref (Self : Ref'Class) return Weak_Ref;
-- Return a weak reference to Self.
-- It does not hold a reference to Self, which means that Self could be
-- destroyed while the weak reference exists. However, this will not
-- result
-- in a Storage_Error when you access the reference.
function Was_Freed (Self : Weak_Ref'Class) return Boolean;
-- True if the weakly referenced element was freed (thus Get would
-- return Null_Ref). It is more efficient to use this function than
-- compare the result of Get with Null_Ref, since the latter will need
-- to play with refcounting.
function Get (Self : Weak_Ref'Class) return Ref;
procedure Get (Self : Weak_Ref'Class; R : out Ref'Class);
-- Return the weakly referenced object. This will return Null_Ref
-- if the object has already been destroyed.
-- The procedure version can be used if you have subclassed Ref.
-- The code should look like:
--
-- -- Create the smart pointer
-- Tmp : Refcounted_Access := new My_Refcounted_Type;
-- R : Ref := Allocate (Tmp); -- Hold a ref to Tmp
--
-- WRef := Get_Weak_Ref (R); -- Does not hold a ref to Tmp
--
-- R := Null_Ref; -- Releases ref to Tmp, and free Tmp
-- we now have Get (WRef) = null
--
-- In the case of a multitasking application, you must write your code
-- so that the referenced type is not freed while you are using it. For
-- instance:
-- declare
-- R : constant Ref := Get (WRef); -- hold a ref to Tmp
-- begin
-- if R /= Null_Ref then
-- ... manipulate R
-- Tmp cannot be freed while in the declare block, since we
-- own a reference to it
-- end if;
-- end;
end Weakref_Pointers;
private
type Weak_Refcounted
is abstract new GNATCOLL.Refcount.Refcounted
with record
Proxy : Proxy_Pointers.Ref; -- Hold a reference to a proxy
end record;
end GNATCOLL.Refcount.Weakref;
|