helics  3.0.1
AsioContextManager.h
1 /*
2 Copyright (c) 2017-2021,
3 Battelle Memorial Institute; Lawrence Livermore National Security, LLC; Alliance for Sustainable
4 Energy, LLC. See the top-level NOTICE for additional details. All rights reserved.
5 SPDX-License-Identifier: BSD-3-Clause
6 */
7 
8 /*
9  * LLNS Copyright Start
10  * Copyright (c) 2017, Lawrence Livermore National Security
11  * This work was performed under the auspices of the U.S. Department
12  * of Energy by Lawrence Livermore National Laboratory in part under
13  * Contract W-7405-Eng-48 and in part under Contract DE-AC52-07NA27344.
14  * Produced at the Lawrence Livermore National Laboratory.
15  * All rights reserved.
16  * For details, see the LICENSE file.
17  * LLNS Copyright End
18  */
19 
20 #pragma once
21 
22 #include <asio/io_context.hpp>
23 #include <atomic>
24 #include <future>
25 #include <map>
26 #include <memory>
27 #include <mutex>
28 #include <string>
29 #include <utility>
30 
32 class AsioContextManager: public std::enable_shared_from_this<AsioContextManager> {
33  private:
34  enum class loop_mode : int { stopped = 0, starting = 1, running = 2 };
35  static std::map<std::string, std::shared_ptr<AsioContextManager>>
36  contexts;
37  std::atomic<int> runCounter{
38  0};
39  std::string name;
40  std::unique_ptr<asio::io_context> ictx;
41  std::unique_ptr<asio::io_context::work>
42  nullwork;
43  bool leakOnDelete = false;
44  std::atomic<loop_mode> running{loop_mode::stopped};
45  std::mutex runningLoopLock;
46  std::atomic<bool> terminateLoop{false};
47  std::future<void> loopRet;
49  explicit AsioContextManager(const std::string& contextName);
50 
52  class Servicer {
53  public:
54  explicit Servicer(std::shared_ptr<AsioContextManager> manager):
55  contextManager(std::move(manager))
56  {
57  }
59  ~Servicer()
60  {
61  if (contextManager) {
62  try {
63  contextManager->haltContextLoop();
64  }
65  catch (...) {
66  // no exceptions in a destructor
67  }
68  }
69  }
71  Servicer(Servicer&& sv) = default;
72 
73  private:
74  std::shared_ptr<AsioContextManager> contextManager;
75  };
76 
77  public:
78  using LoopHandle = std::unique_ptr<Servicer>;
79 
84  static std::shared_ptr<AsioContextManager>
85  getContextPointer(const std::string& contextName = std::string());
91  static std::shared_ptr<AsioContextManager>
92  getExistingContextPointer(const std::string& contextName = std::string());
95  static asio::io_context& getContext(const std::string& contextName = std::string());
99  static asio::io_context& getExistingContext(const std::string& contextName = std::string());
100 
101  static void closeContext(const std::string& contextName = std::string());
109  static void setContextToLeakOnDelete(const std::string& contextName = std::string());
110  virtual ~AsioContextManager();
111 
113  const std::string& getName() const { return name; }
114 
116  asio::io_context& getBaseContext() const { return *ictx; }
117 
124  static LoopHandle runContextLoop(const std::string& contextName = std::string{});
125 
131  LoopHandle startContextLoop();
133  bool isRunning() const { return (running.load() != loop_mode::stopped); }
134 
135  private:
140  void haltContextLoop();
141 
142  friend void contextProcessingLoop(std::shared_ptr<AsioContextManager> ptr);
143 };
144 
145 void contextProcessingLoop(std::shared_ptr<AsioContextManager> ptr);
AsioContextManager::getContextPointer
static std::shared_ptr< AsioContextManager > getContextPointer(const std::string &contextName=std::string())
Definition: AsioContextManager.cpp:38
AsioContextManager::isRunning
bool isRunning() const
Definition: AsioContextManager.h:133
AsioContextManager::getContext
static asio::io_context & getContext(const std::string &contextName=std::string())
Definition: AsioContextManager.cpp:70
AsioContextManager::getName
const std::string & getName() const
Definition: AsioContextManager.h:113
AsioContextManager::getBaseContext
asio::io_context & getBaseContext() const
Definition: AsioContextManager.h:116
AsioContextManager
Definition: AsioContextManager.h:32
AsioContextManager::getExistingContext
static asio::io_context & getExistingContext(const std::string &contextName=std::string())
Definition: AsioContextManager.cpp:75
AsioContextManager::setContextToLeakOnDelete
static void setContextToLeakOnDelete(const std::string &contextName=std::string())
Definition: AsioContextManager.cpp:102
AsioContextManager::runContextLoop
static LoopHandle runContextLoop(const std::string &contextName=std::string{})
Definition: AsioContextManager.cpp:139
AsioContextManager::startContextLoop
LoopHandle startContextLoop()
Definition: AsioContextManager.cpp:151
AsioContextManager::getExistingContextPointer
static std::shared_ptr< AsioContextManager > getExistingContextPointer(const std::string &contextName=std::string())
Definition: AsioContextManager.cpp:57