X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=src%2Feventfd.cpp;fp=src%2Feventfd.cpp;h=6a0b14a67916b104a73320b81e8ece2eb477f41a;hb=ef2bf51d04aaf01fa0cabdcaf905b23423067662;hp=0000000000000000000000000000000000000000;hpb=edc9b96a441194b571e8d55ec1603b5be0ea52eb;p=ric-plt%2Fsdl.git diff --git a/src/eventfd.cpp b/src/eventfd.cpp new file mode 100644 index 0000000..6a0b14a --- /dev/null +++ b/src/eventfd.cpp @@ -0,0 +1,96 @@ +/* + Copyright (c) 2018-2019 Nokia. + + 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 "private/eventfd.hpp" +#include +#include "private/abort.hpp" +#include "private/engine.hpp" +#include "private/system.hpp" + +using namespace shareddatalayer; + +namespace +{ + /* + * Simple wrapper for executing the given callback without expecting + * exceptions. If callback throws, we'll crash. + */ + void execute(const EventFD::Callback& callback) noexcept + { + callback(); + } +} + +EventFD::EventFD(Engine& engine): + EventFD(System::getSystem(), engine) +{ +} + +EventFD::EventFD(System& system, Engine& engine): + system(system), + fd(system, system.eventfd(0U, EFD_CLOEXEC | EFD_NONBLOCK)) +{ + engine.addMonitoredFD(fd, Engine::EVENT_IN, std::bind(&EventFD::handleEvents, this)); +} + +EventFD::~EventFD() +{ +} + +void EventFD::post(const Callback& callback) +{ + if (!callback) + SHAREDDATALAYER_ABORT("A null callback was provided"); + + atomicPushBack(callback); + static const uint64_t value(1U); + system.write(fd, &value, sizeof(value)); +} + +void EventFD::atomicPushBack(const Callback& callback) +{ + std::lock_guard guard(callbacksMutex); + callbacks.push_back(callback); +} + +EventFD::Callbacks EventFD::atomicPopAll() +{ + std::lock_guard guard(callbacksMutex); + Callbacks extractedCallbacks; + std::swap(callbacks, extractedCallbacks); + return extractedCallbacks; +} + +void EventFD::handleEvents() +{ + uint64_t value; + system.read(fd, &value, sizeof(value)); + executeCallbacks(); +} + +void EventFD::executeCallbacks() +{ + Callbacks callbacks(atomicPopAll()); + while (!callbacks.empty()) + popAndExecuteFirstCallback(callbacks); +} + +void EventFD::popAndExecuteFirstCallback(Callbacks& callbacks) +{ + const auto callback(callbacks.front()); + callbacks.pop_front(); + execute(callback); +}