PageRenderTime 49ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/rel-1-3-29/SWIG/Lib/ocaml/director.swg

#
Unknown | 163 lines | 142 code | 21 blank | 0 comment | 0 complexity | a4b3ed47177fb81b5ccc86d376d33a55 MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
  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. #ifdef __cplusplus
  12. #include <string>
  13. namespace Swig {
  14. /* base class for director exceptions */
  15. class DirectorException {
  16. protected:
  17. std::string swig_msg;
  18. public:
  19. DirectorException(const char* msg="") {
  20. }
  21. const char *getMessage() const {
  22. return swig_msg.c_str();
  23. }
  24. virtual ~DirectorException() {}
  25. };
  26. /* type mismatch in the return value from a python method call */
  27. class DirectorTypeMismatchException : public Swig::DirectorException {
  28. public:
  29. DirectorTypeMismatchException(const char* msg="") {
  30. }
  31. };
  32. /* any python exception that occurs during a director method call */
  33. class DirectorMethodException : public Swig::DirectorException {};
  34. /* attempt to call a pure virtual method via a director method */
  35. class DirectorPureVirtualException : public Swig::DirectorException {};
  36. /* simple thread abstraction for pthreads on win32 */
  37. #ifdef __THREAD__
  38. #define __PTHREAD__
  39. #if defined(_WIN32) || defined(__WIN32__)
  40. #define pthread_mutex_lock EnterCriticalSection
  41. #define pthread_mutex_unlock LeaveCriticalSection
  42. #define pthread_mutex_t CRITICAL_SECTION
  43. #define MUTEX_INIT(var) CRITICAL_SECTION var
  44. #else
  45. #include <pthread.h>
  46. #define MUTEX_INIT(var) pthread_mutex_t var = PTHREAD_MUTEX_INITIALIZER
  47. #endif
  48. #endif
  49. /* director base class */
  50. class Director {
  51. private:
  52. /* pointer to the wrapped ocaml object */
  53. CAML_VALUE swig_self;
  54. /* flag indicating whether the object is owned by ocaml or c++ */
  55. mutable bool swig_disown_flag;
  56. mutable bool swig_up;
  57. #ifdef __PTHREAD__
  58. /* locks for sharing the swig_up flag in a threaded environment */
  59. static pthread_mutex_t swig_mutex_up;
  60. static bool swig_mutex_active;
  61. static pthread_t swig_mutex_thread;
  62. #endif
  63. /* reset the swig_up flag once the routing direction has been determined */
  64. #ifdef __PTHREAD__
  65. void swig_clear_up() const {
  66. swig_up = false;
  67. Swig::Director::swig_mutex_active = false;
  68. pthread_mutex_unlock(&swig_mutex_up);
  69. }
  70. #else
  71. void swig_clear_up() const {
  72. swig_up = false;
  73. }
  74. #endif
  75. public:
  76. /* wrap a ocaml object, optionally taking ownership */
  77. Director(CAML_VALUE self) : swig_self(self), swig_disown_flag(false), swig_up( false ) {
  78. register_global_root(&swig_self);
  79. }
  80. /* discard our reference at destruction */
  81. virtual ~Director() {
  82. remove_global_root(&swig_self);
  83. swig_disown();
  84. // Disown is safe here because we're just divorcing a reference that
  85. // points to us.
  86. }
  87. /* return a pointer to the wrapped ocaml object */
  88. CAML_VALUE swig_get_self() const {
  89. return swig_self;
  90. }
  91. /* get the swig_up flag to determine if the method call should be routed
  92. * to the c++ base class or through the wrapped ocaml object
  93. */
  94. #ifdef __PTHREAD__
  95. bool swig_get_up( bool clear = true ) const {
  96. if (Swig::Director::swig_mutex_active) {
  97. if (pthread_equal(Swig::Director::swig_mutex_thread, pthread_self())) {
  98. bool up = swig_up;
  99. if( clear ) swig_clear_up();
  100. return up;
  101. }
  102. }
  103. return false;
  104. }
  105. #else
  106. bool swig_get_up( bool clear = true ) const {
  107. bool up = swig_up;
  108. if( clear ) swig_up = false;
  109. return up;
  110. }
  111. #endif
  112. /* set the swig_up flag if the next method call should be directed to
  113. * the c++ base class rather than the wrapped ocaml object
  114. */
  115. #ifdef __PTHREAD__
  116. void swig_set_up() const {
  117. pthread_mutex_lock(&Swig::Director::swig_mutex_up);
  118. Swig::Director::swig_mutex_thread = pthread_self();
  119. Swig::Director::swig_mutex_active = true;
  120. swig_up = true;
  121. }
  122. #else
  123. void swig_set_up() const {
  124. swig_up = true;
  125. }
  126. #endif
  127. /* acquire ownership of the wrapped ocaml object (the sense of "disown"
  128. * is from ocaml) */
  129. void swig_disown() const {
  130. if (!swig_disown_flag) {
  131. swig_disown_flag=true;
  132. callback(*caml_named_value("caml_obj_disown"),swig_self);
  133. }
  134. }
  135. };
  136. #ifdef __PTHREAD__
  137. MUTEX_INIT(Swig::Director::swig_mutex_up);
  138. pthread_t Swig::Director::swig_mutex_thread;
  139. bool Swig::Director::swig_mutex_active = false;
  140. #endif
  141. }
  142. #endif /* __cplusplus */