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