forked from swig/swig
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Prepare director thread dead lock example
- Loading branch information
Showing
3 changed files
with
177 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
%module(directors="1",threads="1") director_thread_lock | ||
#if defined(SWIGPYTHON) | ||
|
||
%{ | ||
#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; | ||
|
||
SwigExamples::CriticalSection critical_section; | ||
|
||
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; | ||
} | ||
|
||
void invoke_foo() { | ||
SwigExamples::Lock lock(critical_section); | ||
do_foo(); | ||
} | ||
|
||
virtual void invoke_bar(int i) { | ||
SwigExamples::Lock lock(critical_section); | ||
val = i; | ||
} | ||
}; | ||
} | ||
|
||
%{ | ||
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->invoke_foo(); | ||
} | ||
return 0; | ||
} | ||
} | ||
%} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
from director_thread_lock import Foo | ||
import time | ||
|
||
|
||
class Derived(Foo): | ||
|
||
def __init__(self): | ||
Foo.__init__(self) | ||
|
||
def do_foo(self): | ||
self.val = self.val - 1 | ||
time.sleep(0.001) | ||
|
||
|
||
d = Derived() | ||
d.run() | ||
|
||
for i in range(10): | ||
d.invoke_bar(i) | ||
|
||
d.stop() |