Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / devtools / v8plus / share / swig / 1.3.26 / ruby / director.swg
CommitLineData
920dae64
AT
1/***********************************************************************
2 * director.swg
3 *
4 * This file contains support for director classes that proxy
5 * method calls from C++ to Ruby extensions.
6 *
7 * Author : Lyle Johnson (lyle@users.sourceforge.net)
8 * Based on the original Python implementation by
9 * Mark Rose (mrose@stm.lbl.gov).
10 ************************************************************************/
11
12#ifdef __cplusplus
13
14#include <string>
15
16namespace Swig {
17 struct body_args {
18 VALUE recv;
19 ID id;
20 int argc;
21 VALUE *argv;
22 };
23
24 /* Base class for director exceptions */
25 class DirectorException {
26 protected:
27 VALUE swig_error;
28 protected:
29 DirectorException(VALUE error=Qnil) : swig_error(error) {}
30 public:
31 VALUE getType() const {
32 return CLASS_OF(swig_error);
33 }
34 VALUE getError() const {
35 return swig_error;
36 }
37 virtual ~DirectorException() {}
38 };
39
40 /* Type mismatch in the return value from a Ruby method call */
41 class DirectorTypeMismatchException : public Swig::DirectorException {
42 public:
43 DirectorTypeMismatchException(const char *msg="") {
44 VALUE str = rb_str_new2("Swig director type mismatch: ");
45 rb_str_concat(str, rb_str_new2(msg));
46 swig_error = rb_exc_new3(rb_eTypeError, str);
47 }
48 };
49
50 /* Any Ruby exception that occurs during a director method call */
51 class DirectorMethodException : public Swig::DirectorException {
52 public:
53 DirectorMethodException(VALUE error) : Swig::DirectorException(error) {}
54 };
55
56 /* Attempted to call a pure virtual method via a director method */
57 class DirectorPureVirtualException : public Swig::DirectorException {};
58
59
60 /* Simple thread abstraction for pthreads on win32 */
61#ifdef __THREAD__
62#define __PTHREAD__
63#if defined(_WIN32) || defined(__WIN32__)
64#define pthread_mutex_lock EnterCriticalSection
65#define pthread_mutex_unlock LeaveCriticalSection
66#define pthread_mutex_t CRITICAL_SECTION
67#define MUTEX_INIT(var) CRITICAL_SECTION var
68#else
69#include <pthread.h>
70#define MUTEX_INIT(var) pthread_mutex_t var = PTHREAD_MUTEX_INITIALIZER
71#endif
72#endif
73
74 /* director base class */
75 class Director {
76 private:
77 /* pointer to the wrapped Ruby object */
78 VALUE swig_self;
79 /* flag indicating whether the object is owned by Ruby or c++ */
80 mutable bool swig_disown_flag;
81 /* shared flag for breaking recursive director calls */
82 static bool swig_up;
83
84#ifdef __PTHREAD__
85 /* locks for sharing the swig_up flag in a threaded environment */
86 static pthread_mutex_t swig_mutex_up;
87 static bool swig_mutex_active;
88 static pthread_t swig_mutex_thread;
89#endif
90
91 /* reset the swig_up flag once the routing direction has been determined */
92#ifdef __PTHREAD__
93 void swig_clear_up() const {
94 Swig::Director::swig_up = false;
95 Swig::Director::swig_mutex_active = false;
96 pthread_mutex_unlock(&swig_mutex_up);
97 }
98#else
99 void swig_clear_up() const {
100 Swig::Director::swig_up = false;
101 }
102#endif
103
104 public:
105 /* wrap a Ruby object, optionally taking ownership */
106 Director(VALUE self) : swig_self(self), swig_disown_flag(false) {
107 }
108
109 /* discard our reference at destruction */
110 virtual ~Director() {
111 }
112
113 /* return a pointer to the wrapped Ruby object */
114 VALUE swig_get_self() const {
115 return swig_self;
116 }
117
118 /* get the swig_up flag to determine if the method call should be routed
119 * to the c++ base class or through the wrapped Ruby object
120 */
121#ifdef __PTHREAD__
122 bool swig_get_up() const {
123 if (Swig::Director::swig_mutex_active) {
124 if (pthread_equal(Swig::Director::swig_mutex_thread, pthread_self())) {
125 bool up = swig_up;
126 swig_clear_up();
127 return up;
128 }
129 }
130 return false;
131 }
132#else
133 bool swig_get_up() const {
134 bool up = swig_up;
135 swig_up = false;
136 return up;
137 }
138#endif
139
140 /* set the swig_up flag if the next method call should be directed to
141 * the c++ base class rather than the wrapped Ruby object
142 */
143#ifdef __PTHREAD__
144 void swig_set_up() const {
145 pthread_mutex_lock(&Swig::Director::swig_mutex_up);
146 Swig::Director::swig_mutex_thread = pthread_self();
147 Swig::Director::swig_mutex_active = true;
148 Swig::Director::swig_up = true;
149 }
150#else
151 void swig_set_up() const {
152 Swig::Director::swig_up = true;
153 }
154#endif
155
156 /* acquire ownership of the wrapped Ruby object (the sense of "disown"
157 * is from Ruby) */
158 void swig_disown() const {
159 if (!swig_disown_flag) {
160 swig_disown_flag = true;
161 }
162 }
163 };
164
165 bool Swig::Director::swig_up = false;
166
167#ifdef __PTHREAD__
168 MUTEX_INIT(Swig::Director::swig_mutex_up);
169 pthread_t Swig::Director::swig_mutex_thread;
170 bool Swig::Director::swig_mutex_active = false;
171#endif
172
173}
174
175#endif /* __cplusplus */
176
177