aboutsummaryrefslogtreecommitdiff
path: root/Examples/test-suite/director_thread.i
blob: 845f8e093c0614b6912c2ee5fd101ce789f84999 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// This testcase was in the python subdirectory

#if defined(SWIGPYTHON)
// Is "threads" really needed for Python? It seems to work without it.
%module(directors="1",threads="1") director_thread
#else
%module(directors="1") director_thread
#endif

#ifdef SWIGOCAML
%warnfilter(SWIGWARN_PARSE_KEYWORD) val;
#endif

%begin %{
#define SWIG_JAVA_USE_THREAD_NAME
//#define DEBUG_DIRECTOR_THREAD_NAME
%}

%{
#ifdef _WIN32
#include <windows.h>
#include <process.h>
#else
#include <pthread.h>
#include <errno.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#endif

#include <assert.h>
#include <stdio.h>
#include "swig_examples_lock.h"

class Foo;  
extern "C" {
#ifdef _WIN32
  static unsigned int __stdcall working(void* t);
  static HANDLE thread_handle = 0;
#else
  void* working(void* t);
  static pthread_t thread;
#endif

  static int swig_thread_terminate = 0;
  static SwigExamples::CriticalSection critical_section;
  int get_thread_terminate() {
    SwigExamples::Lock lock(critical_section);
    return swig_thread_terminate;
  }
  void set_thread_terminate(int value) {
    SwigExamples::Lock lock(critical_section);
    swig_thread_terminate = value;
  }
}
%}

%director Foo;

%inline {
  static void MilliSecondSleep(int milliseconds) {
  %#ifdef _WIN32
    Sleep(milliseconds);
  %#else
    usleep(milliseconds*1000);
  %#endif
  }

  class Foo {
  public:
    int val;
    
    Foo() : val(0) {
    }
    
    virtual ~Foo() {
    }

    void stop() {
      set_thread_terminate(1);
    %#ifdef _WIN32
      WaitForSingleObject(thread_handle, INFINITE);
      CloseHandle(thread_handle);
    %#else  
      pthread_join(thread, NULL);
    %#endif
    }

    void run() {
%#ifdef _WIN32
      unsigned int thread_id = 0;
      thread_handle = (HANDLE)_beginthreadex(NULL,0,working,this,0,&thread_id);
      if (thread_handle == 0) {
        fprintf(stderr, "_beginthreadex failed in run()\n");
        assert(0);
      }
%#else
      int create = pthread_create(&thread,NULL,working,this);
      if (create != 0) {
        errno = create;
        perror("pthread_create in run()");
        assert(0);
      }
%#endif
      MilliSecondSleep(500);
    }

    void setThreadName() {
%#ifdef _WIN32
%#else

%#ifdef __APPLE__
      int setname = pthread_setname_np("MyThreadName");
%#else
      int setname = pthread_setname_np(pthread_self(), "MyThreadName");
%#endif

      if (setname != 0) {
        errno = setname;
        perror("calling pthread_setname_np in setThreadName()");
        assert(0);
      }
%#endif
    }

    static bool namedThread() {
%#ifdef _WIN32
      return false;
%#else
      return true;
%#endif
    }

    virtual void do_foo() {
      val += 1;
    }
  };
}

%{
extern "C" {
#ifdef _WIN32
  unsigned int __stdcall working(void* t)
#else
  void* working(void* t)
#endif
  {
    Foo* f = static_cast<Foo*>(t);
    f->setThreadName();
    while (!get_thread_terminate()) {
      MilliSecondSleep(50);
      f->do_foo();
    }
    return 0;
  }
}
%}