Add section on multi-thread issues that affect single threaded applications
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@9897 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
82bf3c6d82
commit
090e3796ad
1 changed files with 90 additions and 0 deletions
|
|
@ -69,6 +69,7 @@
|
|||
<li><a href="#inheritance_mirroring">Inheritance</a>
|
||||
<li><a href="#proxy_classes_gc">Proxy classes and garbage collection</a>
|
||||
<li><a href="#java_pgcpp">The premature garbage collection prevention parameter for proxy class marshalling</a>
|
||||
<li><a href="#java_multithread_libraries">Single threaded applications and thread safety</a>
|
||||
</ul>
|
||||
<li><a href="#type_wrapper_classes">Type wrapper classes</a>
|
||||
<li><a href="#enum_classes">Enum classes</a>
|
||||
|
|
@ -2317,6 +2318,7 @@ See <a href="#imclass_pragmas">The intermediary JNI class pragmas</a> section fo
|
|||
|
||||
<p>
|
||||
A Java proxy class is generated for each structure, union or C++ class that is wrapped.
|
||||
Proxy classes have also been called <a href="http://java.sun.com/developer/JDCTechTips/2001/tt0612.html#tip2">peer classes</a>.
|
||||
The default proxy class for our previous example looks like this:
|
||||
</p>
|
||||
|
||||
|
|
@ -2866,6 +2868,94 @@ For example:
|
|||
<b>Compatibility note:</b> The generation of this additional parameter did not occur in versions prior to SWIG-1.3.30.
|
||||
</p>
|
||||
|
||||
<H4><a name="java_multithread_libraries"></a>20.4.3.5 Single threaded applications and thread safety</H4>
|
||||
|
||||
|
||||
<p>
|
||||
Single threaded Java applications using JNI need to consider thread safety.
|
||||
The same applies for .NET applications using PInvoke.
|
||||
Consider the C++ class:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
class Test {
|
||||
string str;
|
||||
public:
|
||||
Test() : str("initial") {}
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
and the Java proxy class generated by SWIG:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
public class Test {
|
||||
private long swigCPtr;
|
||||
protected boolean swigCMemOwn;
|
||||
|
||||
protected Test(long cPtr, boolean cMemoryOwn) {
|
||||
swigCMemOwn = cMemoryOwn;
|
||||
swigCPtr = cPtr;
|
||||
}
|
||||
|
||||
protected static long getCPtr(Test obj) {
|
||||
return (obj == null) ? 0 : obj.swigCPtr;
|
||||
}
|
||||
|
||||
protected void finalize() {
|
||||
delete();
|
||||
}
|
||||
|
||||
// Call C++ destructor
|
||||
public synchronized void delete() {
|
||||
if(swigCPtr != 0 && swigCMemOwn) {
|
||||
swigCMemOwn = false;
|
||||
exampleJNI.delete_Test(swigCPtr);
|
||||
}
|
||||
swigCPtr = 0;
|
||||
}
|
||||
|
||||
// Call C++ constructor
|
||||
public Test() {
|
||||
this(exampleJNI.new_Test(), true);
|
||||
}
|
||||
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>
|
||||
It has two methods that call JNI methods, namely, <tt>exampleJNI.new_Test()</tt> for the C++ constructor and <tt>exampleJNI.delete_Test()</tt> for the C++ destructor.
|
||||
If the garbage collector collects an instance of this class, ie <tt>delete()</tt> is not explicitly called, then the C++ destructor will be run in a different thread to the main thread.
|
||||
This is because when an object is marked for garbage collection, any objects with finalizers are added to a finalization queue
|
||||
and the objects in the finalization queue have their <tt>finalize()</tt> methods run in a separate finalization thread.
|
||||
Therefore, if the C memory allocator is not thread safe, then the heap will get corrupted sooner or later, when a concurrent C++ delete and new are executed.
|
||||
It is thus essential, even in single threaded usage, to link to the C multi-thread runtime libraries,
|
||||
for example, use the /MD option for Visual C++ on Windows.
|
||||
Alternatively, lock all access to C++ functions that have heap allocation/deallocation.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Note that some of the STL in Visual C++ 6 is not thread safe, so although code might be linked to the multithread runtime libraries, undefined behaviour might still occur in a single threaded Java program.
|
||||
Similarly some older versions of Sun Studio have bugs in the multi-threaded implementation of the std::string class and so will lead to undefined behaviour in these supposedly single threaded Java applications.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The following innocuous Java usage of Test is an example that will crash very quickly on a multiprocessor machine if the JNI compiled code is linked against the single thread C runtime libraries.
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
for (int i=0; i<100000; i++) {
|
||||
System.out.println("Iteration " + i);
|
||||
for (int k=0; k<10; k++) {
|
||||
Test test = new Test();
|
||||
}
|
||||
System.gc();
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
||||
<H3><a name="type_wrapper_classes"></a>20.4.4 Type wrapper classes</H3>
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue