1 // This testcase was in the python subdirectory
2 
3 #if defined(SWIGPYTHON)
4 // Is "threads" really needed for Python? It seems to work without it.
5 %module(directors="1",threads="1") director_thread
6 #else
7 %module(directors="1") director_thread
8 #endif
9 
10 #ifdef SWIGOCAML
11 %warnfilter(SWIGWARN_PARSE_KEYWORD) val;
12 #endif
13 
14 %begin %{
15 #define SWIG_JAVA_USE_THREAD_NAME
16 //#define DEBUG_DIRECTOR_THREAD_NAME
17 %}
18 
19 %{
20 #ifdef _WIN32
21 #include <windows.h>
22 #include <process.h>
23 #include <stdio.h>
24 #else
25 #include <pthread.h>
26 #include <errno.h>
27 #include <stdio.h>
28 #include <signal.h>
29 #include <unistd.h>
30 #endif
31 
32 #include <assert.h>
33 #include "swig_examples_lock.h"
34 
35 class Foo;
36 extern "C" {
37 #ifdef _WIN32
38   static unsigned int __stdcall working(void* t);
39   static HANDLE thread_handle = 0;
40 #else
41   void* working(void* t);
42   static pthread_t thread;
43 #endif
44 
45   static int thread_terminate = 0;
46   static SwigExamples::CriticalSection critical_section;
get_thread_terminate()47   int get_thread_terminate() {
48     SwigExamples::Lock lock(critical_section);
49     return thread_terminate;
50   }
set_thread_terminate(int value)51   void set_thread_terminate(int value) {
52     SwigExamples::Lock lock(critical_section);
53     thread_terminate = value;
54   }
55 }
56 %}
57 
58 %director Foo;
59 
60 %inline {
MilliSecondSleep(int milliseconds)61   static void MilliSecondSleep(int milliseconds) {
62   %#ifdef _WIN32
63     Sleep(milliseconds);
64   %#else
65     usleep(milliseconds*1000);
66   %#endif
67   }
68 
69   class Foo {
70   public:
71     int val;
72 
Foo()73     Foo() : val(0) {
74     }
75 
~Foo()76     virtual ~Foo()  {
77     }
78 
stop()79     void stop() {
80       set_thread_terminate(1);
81     %#ifdef _WIN32
82       WaitForSingleObject(thread_handle, INFINITE);
83       CloseHandle(thread_handle);
84     %#else
85       pthread_join(thread, NULL);
86     %#endif
87     }
88 
run()89     void run() {
90 %#ifdef _WIN32
91       unsigned int thread_id = 0;
92       thread_handle = (HANDLE)_beginthreadex(NULL,0,working,this,0,&thread_id);
93       if (thread_handle == 0) {
94         fprintf(stderr, "_beginthreadex failed in run()\n");
95         assert(0);
96       }
97 %#else
98       int create = pthread_create(&thread,NULL,working,this);
99       if (create != 0) {
100         errno = create;
101         perror("pthread_create in run()");
102         assert(0);
103       }
104 %#endif
105       MilliSecondSleep(500);
106     }
107 
setThreadName()108     void setThreadName() {
109 %#ifdef _WIN32
110 %#else
111 
112 %#ifdef __APPLE__
113       int setname = pthread_setname_np("MyThreadName");
114 %#else
115       int setname = pthread_setname_np(pthread_self(), "MyThreadName");
116 %#endif
117 
118       if (setname != 0) {
119         errno = setname;
120         perror("calling pthread_setname_np in setThreadName()");
121         assert(0);
122       }
123 %#endif
124     }
125 
namedThread()126     static bool namedThread() {
127 %#ifdef _WIN32
128       return false;
129 %#else
130       return true;
131 %#endif
132     }
133 
do_foo()134     virtual void do_foo() {
135       val += 1;
136     }
137   };
138 }
139 
140 %{
141 extern "C" {
142 #ifdef _WIN32
working(void * t)143   unsigned int __stdcall working(void* t)
144 #else
145   void* working(void* t)
146 #endif
147   {
148     Foo* f = static_cast<Foo*>(t);
149     f->setThreadName();
150     while (!get_thread_terminate()) {
151       MilliSecondSleep(50);
152       f->do_foo();
153     }
154     return 0;
155   }
156 }
157 %}
158