~ubuntu-branches/ubuntu/breezy/redland-bindings/breezy

« back to all changes in this revision

Viewing changes to csharp/World.cs

  • Committer: Bazaar Package Importer
  • Author(s): Fabio M. Di Nitto
  • Date: 2005-06-21 12:56:49 UTC
  • mfrom: (1.1.1 upstream) (0.1.2 sarge)
  • Revision ID: james.westby@ubuntu.com-20050621125649-1uwxez1hdyzw6vzd
Tags: 1.0.2.1-1ubuntu1
* Resynchronise with Debian.

* Fix FTBFS: Add python2.4-dev Build-Dep.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
//
2
2
// World.cs: Redland Initialization class
3
3
//
4
 
// $Id: World.cs,v 1.5 2004/07/09 15:29:06 cmdjb Exp $
 
4
// $Id: World.cs,v 1.7 2005/01/05 11:41:42 edd Exp $
5
5
//
6
6
// Author:
7
7
//      Cesar Lopez Nataren (cesar@ciencias.unam.mx)
8
8
//      Edd Dumbill (edd@usefulinc.com)
9
9
//
10
10
// (C) 2004, Cesar Lopez Nataren
11
 
//           Edd Dumbill
 
11
// (C) 2004-5 Edd Dumbill
12
12
//
13
13
 
14
14
using System;
18
18
 
19
19
namespace Redland {
20
20
 
 
21
        public class WorldException : Exception {
 
22
                public WorldException (String s): base (s) { }
 
23
        }
 
24
 
21
25
        class World : IWrapper {
22
26
 
23
 
                IntPtr world;
 
27
                private static HandleRef handle;
24
28
 
25
29
                internal ArrayList messages;
26
 
 
27
 
                LogLevel level;
 
30
                private LogLevel level;
 
31
 
 
32
                private static int refs = 0;
 
33
                private static bool initialized = false;
 
34
 
 
35
                // HOW WORLD'S LIFETIME IS MANAGED -- Edd Dumbill, 2005-01-05
 
36
                //
 
37
                // It is necessary to keep an instance of the C world around for
 
38
                // as long as any Redland object needs it.  This includes in their
 
39
                // destructors.  Unfortunately, when all references to objects and
 
40
                // any 'inner' objects referred to within are liable to finalization,
 
41
                // the .NET finalizer makes no distinction about order.  This means
 
42
                // that if the C-world were closed from ~World() then some of the
 
43
                // other object finalizers would crash as the C world would close
 
44
                // before their own C based destructors (which need world) could run.
 
45
                // 
 
46
                // To get around this, we detach the destruction of the C world from
 
47
                // the .NET World object lifecycle, and use a single static reference
 
48
                // to it, with manual ref-counting.  Each client object uses
 
49
                // AddReference at construct-time and RemoveReference in Dispose().
 
50
                // This includes the .NET World object.
 
51
                //
 
52
                // When RemoveReference makes the ref count hit zero, the C-world is
 
53
                // destroyed.  To ensure this only happens at the end of the run, the
 
54
                // World object itself performs an AddReference on construct and 
 
55
                // RemoveReference on destruct.
28
56
 
29
57
                public LogMessage [] Messages {
30
58
                        get {
33
61
                }
34
62
 
35
63
                private delegate int MessageHandler (IntPtr userdata, IntPtr message);
 
64
                private MessageHandler mhandler;
36
65
 
37
66
                [DllImport ("librdf")]
38
67
                static extern IntPtr librdf_new_world ();
39
68
                [DllImport ("librdf")]
40
 
                static extern void librdf_world_set_logger (IntPtr world,
 
69
                static extern void librdf_world_set_logger (HandleRef world,
41
70
                                IntPtr userdata, Delegate cb);
42
71
 
43
72
                internal World ()
44
73
                {
45
 
                        world = librdf_new_world ();
46
 
                        ClearLog ();
47
 
                        librdf_world_set_logger (world, new IntPtr (0),
48
 
                                        new MessageHandler (dispatchMessage));
49
 
                        level = LogLevel.Warn;
 
74
                        if (! initialized) {
 
75
                                handle = new HandleRef (this, librdf_new_world ());
 
76
                                ClearLog ();
 
77
                                mhandler = new MessageHandler (dispatchMessage);
 
78
                                librdf_world_set_logger (handle, new IntPtr (0), mhandler);
 
79
                                level = LogLevel.Warn;
 
80
                                // logger set up, now let's open the world
 
81
                                Open ();
 
82
                                initialized = true;
 
83
                                AddReference ();
 
84
                        } else {
 
85
                                throw new WorldException ("Can only make one World");
 
86
                        }
 
87
                }
 
88
 
 
89
                ~World () {
 
90
                        RemoveReference ();
50
91
                }
51
92
 
52
93
                public LogLevel LogLevel {
53
 
                        get {
54
 
                                return level;
55
 
                        }
56
 
                        set {
57
 
                                level = value;
58
 
                        }
59
 
                }
60
 
 
61
 
                [DllImport ("librdf")]
62
 
                static extern void librdf_world_open (IntPtr world);
63
 
 
64
 
                internal void Open ()
65
 
                {
66
 
                        librdf_world_open (world);
67
 
                }
68
 
 
69
 
                public  IntPtr Handle {
70
 
                        get { return world; }
71
 
                }
72
 
 
73
 
                [DllImport ("librdf")]
74
 
                static extern void librdf_free_world (IntPtr world);
75
 
 
76
 
                ~World ()
77
 
                {
78
 
                        librdf_free_world (world);
 
94
                        get { return level; }
 
95
                        set { level = value; }
 
96
                }
 
97
 
 
98
                [DllImport ("librdf")]
 
99
                static extern void librdf_world_open (HandleRef world);
 
100
 
 
101
                static internal void Open ()
 
102
                {
 
103
                        librdf_world_open (handle);
 
104
                }
 
105
 
 
106
                public HandleRef Handle {
 
107
                        get { return handle; }
 
108
                }
 
109
 
 
110
                public World AddReference () {
 
111
                        refs++;
 
112
                        return this;
 
113
                }
 
114
 
 
115
                public void RemoveReference () {
 
116
                        if (refs == 0) {
 
117
                                throw new WorldException ("Attempt to remove reference from World when no references held");
 
118
                        }
 
119
                        refs--;
 
120
                        if (refs == 0) {
 
121
                                FreeWorld ();
 
122
                        }
 
123
                }
 
124
 
 
125
                [DllImport ("librdf")]
 
126
                static extern void librdf_free_world (HandleRef world);
 
127
 
 
128
                protected static void FreeWorld ()
 
129
                {
 
130
                        if (refs > 0)
 
131
                                throw new WorldException ("Attempt to free world when references still held");
 
132
 
 
133
                        if (handle.Handle != IntPtr.Zero) {
 
134
                                librdf_free_world (handle);
 
135
                                handle = new HandleRef (handle.Wrapper, IntPtr.Zero);
 
136
                        }
79
137
                }
80
138
 
81
139
                public void ClearLog ()