diff --git a/build/Jamfile b/build/Jamfile
index dbc9fb2036..bfb6c5539b 100644
--- a/build/Jamfile
+++ b/build/Jamfile
@@ -68,6 +68,7 @@ lib boost_python
import.cpp
exec.cpp
object/function_doc_signature.cpp
+ eventloop.cpp
: # requirements
static:BOOST_PYTHON_STATIC_LIB
BOOST_PYTHON_SOURCE
diff --git a/include/boost/python/eventloop.hpp b/include/boost/python/eventloop.hpp
index 7d1bda42ba..78fb48c8a9 100644
--- a/include/boost/python/eventloop.hpp
+++ b/include/boost/python/eventloop.hpp
@@ -9,11 +9,8 @@
# ifndef EVENT_LOOP_PY2021_H_
# define EVENT_LOOP_PY2021_H_
-#include
-#include
#include
#include
-#include
#include
namespace a = boost::asio;
@@ -32,40 +29,8 @@ class EventLoop
std::unordered_map> _descriptor_map;
std::chrono::steady_clock::time_point _created_time;
- void _add_reader_or_writer(int fd, py::object f, int key)
- {
- // add descriptor
- if (_descriptor_map.find(key) == _descriptor_map.end())
- {
- _descriptor_map.emplace(key,
- std::move(std::make_unique(_strand.context(), fd))
- );
- }
-
- _descriptor_map.find(key)->second->async_wait(a::posix::descriptor::wait_type::wait_read,
- a::bind_executor(_strand, [key, f, loop=this] (const boost::system::error_code& ec)
- {
- // move descriptor
- auto iter = loop->_descriptor_map.find(key);
- if (iter != loop->_descriptor_map.end())
- {
- iter->second->release();
- loop->_descriptor_map.erase(iter);
- }
- loop->call_soon(f);
- }));
- return;
- }
-
- void _remove_reader_or_writer(int key)
- {
- auto iter = _descriptor_map.find(key);
- if (iter != _descriptor_map.end())
- {
- iter->second->release();
- _descriptor_map.erase(iter);
- }
- }
+ void _add_reader_or_writer(int fd, py::object f, int key);
+ void _remove_reader_or_writer(int key);
public:
EventLoop(a::io_context& ctx):
@@ -83,98 +48,53 @@ class EventLoop
}
// TODO: implement this
- void call_soon_thread_safe(py::object f)
- {
- return;
- }
+ inline void call_soon_thread_safe(py::object f) {};
// Schedule callback to be called after the given delay number of seconds
// TODO: An instance of asyncio.Handle is returned, which can be used later to cancel the callback.
- void call_later(double delay, py::object f)
- {
- // add timer
- _id_to_timer_map.emplace(_timer_id,
- std::move(std::make_unique(_strand.context(),
- std::chrono::steady_clock::now() + std::chrono::nanoseconds(int64_t(delay * 1e9))))
- );
-
- _id_to_timer_map.find(_timer_id)->second->async_wait(
- // remove timer
- a::bind_executor(_strand, [id=_timer_id, f, loop=this] (const boost::system::error_code& ec)
- {
- loop->_id_to_timer_map.erase(id);
- loop->call_soon(f);
- }));
- _timer_id++;
- }
+ void call_later(double delay, py::object f);
- void call_at(double when, py::object f)
- {
- double diff = when - time();
- if (diff > 0)
- return call_later(diff, f);
- return call_soon(f);
- }
+ void call_at(double when, py::object f);
- double time()
+ inline double time()
{
- auto now = std::chrono::steady_clock::now();
- std::chrono::duration diff = now - _created_time;
- return diff.count();
+ return static_cast>(std::chrono::steady_clock::now() - _created_time).count();
}
// week 2 ......start......
- void add_reader(int fd, py::object f)
+ inline void add_reader(int fd, py::object f)
{
_add_reader_or_writer(fd, f, fd * 2);
}
- void remove_reader(int fd)
+ inline void remove_reader(int fd)
{
_remove_reader_or_writer(fd * 2);
}
- void add_writer(int fd, py::object f)
+ inline void add_writer(int fd, py::object f)
{
_add_reader_or_writer(fd, f, fd * 2 + 1);
}
- void remove_writer(int fd)
+ inline void remove_writer(int fd)
{
_remove_reader_or_writer(fd * 2 + 1);
}
- void sock_recv()
- {
-
- }
-
- void sock_recv_into()
- {
-
- }
-
- void sock_sendall()
- {
+ void sock_recv(py::object sock, int bytes);
- }
+ void sock_recv_into(py::object sock, py::object buffer);
- void sock_connect()
- {
+ void sock_sendall(py::object sock, py::object data);
- }
-
- void sock_accept()
- {
+ void sock_connect(py::object sock, py::object address);
- }
-
- void sock_sendfile()
- {
-
- }
+ void sock_accept(py::object sock);
+
+ void sock_sendfile(py::object sock, py::object file, int offset = 0, int count = 0, bool fallback = true);
// week 2 ......end......
diff --git a/src/eventloop.cpp b/src/eventloop.cpp
new file mode 100644
index 0000000000..cf2c8ab8b6
--- /dev/null
+++ b/src/eventloop.cpp
@@ -0,0 +1,111 @@
+// Copyright Pan Yue 2021.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// TODO:
+// 1. posix::stream_descriptor need windows version
+// 2. call_* need return async.Handle
+
+#include
+#include
+#include
+
+namespace a = boost::asio;
+namespace c = std::chrono;
+namespace py = boost::python;
+
+namespace boost { namespace python { namespace eventloop {
+
+void EventLoop::_add_reader_or_writer(int fd, py::object f, int key)
+{
+ // add descriptor
+ if (_descriptor_map.find(key) == _descriptor_map.end())
+ {
+ _descriptor_map.emplace(key,
+ std::move(std::make_unique(_strand.context(), fd))
+ );
+ }
+
+ _descriptor_map.find(key)->second->async_wait(a::posix::descriptor::wait_type::wait_read,
+ a::bind_executor(_strand, [key, f, loop=this] (const boost::system::error_code& ec)
+ {
+ // move descriptor
+ auto iter = loop->_descriptor_map.find(key);
+ if (iter != loop->_descriptor_map.end())
+ {
+ iter->second->release();
+ loop->_descriptor_map.erase(iter);
+ }
+ loop->call_soon(f);
+ }));
+ return;
+}
+
+void EventLoop::_remove_reader_or_writer(int key)
+{
+ auto iter = _descriptor_map.find(key);
+ if (iter != _descriptor_map.end())
+ {
+ iter->second->release();
+ _descriptor_map.erase(iter);
+ }
+}
+
+void EventLoop::call_later(double delay, py::object f)
+{
+ // add timer
+ _id_to_timer_map.emplace(_timer_id,
+ std::move(std::make_unique(_strand.context(),
+ std::chrono::steady_clock::now() + std::chrono::nanoseconds(int64_t(delay * 1e9))))
+ );
+
+ _id_to_timer_map.find(_timer_id)->second->async_wait(
+ // remove timer
+ a::bind_executor(_strand, [id=_timer_id, f, loop=this] (const boost::system::error_code& ec)
+ {
+ loop->_id_to_timer_map.erase(id);
+ loop->call_soon(f);
+ }));
+ _timer_id++;
+}
+
+void EventLoop::call_at(double when, py::object f)
+{
+ double diff = when - time();
+ if (diff > 0)
+ return call_later(diff, f);
+ return call_soon(f);
+}
+
+void EventLoop::sock_recv(py::object sock, int bytes)
+{
+
+}
+
+void EventLoop::sock_recv_into(py::object sock, py::object buffer)
+{
+
+}
+
+void EventLoop::sock_sendall(py::object sock, py::object data)
+{
+
+}
+
+void EventLoop::sock_connect(py::object sock, py::object address)
+{
+
+}
+
+void EventLoop::sock_accept(py::object sock)
+{
+
+}
+
+void EventLoop::sock_sendfile(py::object sock, py::object file, int offset, int count, bool fallback)
+{
+
+}
+
+}}}
\ No newline at end of file
diff --git a/src/fabscript b/src/fabscript
index 0ebeac6098..6c5b858351 100644
--- a/src/fabscript
+++ b/src/fabscript
@@ -40,7 +40,8 @@ bpl = library('boost_python' + root.py_suffix,
'wrapper.cpp',
'import.cpp',
'exec.cpp',
- 'object/function_doc_signature.cpp'],
+ 'object/function_doc_signature.cpp',
+ 'eventloop.cpp'],
dependencies=root.config,
features=features + define('BOOST_PYTHON_SOURCE'))