Skip to content

Commit

Permalink
Test for reuse of CPPOverload proxies in vector calls from different …
Browse files Browse the repository at this point in the history
…threads
  • Loading branch information
wlav committed May 15, 2022
1 parent c4ec1cf commit 4f40c72
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 2 deletions.
1 change: 1 addition & 0 deletions doc/source/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ master: 2.4.0
* Fix lookup of templates of function with template args
* Correct typing of int8_t/uint8_t enums
* Basic support for hidden enums
* Fix reuse of CPPOverload proxies in vector calls from different threads


2022-04-03: 2.3.1
Expand Down
72 changes: 71 additions & 1 deletion test/test_concurrent.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def test03_timeout(self):
if t.is_alive(): # was timed-out
cppyy.gbl.test12_timeout.stopit[0] = True

def test04_cpp_threading(self):
def test04_cpp_threading_with_exceptions(self):
"""Threads and Python exceptions"""

if IS_MAC_ARM:
Expand Down Expand Up @@ -226,3 +226,73 @@ def process(self, data, channels, samples):

p = Processor()
cppyy.gbl.FloatDim2.callback(p)

def test06_overload_reuse_in_threads(self):
"""Threads reuse overload objects; check for clashes"""

import cppyy
import threading

cppyy.cppdef("""\
namespace CPPOverloadReuse {
class Simulation1 {
public:
virtual void set_something(std::map<std::string, std::string>, std::string) {}
}; }""")

def test():
o = {"a": "b"} # causes a temporary to be created
simulation = cppyy.gbl.CPPOverloadReuse.Simulation1()
simulation.set_something(o, ".")

threads = [threading.Thread(target=test) for i in range(0, 100)]

for t in threads:
t.start()

for t in threads:
t.join()

def test07_overload_reuse_in_threads_wo_gil(self):
"""Threads reuse overload objects; check for clashes if no GIL"""

import cppyy
import threading

cppyy.cppdef("""\
namespace CPPOverloadReuse {
class Simulation2 {
int fCount;
public:
Simulation2(int count) : fCount(count) {}
virtual int do_something() { return fCount; }
}; }""")

cppyy.gbl.CPPOverloadReuse.Simulation2.do_something.__release_gil__ = True

class State(object):
lock = threading.Lock()
c1, c2, c3 = 0, 0, 0

def test(i, state=State):
#global c1, c2, c3, lock

simulation = cppyy.gbl.CPPOverloadReuse.Simulation2(i)
res = simulation.do_something()

with state.lock:
state.c3 += state.c1
state.c2 += res
state.c1 += 1

threads = [threading.Thread(target=test, args=[i]) for i in range(0, 1000)]

for t in threads:
t.start()

for t in threads:
t.join()

assert State.c1 == 1000
assert State.c2 == State.c3

1 change: 1 addition & 0 deletions test/test_conversions.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def test02_memory_handling_of_temporaries(self):

assert CC.s_count == 0
c = CC()
assert c.__python_owns__
assert CC.s_count == 1
del c; gc.collect()
assert CC.s_count == 0
Expand Down
2 changes: 1 addition & 1 deletion test/test_templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -1085,7 +1085,7 @@ class TNaVU;
n += 1
cppyy.cppdef(cpp.format(v=v, f=f, i=i, n=n))
for t in types:
run_n = getattr(cppyy.gbl, f'TNaRun_{n}')
run_n = getattr(cppyy.gbl, 'TNaRun_%d' % n)
getattr(run_n, t)


Expand Down

0 comments on commit 4f40c72

Please sign in to comment.