<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="polydoc.xsl"?>
<polydoc>
<title>Signature WEAK Structure Weak</title>
<navigation>
<parent href="Basis.html">Basis</parent>
<previous href="Universal.xml">Universal</previous>
</navigation>
<headtext>
<p>
  The <identifier>Weak</identifier> structure contains functions for constructing 
  <em>weak</em> references and arrays. A weak reference is a way of detecting 
  when a resource is no longer in use and can be recovered. It is, in effect, 
  a way of extending the concept of garbage-collection to user code.
</p></headtext>
<topdecs>
<summary>signature WEAK:
sig
    val weak: 'a ref option -&gt; 'a ref option ref
    val weakArray: int * 'a ref option -&gt; 'a ref option array
    val weakLock: Thread.Mutex.mutex
    and weakSignal: Thread.ConditionVar.conditionVar
    val touch: 'a ref -&gt; unit
end
structure Weak: WEAK
</summary>
<bindings><binding>
<code>val <definition>weak</definition> : 'a ref option -&gt; 'a ref option ref
</code>
<text><p> Constructs a weak reference.  </p></text>
</binding>
<binding>
<code>val <definition>weakArray</definition> : int * 'a ref option -&gt; 'a ref option array
</code>
<text><p> Constructs an array containing weak references. </p></text>
</binding>
<binding>
<code>val <definition>weakLock</definition> : Thread.Mutex.mutex
and <definition>weakSignal</definition> : Thread.ConditionVar.conditionVar
</code>
<text><p> A lock and a condition variable that is broadcast when the garbage collector has recovered a <em>token</em>. </p></text>
</binding>
<binding>
<code>val <definition>touch</definition> : 'a ref -&gt; unit
</code>
<text><p> Uses the reference without changing it, ensuring that it is reachable at that point. </p></text>
</binding>
</bindings>
</topdecs>
<tailtext>
<p>
   The idea behind weak references is to allow user library code to recover resources 
  when they are no longer in use. This is only relevant for resources, such as 
  file descriptors, that exist outside the Poly/ML memory and need to be recovered.</p>
<p>  The garbage-collector recovers space in the heap by identifying cells that 
  are reachable from <em>roots</em>, generally the stacks of threads, and treating 
  everything else as garbage. This can be extended to external resources by associating 
  a <em>token</em> with the resource. While the token is reachable the resource 
  is considered to be in use. Once the token ceases to be reachable the resource 
  can be recovered.</p>
<p>  A weak reference is used to detect when the token is no longer accessible. 
  To make use of this the library code must allocate a normal reference value, 
  the token, whenever it constructs or links to the external resource and include 
  the token within the data it returns to the client code. The contents of the 
  reference are not relevant; it can be a <identifier>unit ref</identifier>, 
  what matters is the identity of the reference. When the library creates a token 
  it makes an entry in its own data structure within a weak reference or array. 
  That entry is set to <identifier>SOME token</identifier>. Note that the 
  type of a weak reference is <identifier>'a ref option ref</identifier> 
  i.e. it can only contain an option type holding a reference value.</p>
<p>  Provided the client code continues to use the resource and has a reachable 
  pointer to the token there will be no change to the state. If, though, it discards 
  the data associated with the resource and hence the pointer to the token the 
  resource is considered to be released and the library may recover the resource. 
  If the garbage collector detects that there are no other pointers to the token 
  except the weak reference it will change the weak reference from <identifier>SOME token</identifier> to
  <identifier>NONE</identifier>, so there are no longer  any pointers at all.</p>
<p>  To actually release the external resource the library must check the weak references 
  or arrays within its own data structures and look for entries that have been 
  set to <identifier>NONE</identifier>. Depending how the library code 
  works it may be appropriate to do this synchronously whenever a request is made 
  to allocate a new resource. An alternative would be to create a new thread to 
  manage the process asynchronously. To aid this the thread should lock the <identifier>weakLock</identifier> 
  mutex and suspend itself by calling <identifier>Thread.ConditionVar.wait</identifier> 
  or <identifier>Thread.ConditionVar.waitUntil</identifier>,  passing <identifier>weakLock</identifier> and <identifier>weakSignal</identifier> 
  as arguments. The <identifier>weakSignal</identifier> condition variable 
  is broadcast after a garbage-collection if the garbage collector has modified 
  a weak reference. Because there may be several libraries using weak references 
  the receipt of the signal does not guarantee that a resource associated with 
  any particular library has been released.</p>
<p>  The garbage-collector is only run when necessary and detection of released 
  resources may happen very infrequently, depending on factors such as the size 
  of the heap. To force a collection the library can call <identifier>PolyML.fullGC</identifier>
</p></tailtext>
</polydoc>
