CXXR (C++ R)
WeakRef.h
Go to the documentation of this file.
1 /*CXXR $Id: WeakRef.h 1348 2013-02-25 17:49:03Z arr $
2  *CXXR
3  *CXXR This file is part of CXXR, a project to refactor the R interpreter
4  *CXXR into C++. It may consist in whole or in part of program code and
5  *CXXR documentation taken from the R project itself, incorporated into
6  *CXXR CXXR (and possibly MODIFIED) under the terms of the GNU General Public
7  *CXXR Licence.
8  *CXXR
9  *CXXR CXXR is Copyright (C) 2008-13 Andrew R. Runnalls, subject to such other
10  *CXXR copyrights and copyright restrictions as may be stated below.
11  *CXXR
12  *CXXR CXXR is not part of the R project, and bugs and other issues should
13  *CXXR not be reported via r-bugs or other R project channels; instead refer
14  *CXXR to the CXXR website.
15  *CXXR */
16 
17 /*
18  * R : A Computer Language for Statistical Data Analysis
19  * Copyright (C) 1995, 1996 Robert Gentleman and Ross Ihaka
20  * Copyright (C) 1999-2006 The R Development Core Team.
21  * Andrew Runnalls (C) 2007
22  *
23  * This program is free software; you can redistribute it and/or modify
24  * it under the terms of the GNU General Public License as published by
25  * the Free Software Foundation; either version 2.1 of the License, or
26  * (at your option) any later version.
27  *
28  * This program is distributed in the hope that it will be useful,
29  * but WITHOUT ANY WARRANTY; without even the implied warranty of
30  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31  * GNU General Public License for more details.
32  *
33  * You should have received a copy of the GNU General Public License
34  * along with this program; if not, a copy is available at
35  * http://www.r-project.org/Licenses/
36  */
37 
42 #ifndef WEAKREF_HPP
43 #define WEAKREF_HPP
44 
45 #include "CXXR/RObject.h"
46 
47 #ifdef __cplusplus
48 extern "C" {
49 #endif
50 
51  /* Finalization interface */
52  typedef void (*R_CFinalizer_t)(SEXP);
53  void R_RegisterFinalizer(SEXP s, SEXP fun);
54  void R_RegisterCFinalizer(SEXP s, R_CFinalizer_t fun);
55  void R_RegisterFinalizerEx(SEXP s, SEXP fun, Rboolean onexit);
56  void R_RegisterCFinalizerEx(SEXP s, R_CFinalizer_t fun, Rboolean onexit);
57 
58  /* Weak reference interface */
59  SEXP R_MakeWeakRef(SEXP key, SEXP val, SEXP fin, Rboolean onexit);
60  SEXP R_MakeWeakRefC(SEXP key, SEXP val, R_CFinalizer_t fin,
61  Rboolean onexit);
62  void R_RunExitFinalizers(void);
63  SEXP R_WeakRefKey(SEXP w);
64  SEXP R_WeakRefValue(SEXP w);
65 
66 #ifdef __cplusplus
67 } // extern "C"
68 
69 #include <list>
70 #include "CXXR/Allocator.hpp"
71 #include "CXXR/FunctionBase.h"
72 
73 namespace CXXR {
110  class WeakRef : public RObject {
111  public:
138  WeakRef(RObject* key, RObject* value, FunctionBase* R_finalizer = 0,
139  bool finalize_on_exit = false);
140 
168  WeakRef(RObject* key, RObject* value, R_CFinalizer_t C_finalizer,
169  bool finalize_on_exit = false);
170 
171  ~WeakRef();
172 
181  static bool check();
182 
186  RObject* key() const {return m_key;}
187 
193  static void runExitFinalizers();
194 
208  static bool runFinalizers();
209 
213  RObject* value() const {return m_value;}
214 
215  // Virtual functions of RObject:
216  unsigned int packGPBits() const;
217  void unpackGPBits(unsigned int gpbits);
218  protected:
219  // Virtual function of GCNode:
220  void detachReferents();
221  private:
222  typedef std::list<WeakRef*, Allocator<WeakRef*> > WRList;
223  static WRList* s_live;
224  static WRList* s_f10n_pending; // Finalization pending
225  static WRList* s_tombstone;
226 
227  static int s_count; // Count of references in existence (for
228  // debugging)
229 
230  GCEdge<> m_key;
231  GCEdge<> m_value;
232  GCEdge<FunctionBase> m_Rfinalizer;
233  GCEdge<> m_self; // Each WeakRef refers to itself, to stop
234  // WeakRef nodes being deleted by gclite().
235  R_CFinalizer_t m_Cfinalizer;
236  WRList::iterator m_lit;
237  bool m_ready_to_finalize;
238  bool m_finalize_on_exit;
239 
240  // Clean up static data members:
241  static void cleanup();
242 
243  void finalize();
244 
245  // Initialize the static data members:
246  static void initialize();
247 
258  static void markThru();
259 
260  // Tombstone the node:
261  void tombstone();
262 
263  // Transfer the WeakRef from list 'from' to list 'to':
264  void transfer(WRList* from, WRList* to)
265  {
266  to->splice(to->end(), *from, m_lit);
267  }
268 
269  // Return pointer to the list (s_live, s_f10n_pending or
270  // s_tombstone) on which - according to its internal data -
271  // the object currently should be listed (and quite possibly
272  // is listed).
273  WRList* wrList() const;
274 
275  friend class GCNode;
276  friend class SchwarzCounter<WeakRef>;
277  };
278 } // namespace CXXR
279 
280 namespace {
281  CXXR::SchwarzCounter<CXXR::WeakRef> weakref_schwarz_ctr;
282 }
283 
284 #endif /* __cplusplus */
285 
286 #endif /* WEAKREF_HPP */