Author: Armin Rigo <[email protected]>
Branch: static-callback-embedding
Changeset: r2505:5db2f5b5d3ab
Date: 2016-01-01 11:36 +0100
http://bitbucket.org/cffi/cffi/changeset/5db2f5b5d3ab/
Log: test multiple threads all doing the initial call to an "extern
Python" function in parallel
diff --git a/testing/embedding/add1.py b/testing/embedding/add1.py
--- a/testing/embedding/add1.py
+++ b/testing/embedding/add1.py
@@ -6,14 +6,20 @@
extern "Python" int add1(int, int);
""", dllexport=True)
-ffi.embedding_init_code("""
- print("preparing")
+ffi.embedding_init_code(r"""
+ import sys, time
+ sys.stdout.write("preparing")
+ for i in range(3):
+ sys.stdout.flush()
+ time.sleep(0.02)
+ sys.stdout.write(".")
+ sys.stdout.write("\n")
int(ord("A")) # check that built-ins are there
@ffi.def_extern()
def add1(x, y):
- print "adding", x, "and", y
+ sys.stdout.write("adding %d and %d\n" % (x, y))
return x + y
""")
diff --git a/testing/embedding/test_basic.py b/testing/embedding/test_basic.py
--- a/testing/embedding/test_basic.py
+++ b/testing/embedding/test_basic.py
@@ -29,13 +29,13 @@
env=env)
self._compiled_modules.add(name)
- def compile(self, name, modules):
+ def compile(self, name, modules, extra=[]):
path = self.get_path()
filename = '%s.c' % name
shutil.copy(os.path.join(local_dir, filename), path)
- self._run(['gcc', filename, '-o', name, '-L.'] +
+ self._run(['gcc', '-g', filename, '-o', name, '-L.'] +
['%s.so' % modname for modname in modules] +
- ['-lpython2.7', '-Wl,-rpath=$ORIGIN/'])
+ ['-lpython2.7', '-Wl,-rpath=$ORIGIN/'] + extra)
def execute(self, name):
path = self.get_path()
@@ -52,7 +52,7 @@
self.prepare_module('add1')
self.compile('add1-test', ['_add1_cffi'])
output = self.execute('add1-test')
- assert output == ("preparing\n"
+ assert output == ("preparing...\n"
"adding 40 and 2\n"
"adding 100 and -5\n"
"got: 42 95\n")
@@ -62,7 +62,7 @@
self.prepare_module('add2')
self.compile('add2-test', ['_add1_cffi', '_add2_cffi'])
output = self.execute('add2-test')
- assert output == ("preparing\n"
+ assert output == ("preparing...\n"
"adding 40 and 2\n"
"preparing ADD2\n"
"adding 100 and -5 and -20\n"
diff --git a/testing/embedding/test_thread.py b/testing/embedding/test_thread.py
new file mode 100644
--- /dev/null
+++ b/testing/embedding/test_thread.py
@@ -0,0 +1,13 @@
+from testing.embedding.test_basic import EmbeddingTests
+
+
+class TestThread(EmbeddingTests):
+ def test_first_calls_in_parallel(self):
+ self.prepare_module('add1')
+ self.compile('thread1-test', ['_add1_cffi'], ['-pthread'])
+ for i in range(5):
+ output = self.execute('thread1-test')
+ assert output == ("starting\n"
+ "preparing...\n" +
+ "adding 40 and 2\n" * 10 +
+ "done\n")
diff --git a/testing/embedding/thread1-test.c b/testing/embedding/thread1-test.c
new file mode 100644
--- /dev/null
+++ b/testing/embedding/thread1-test.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <assert.h>
+
+#define NTHREADS 10
+
+
+extern int add1(int, int);
+
+static sem_t done;
+
+
+static void *start_routine(void *arg)
+{
+ int x, y, status;
+ x = add1(40, 2);
+ assert(x == 42);
+
+ status = sem_post(&done);
+ assert(status == 0);
+
+ return arg;
+}
+
+int main(void)
+{
+ pthread_t th;
+ int i, status = sem_init(&done, 0, 0);
+ assert(status == 0);
+
+ printf("starting\n");
+ for (i = 0; i < NTHREADS; i++) {
+ status = pthread_create(&th, NULL, start_routine, NULL);
+ assert(status == 0);
+ }
+ for (i = 1; i <= NTHREADS; i++) {
+ status = sem_wait(&done);
+ assert(status == 0);
+ }
+ printf("done\n");
+ return 0;
+}
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit