blob: a2ef53108d35a7020f6909daa8c324f66b9d7496 [file] [log] [blame]
// Copyright (C) 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "awaitable_qe_call.h"
#include "pyobj.h"
namespace dctv {
using std::unique_ptr;
AwaitableQeCall::AwaitableQeCall(unique_ptr<QeCall> request) noexcept
: request(std::move(request))
{
assert(this->request);
}
unique_pyref
AwaitableQeCall::next()
{
if (!this->drained) {
this->drained = true;
return addref(this);
}
return this->send(Py_None);
}
unique_pyref
AwaitableQeCall::send(pyref obj)
{
if (_PyGen_SetStopIterationValue(obj.get()))
throw_current_pyerr();
return {};
}
unique_ptr<QeCall>
AwaitableQeCall::extract_request()
{
if (!this->request)
throw_pyerr_msg(PyExc_RuntimeError,
"request already extracted");
return std::move(this->request);
}
int
AwaitableQeCall::py_traverse(visitproc visit, void* arg) const noexcept
{
if (this->request)
if (int ret = this->request->py_traverse(visit, arg); ret)
return ret;
return 0;
}
int
AwaitableQeCall::py_clear() noexcept
{
safe_clear(&this->request);
return 0;
}
PyAsyncMethods AwaitableQeCall::pyasync[] = {
return_self /* am_await */,
nullptr /* am_aiter */,
nullptr /* am_anext */,
};
PyMethodDef AwaitableQeCall::pymethods[] = {
make_methoddef("send",
wraperr<&AwaitableQeCall::send>(),
METH_O,
"Send QeCall reply"),
{ 0 },
};
PyTypeObject AwaitableQeCall::pytype =
make_py_type<AwaitableQeCall>(
"dctv._native.AwaitableQeCall",
"Operator request for the query core",
[](PyTypeObject* t) {
t->tp_iter = return_self;
t->tp_iternext = wraperr<&AwaitableQeCall::next>();
t->tp_as_async = AwaitableQeCall::pyasync;
t->tp_methods = AwaitableQeCall::pymethods;
});
unique_pyref
make_qe_call(std::unique_ptr<QeCall> qe_call)
{
return make_pyobj<AwaitableQeCall>(std::move(qe_call));
}
void
init_awaitable_qe_call(pyref m)
{
register_type(m, &AwaitableQeCall::pytype);
}
} // namespace dctv