1(* 2 Title: Weak references 3 Author: David Matthews 4 Copyright David Matthews 2008, 2015-16 5 6 This library is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Lesser General Public 8 License version 2.1 as published by the Free Software Foundation. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18*) 19 20(* A weak reference or array contains option values. The SOME variant of 21 the option must contain a reference. This restriction is imposed because 22 they require pointer equality. A weak reference or array behaves just like 23 a normal ref or array with one difference. The garbage collector may set 24 a weak ref or the field of weak array to NONE if it currently contains 25 SOME r but r is not reachable other than through weak references. The 26 one proviso is that if r is contained in the executable it is always 27 reachable. 28*) 29 30signature WEAK = 31sig 32 val weak: 'a ref option -> 'a ref option ref 33 val weakArray: int * 'a ref option -> 'a ref option array 34 val weakLock: Thread.Mutex.mutex 35 and weakSignal: Thread.ConditionVar.conditionVar 36 val touch : 'a ref -> unit 37end; 38 39structure Weak: WEAK = 40struct 41 fun weak (v: 'a ref option): 'a ref option ref = RunCall.allocateWordMemory(0w1, 0wx60, v) 42 43 fun weakArray(n: int, v: 'a ref option): 'a ref option array = 44 let 45 val () = if n < 0 orelse n >= Array.maxLen then raise Size else () 46 val arr = RunCall.allocateWordMemory(Word.fromInt n, 0wx60, v) 47 in 48 arr 49 end 50 51 val weakLock = Thread.Mutex.mutex() 52 and weakSignal = Thread.ConditionVar.conditionVar() 53 54 (* touch is considered by the compiler as an access to the ref but doesn't 55 actually do anything with it. The idea is that it ensures that when a ref 56 is used as a token that this will access the ref and avoid the weak 57 reference becoming set to NONE. It's primarily there for long-term 58 security in the event that the compiler is sufficiently clever to 59 work out that something is no longer referenced. *) 60 fun touch v = v := !v 61end; 62