Skip to content

Commit

Permalink
Merge pull request #713 from shaitan/python
Browse files Browse the repository at this point in the history
python: wrap python_async_result::iterator to free GIL in long operations
  • Loading branch information
bioothod authored Jul 25, 2016
2 parents 77acf46 + f7b36e4 commit cf70a80
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 9 deletions.
49 changes: 47 additions & 2 deletions bindings/python/async_result.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,53 @@ error get_async_result_error(const python_async_result<T> &async) {
}

template <typename T>
struct def_async_result<T>
{
typename python_async_result<T>::iterator &python_async_result<T>::iterator::operator=(const iterator &other) {
py_allow_threads_scoped pythr;
m_inner = other.m_inner;
return *this;
}

template <typename T>
bool python_async_result<T>::iterator::operator==(const iterator &other) const {
py_allow_threads_scoped pythr;
return m_inner == other.m_inner;
}

template <typename T>
bool python_async_result<T>::iterator::operator!=(const iterator &other) const {
py_allow_threads_scoped pythr;
return m_inner != other.m_inner;
}

template <typename T>
T python_async_result<T>::iterator::operator*() const {
py_allow_threads_scoped pythr;
return *m_inner;
}

template <typename T>
T *python_async_result<T>::iterator::operator->() const {
py_allow_threads_scoped pythr;
return m_inner.operator->();
}

template <typename T>
typename python_async_result<T>::iterator &python_async_result<T>::iterator::operator++() {
py_allow_threads_scoped pythr;
++m_inner;
return *this;
}

template <typename T>
typename python_async_result<T>::iterator python_async_result<T>::iterator::operator++(int) {
py_allow_threads_scoped pythr;
iterator tmp(m_inner);
++m_inner;
return tmp;
}

template <typename T>
struct def_async_result<T> {
static void init() {
bp::class_<python_async_result<T>>(
"AsyncResult", "Future for waiting/getting results from asynchronous execution of operation")
Expand Down
35 changes: 28 additions & 7 deletions bindings/python/async_result.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,20 +89,39 @@ struct callback_one_handlers {
};

template <typename T>
struct python_async_result
{
typedef typename async_result<T>::iterator iterator;

std::shared_ptr<async_result<T>> scope;
struct python_async_result {
class iterator : public std::iterator<std::input_iterator_tag, T, std::ptrdiff_t, T *, T> {
public:
iterator()
: m_inner() {}
iterator(const typename async_result<T>::iterator &other)
: m_inner(other) {}
iterator(const iterator &other)
: m_inner(other.m_inner) {}
~iterator() {}

iterator &operator=(const iterator &other);

bool operator==(const iterator &other) const;
bool operator!=(const iterator &other) const;

T operator*() const;
T *operator->() const;

iterator &operator ++();
iterator operator ++(int);
private:
typename async_result<T>::iterator m_inner;
};

iterator begin() {
py_allow_threads_scoped pythr;
return scope->begin();
return iterator{scope->begin()};
}

iterator end() {
py_allow_threads_scoped pythr;
return scope->end();
return iterator{scope->end()};
}

bp::list get() {
Expand Down Expand Up @@ -152,6 +171,8 @@ struct python_async_result
auto callback = boost::make_shared<callback_all_handler<T>>(handler);
scope->connect(boost::bind(&callback_all_handler<T>::on_results, callback, _1, _2));
}

std::shared_ptr<async_result<T>> scope;
};

template <typename T>
Expand Down

0 comments on commit cf70a80

Please sign in to comment.