Home | History | Annotate | Download | only in ocaml
      1 /* -----------------------------------------------------------------------------
      2  * director.swg
      3  *
      4  * This file contains support for director classes that proxy
      5  * method calls from C++ to Ocaml extensions.
      6  *
      7  * ----------------------------------------------------------------------------- */
      8 
      9 #ifdef __cplusplus
     10 
     11 #include <string>
     12 
     13 # define SWIG_DIRECTOR_CAST(ARG) dynamic_cast<Swig::Director *>(ARG)
     14 
     15 namespace Swig {
     16   /* base class for director exceptions */
     17   class DirectorException {
     18     protected:
     19       std::string swig_msg;
     20     public:
     21       DirectorException(const char* msg="") {
     22       }
     23       const char *getMessage() const {
     24         return swig_msg.c_str();
     25       }
     26       virtual ~DirectorException() {}
     27   };
     28 
     29   /* type mismatch in the return value from a python method call */
     30   class DirectorTypeMismatchException : public Swig::DirectorException {
     31     public:
     32       DirectorTypeMismatchException(const char* msg="") {
     33       }
     34   };
     35 
     36   /* any python exception that occurs during a director method call */
     37   class DirectorMethodException : public Swig::DirectorException {};
     38 
     39   /* attempt to call a pure virtual method via a director method */
     40   class DirectorPureVirtualException : public Swig::DirectorException {
     41     public:
     42       DirectorPureVirtualException(const char* msg="") {
     43       }
     44 
     45       static void raise(const char *msg) {
     46         throw DirectorPureVirtualException(msg);
     47       }
     48   };
     49 
     50   /* simple thread abstraction for pthreads on win32 */
     51 #ifdef __THREAD__
     52 #define __PTHREAD__
     53 #if defined(_WIN32) || defined(__WIN32__)
     54 #define pthread_mutex_lock EnterCriticalSection
     55 #define pthread_mutex_unlock LeaveCriticalSection
     56 #define pthread_mutex_t CRITICAL_SECTION
     57 #define MUTEX_INIT(var) CRITICAL_SECTION var
     58 #else
     59 #include <pthread.h>
     60 #define MUTEX_INIT(var) pthread_mutex_t var = PTHREAD_MUTEX_INITIALIZER
     61 #endif
     62 #endif
     63 
     64   /* director base class */
     65   class Director {
     66     private:
     67       /* pointer to the wrapped ocaml object */
     68       CAML_VALUE swig_self;
     69       /* flag indicating whether the object is owned by ocaml or c++ */
     70       mutable bool swig_disown_flag;
     71 
     72     public:
     73       /* wrap a ocaml object, optionally taking ownership */
     74       Director(CAML_VALUE self) : swig_self(self), swig_disown_flag(false) {
     75         register_global_root(&swig_self);
     76       }
     77 
     78       /* discard our reference at destruction */
     79       virtual ~Director() {
     80         remove_global_root(&swig_self);
     81         swig_disown();
     82         // Disown is safe here because we're just divorcing a reference that
     83         // points to us.
     84       }
     85 
     86       /* return a pointer to the wrapped ocaml object */
     87       CAML_VALUE swig_get_self() const {
     88 	  return swig_self;
     89       }
     90 
     91       /* acquire ownership of the wrapped ocaml object (the sense of "disown"
     92        * is from ocaml) */
     93       void swig_disown() const {
     94         if (!swig_disown_flag) {
     95           swig_disown_flag=true;
     96           callback(*caml_named_value("caml_obj_disown"),swig_self);
     97         }
     98       }
     99   };
    100 }
    101 
    102 #endif /* __cplusplus */
    103