1/* -----------------------------------------------------------------------------
2 * See the LICENSE file for information on copyright, usage and redistribution
3 * of SWIG, and the README file for authors - http://www.swig.org/release.html.
4 *
5 * director.swg
6 *
7 * This file contains support for director classes that proxy
8 * method calls from C++ to Ocaml extensions.
9 *
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    public:
43      DirectorPureVirtualException(const char* msg="") {
44      }
45
46      static void raise(const char *msg) {
47        throw DirectorPureVirtualException(msg);
48      }
49  };
50
51  /* simple thread abstraction for pthreads on win32 */
52#ifdef __THREAD__
53#define __PTHREAD__
54#if defined(_WIN32) || defined(__WIN32__)
55#define pthread_mutex_lock EnterCriticalSection
56#define pthread_mutex_unlock LeaveCriticalSection
57#define pthread_mutex_t CRITICAL_SECTION
58#define MUTEX_INIT(var) CRITICAL_SECTION var
59#else
60#include <pthread.h>
61#define MUTEX_INIT(var) pthread_mutex_t var = PTHREAD_MUTEX_INITIALIZER
62#endif
63#endif
64
65  /* director base class */
66  class Director {
67    private:
68      /* pointer to the wrapped ocaml object */
69      CAML_VALUE swig_self;
70      /* flag indicating whether the object is owned by ocaml or c++ */
71      mutable bool swig_disown_flag;
72
73    public:
74      /* wrap a ocaml object, optionally taking ownership */
75      Director(CAML_VALUE self) : swig_self(self), swig_disown_flag(false) {
76        register_global_root(&swig_self);
77      }
78
79      /* discard our reference at destruction */
80      virtual ~Director() {
81        remove_global_root(&swig_self);
82        swig_disown();
83        // Disown is safe here because we're just divorcing a reference that
84        // points to us.
85      }
86
87      /* return a pointer to the wrapped ocaml object */
88      CAML_VALUE swig_get_self() const {
89	  return swig_self;
90      }
91
92      /* acquire ownership of the wrapped ocaml object (the sense of "disown"
93       * is from ocaml) */
94      void swig_disown() const {
95        if (!swig_disown_flag) {
96          swig_disown_flag=true;
97          callback(*caml_named_value("caml_obj_disown"),swig_self);
98        }
99      }
100  };
101}
102
103#endif /* __cplusplus */
104