| Index: mojo/public/python/src/python_system_helper.cc
|
| diff --git a/mojo/public/python/src/python_system_helper.cc b/mojo/public/python/src/python_system_helper.cc
|
| index 22b6bbb4a5d47eff3e459168b387df4e58b3ddf9..ceab1d02825f90ecefacfd31766bf3339f18484b 100644
|
| --- a/mojo/public/python/src/python_system_helper.cc
|
| +++ b/mojo/public/python/src/python_system_helper.cc
|
| @@ -6,173 +6,37 @@
|
|
|
| #include "Python.h"
|
|
|
| -#include "mojo/public/cpp/environment/environment.h"
|
| -#include "mojo/public/cpp/environment/logging.h"
|
| -#include "mojo/public/cpp/system/macros.h"
|
| #include "mojo/public/cpp/utility/run_loop.h"
|
| +#include "mojo/public/python/src/common.h"
|
|
|
| namespace {
|
| -
|
| -class ScopedGIL {
|
| - public:
|
| - ScopedGIL() { state_ = PyGILState_Ensure(); }
|
| -
|
| - ~ScopedGIL() { PyGILState_Release(state_); }
|
| -
|
| - private:
|
| - PyGILState_STATE state_;
|
| -
|
| - MOJO_DISALLOW_COPY_AND_ASSIGN(ScopedGIL);
|
| -};
|
| -
|
| -enum ScopedPyRefAcquire {
|
| - kAcquire,
|
| -};
|
| -
|
| -class ScopedPyRef {
|
| +class QuitCurrentRunLoop : public mojo::Closure::Runnable {
|
| public:
|
| - ScopedPyRef(PyObject* object) : object_(object) {}
|
| - ScopedPyRef(PyObject* object, ScopedPyRefAcquire) : object_(object) {
|
| - Py_XINCREF(object_);
|
| - }
|
| -
|
| - ~ScopedPyRef() {
|
| - if (object_) {
|
| - ScopedGIL acquire_gil;
|
| - Py_DECREF(object_);
|
| - }
|
| - }
|
| -
|
| - operator PyObject*() const { return object_; }
|
| -
|
| - private:
|
| - PyObject* object_;
|
| -
|
| - MOJO_DISALLOW_COPY_AND_ASSIGN(ScopedPyRef);
|
| -};
|
| -
|
| -class PythonClosure : public mojo::Closure::Runnable {
|
| - public:
|
| - PythonClosure(PyObject* callable) : callable_(callable, kAcquire) {
|
| - MOJO_DCHECK(callable);
|
| - }
|
| -
|
| void Run() const override {
|
| - ScopedGIL acquire_gil;
|
| - ScopedPyRef empty_tuple(PyTuple_New(0));
|
| - if (!empty_tuple) {
|
| - mojo::RunLoop::current()->Quit();
|
| - return;
|
| - }
|
| -
|
| - ScopedPyRef result(PyObject_CallObject(callable_, empty_tuple));
|
| - if (!result) {
|
| - mojo::RunLoop::current()->Quit();
|
| - return;
|
| - }
|
| + mojo::RunLoop::current()->Quit();
|
| }
|
|
|
| - private:
|
| - ScopedPyRef callable_;
|
| -
|
| - MOJO_DISALLOW_COPY_AND_ASSIGN(PythonClosure);
|
| + static mojo::Closure NewQuitClosure() {
|
| + return mojo::Closure(
|
| + static_cast<mojo::Closure::Runnable*>(new QuitCurrentRunLoop()));
|
| + }
|
| };
|
|
|
| -void AsyncCallbackForwarder(void* closure, MojoResult result) {
|
| - mojo::Callback<void(MojoResult)>* callback =
|
| - static_cast<mojo::Callback<void(MojoResult)>*>(closure);
|
| - // callback will be deleted when it is run.
|
| - callback->Run(result);
|
| -}
|
| -
|
| } // namespace
|
|
|
| namespace mojo {
|
| namespace python {
|
|
|
| -class PythonAsyncWaiter::AsyncWaiterRunnable
|
| - : public mojo::Callback<void(MojoResult)>::Runnable {
|
| - public:
|
| - AsyncWaiterRunnable(PyObject* callable, CallbackMap* callbacks)
|
| - : wait_id_(0), callable_(callable, kAcquire), callbacks_(callbacks) {
|
| - MOJO_DCHECK(callable);
|
| - MOJO_DCHECK(callbacks_);
|
| - }
|
| -
|
| - void set_wait_id(int wait_id) { wait_id_ = wait_id; }
|
| -
|
| - void Run(MojoResult mojo_result) const override {
|
| - MOJO_DCHECK(wait_id_);
|
| -
|
| - // Remove to reference to this object from PythonAsyncWaiter and ensure this
|
| - // object will be destroyed when this method exits.
|
| - MOJO_DCHECK(callbacks_->find(wait_id_) != callbacks_->end());
|
| - internal::SharedPtr<mojo::Callback<void(MojoResult)>> self =
|
| - (*callbacks_)[wait_id_];
|
| - callbacks_->erase(wait_id_);
|
| -
|
| - ScopedGIL acquire_gil;
|
| - ScopedPyRef args_tuple(Py_BuildValue("(i)", mojo_result));
|
| - if (!args_tuple) {
|
| - mojo::RunLoop::current()->Quit();
|
| - return;
|
| - }
|
| -
|
| - ScopedPyRef result(PyObject_CallObject(callable_, args_tuple));
|
| - if (!result) {
|
| - mojo::RunLoop::current()->Quit();
|
| - return;
|
| - }
|
| - }
|
| -
|
| - private:
|
| - MojoAsyncWaitID wait_id_;
|
| - ScopedPyRef callable_;
|
| - CallbackMap* callbacks_;
|
| -
|
| - MOJO_DISALLOW_COPY_AND_ASSIGN(AsyncWaiterRunnable);
|
| -};
|
| -
|
| Closure BuildClosure(PyObject* callable) {
|
| if (!PyCallable_Check(callable))
|
| return Closure();
|
|
|
| - return Closure(
|
| - static_cast<mojo::Closure::Runnable*>(new PythonClosure(callable)));
|
| + return mojo::Closure(
|
| + NewRunnableFromClosure(callable, QuitCurrentRunLoop::NewQuitClosure()));
|
| }
|
|
|
| -PythonAsyncWaiter::PythonAsyncWaiter() {
|
| - async_waiter_ = Environment::GetDefaultAsyncWaiter();
|
| -}
|
| -
|
| -PythonAsyncWaiter::~PythonAsyncWaiter() {
|
| - for (CallbackMap::const_iterator it = callbacks_.begin();
|
| - it != callbacks_.end();
|
| - ++it) {
|
| - async_waiter_->CancelWait(it->first);
|
| - }
|
| -}
|
| -
|
| -MojoAsyncWaitID PythonAsyncWaiter::AsyncWait(MojoHandle handle,
|
| - MojoHandleSignals signals,
|
| - MojoDeadline deadline,
|
| - PyObject* callable) {
|
| - AsyncWaiterRunnable* runner = new AsyncWaiterRunnable(callable, &callbacks_);
|
| - internal::SharedPtr<mojo::Callback<void(MojoResult)>> callback(
|
| - new mojo::Callback<void(MojoResult)>(
|
| - static_cast<mojo::Callback<void(MojoResult)>::Runnable*>(runner)));
|
| - MojoAsyncWaitID wait_id = async_waiter_->AsyncWait(
|
| - handle, signals, deadline, &AsyncCallbackForwarder, callback.get());
|
| - callbacks_[wait_id] = callback;
|
| - runner->set_wait_id(wait_id);
|
| - return wait_id;
|
| -}
|
| -
|
| -void PythonAsyncWaiter::CancelWait(MojoAsyncWaitID wait_id) {
|
| - if (callbacks_.find(wait_id) != callbacks_.end()) {
|
| - async_waiter_->CancelWait(wait_id);
|
| - callbacks_.erase(wait_id);
|
| - }
|
| +PythonAsyncWaiter* NewAsyncWaiter() {
|
| + return new PythonAsyncWaiter(QuitCurrentRunLoop::NewQuitClosure());
|
| }
|
|
|
| } // namespace python
|
|
|