/
Neitrinok
/
seastar
Обзор
Документация
Войти
/
Neitrinok
/
seastar
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/core/syscall_work_queue.hh
89 строк
3 KB
Kefu Chai
treewide: add C++ modules support
24 май 2023, 13:36
24 май 2023, 13:36
aa1c8b3
Код
Авторство
О чём код?
/* * This file is open source software, licensed to you under the terms * of the Apache License, Version 2.0 (the "License"). See the NOTICE file * distributed with this work for additional information regarding copyright * ownership. 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. */ /* * Copyright 2019 ScyllaDB */ #pragma once #include <seastar/core/internal/pollable_fd.hh> #include <seastar/core/future.hh> #include <seastar/core/semaphore.hh> #include <seastar/util/std-compat.hh> #include <seastar/util/noncopyable_function.hh> #include <seastar/util/modules.hh> #ifndef SEASTAR_MODULE #include <boost/lockfree/spsc_queue.hpp> #endif namespace seastar { class syscall_work_queue { static constexpr size_t queue_length = 128; struct work_item; using lf_queue = boost::lockfree::spsc_queue<work_item*, boost::lockfree::capacity<queue_length>>; lf_queue _pending; lf_queue _completed; writeable_eventfd _start_eventfd; semaphore _queue_has_room = { queue_length }; struct work_item { virtual ~work_item() {} virtual void process() = 0; virtual void complete() = 0; virtual void set_exception(std::exception_ptr) = 0; }; template <typename T> struct work_item_returning : work_item { noncopyable_function<T ()> _func; promise<T> _promise; std::optional<T> _result; work_item_returning(noncopyable_function<T ()> func) : _func(std::move(func)) {} virtual void process() override { _result = this->_func(); } virtual void complete() override { _promise.set_value(std::move(*_result)); } virtual void set_exception(std::exception_ptr eptr) override { _promise.set_exception(eptr); }; future<T> get_future() { return _promise.get_future(); } }; public: syscall_work_queue(); template <typename T> future<T> submit(noncopyable_function<T ()> func) noexcept { try { auto wi = std::make_unique<work_item_returning<T>>(std::move(func)); auto fut = wi->get_future(); submit_item(std::move(wi)); return fut; } catch (...) { return current_exception_as_future<T>(); } } private: void work(); // Scans the _completed queue, that contains the requests already handled by the syscall thread, // effectively opening up space for more requests to be submitted. One consequence of this is // that from the reactor's point of view, a request is not considered handled until it is // removed from the _completed queue. // // Returns the number of requests handled. unsigned complete(); void submit_item(std::unique_ptr<syscall_work_queue::work_item> wi); friend class thread_pool; }; }