Commit c92a4830 authored by Kirill Smelkov's avatar Kirill Smelkov

libgolang: tests: waitBlocked: Allow to specify for how many receivers/senders should be blocked

This will be needed in the next patch.
parent 44737253
...@@ -47,9 +47,9 @@ def pylen_sendq(pychan pych not None): # -> int ...@@ -47,9 +47,9 @@ def pylen_sendq(pychan pych not None): # -> int
# runtime/libgolang_test.cpp # runtime/libgolang_test.cpp
cdef extern from *: cdef extern from *:
""" """
extern void waitBlocked(golang::_chan *ch, bool rx, bool tx); extern void waitBlocked(golang::_chan *ch, int nrx, int ntx);
""" """
void waitBlocked(_chan *, bint rx, bint tx) nogil except +topyexc void waitBlocked(_chan *, int nrx, int ntx) nogil except +topyexc
# pywaitBlocked waits till a receive or send pychan operation blocks waiting on the channel. # pywaitBlocked waits till a receive or send pychan operation blocks waiting on the channel.
# #
...@@ -58,17 +58,17 @@ def pywaitBlocked(pychanop): ...@@ -58,17 +58,17 @@ def pywaitBlocked(pychanop):
if pychanop.__self__.__class__ is not pychan: if pychanop.__self__.__class__ is not pychan:
pypanic("wait blocked: %r is method of a non-chan: %r" % (pychanop, pychanop.__self__.__class__)) pypanic("wait blocked: %r is method of a non-chan: %r" % (pychanop, pychanop.__self__.__class__))
cdef pychan pych = pychanop.__self__ cdef pychan pych = pychanop.__self__
cdef bint recv = False cdef int nrecv = 0
cdef bint send = False cdef int nsend = 0
if pychanop.__name__ == "recv": # XXX better check PyCFunction directly if pychanop.__name__ == "recv": # XXX better check PyCFunction directly
recv = True nrecv = 1
elif pychanop.__name__ == "send": # XXX better check PyCFunction directly elif pychanop.__name__ == "send": # XXX better check PyCFunction directly
send = True nsend = 1
else: else:
pypanic("wait blocked: unexpected chan method: %r" % (pychanop,)) pypanic("wait blocked: unexpected chan method: %r" % (pychanop,))
with nogil: with nogil:
waitBlocked(pych.ch._rawchan(), recv, send) waitBlocked(pych.ch._rawchan(), nrecv, nsend)
# `with pypanicWhenBlocked` hooks into libgolang _blockforever to raise panic with # `with pypanicWhenBlocked` hooks into libgolang _blockforever to raise panic with
......
...@@ -144,17 +144,15 @@ void _test_chan_cpp() { ...@@ -144,17 +144,15 @@ void _test_chan_cpp() {
//chan<chan<int>> zzz; //chan<chan<int>> zzz;
} }
// waitBlocked waits until either a receive (if rx) or send (if tx) operation // waitBlocked waits until at least nrx recv and ntx send operations block
// blocks waiting on the channel. // waiting on the channel.
void waitBlocked(_chan *ch, bool rx, bool tx) { void waitBlocked(_chan *ch, int nrx, int ntx) {
if (ch == NULL) if (ch == NULL)
panic("wait blocked: called on nil channel"); panic("wait blocked: called on nil channel");
double t0 = time::now(); double t0 = time::now();
while (1) { while (1) {
if (rx && (_tchanrecvqlen(ch) != 0)) if ((_tchanrecvqlen(ch) >= nrx) && (_tchansendqlen(ch) >= ntx))
return;
if (tx && (_tchansendqlen(ch) != 0))
return; return;
double now = time::now(); double now = time::now();
...@@ -165,10 +163,10 @@ void waitBlocked(_chan *ch, bool rx, bool tx) { ...@@ -165,10 +163,10 @@ void waitBlocked(_chan *ch, bool rx, bool tx) {
} }
template<typename T> void waitBlocked_RX(chan<T> ch) { template<typename T> void waitBlocked_RX(chan<T> ch) {
waitBlocked(ch._rawchan(), /*rx=*/true, /*tx=*/0); waitBlocked(ch._rawchan(), /*nrx=*/1, /*ntx=*/0);
} }
template<typename T> void waitBlocked_TX(chan<T> ch) { template<typename T> void waitBlocked_TX(chan<T> ch) {
waitBlocked(ch._rawchan(), /*rx=*/0, /*tx=*/true); waitBlocked(ch._rawchan(), /*nrx=*/0, /*ntx=*/1);
} }
// usestack_and_call pushes C-stack down and calls f from that. // usestack_and_call pushes C-stack down and calls f from that.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment