OSVR-Core
ServerImpl.h
Go to the documentation of this file.
1 
11 // Copyright 2014 Sensics, Inc.
12 //
13 // Licensed under the Apache License, Version 2.0 (the "License");
14 // you may not use this file except in compliance with the License.
15 // You may obtain a copy of the License at
16 //
17 // http://www.apache.org/licenses/LICENSE-2.0
18 //
19 // Unless required by applicable law or agreed to in writing, software
20 // distributed under the License is distributed on an "AS IS" BASIS,
21 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 // See the License for the specific language governing permissions and
23 // limitations under the License.
24 
25 #ifndef INCLUDED_ServerImpl_h_GUID_BA15589C_D1AD_4BBE_4F93_8AC87043A982
26 #define INCLUDED_ServerImpl_h_GUID_BA15589C_D1AD_4BBE_4F93_8AC87043A982
27 
28 // Internal Includes
31 #include <osvr/Common/LowLatency.h>
32 #include <osvr/Common/PathTree.h>
38 #include <osvr/Server/Server.h>
39 #include <osvr/Util/Flag.h>
40 #include <osvr/Util/Log.h>
41 #include <osvr/Util/SharedPtr.h>
42 #include <osvr/Util/UniquePtr.h>
43 
44 // Library/third-party includes
45 #include <boost/noncopyable.hpp>
46 #include <boost/optional.hpp>
47 #include <boost/thread.hpp>
48 
49 #include <json/value.h>
51 #include <vrpn_Connection.h>
52 
53 // Standard includes
54 #include <string>
55 
56 namespace osvr {
57 namespace server {
58 
60  class ServerImpl : boost::noncopyable {
61  public:
64  boost::optional<std::string> const &host,
65  boost::optional<int> const &port);
66 
68  ~ServerImpl();
69 
71  void start();
72 
75  void startAndAwaitShutdown();
76 
78  void awaitShutdown();
79 
81  void stop();
82 
85  void signalStop();
86 
88  void loadPlugin(std::string const &pluginName);
89 
91  void loadAutoPlugins();
92 
95 
97  void triggerHardwareDetect();
98 
101 
103  bool addRoute(std::string const &routingDirective);
104 
106  bool addAlias(std::string const &path, std::string const &source,
107  common::AliasPriority priority);
108 
110  bool addAliases(Json::Value const &aliases,
111  common::AliasPriority priority);
112 
114  void addExternalDevice(std::string const &path,
115  std::string const &deviceName,
116  std::string const &server,
117  std::string const &descriptor);
118 
120  bool addString(std::string const &path, std::string const &value);
121 
123  void setSleepTime(int microseconds);
124 #if 0
125  int getSleepTime() const;
127 #endif
128  void instantiateDriver(std::string const &plugin,
130  std::string const &driver,
131  std::string const &params);
132 
134  void update();
135 
136  private:
139  bool m_loop();
140 
142  void m_update();
143 
146  template <typename Callable> void m_callControlled(Callable f);
147 
149  template <typename Callable> void m_callControlled(Callable f) const;
150 
153  void m_orderedDestruction();
154 
156  void m_queueTreeSend();
157 
159  void m_sendTree();
160 
162  static int VRPN_CALLBACK m_handleUpdatedRoute(void *userdata,
163  vrpn_HANDLERPARAM p);
164 
167  bool m_addRoute(std::string const &routingDirective);
168 
171  bool m_addAlias(std::string const &path, std::string const &source,
172  common::AliasPriority priority);
173 
176  bool m_addAliases(Json::Value const &aliases,
177  common::AliasPriority priority);
178 
180  void m_handleDeviceDescriptors();
181 
186  bool m_inServerThread() const;
187 
189  static int VRPN_CALLBACK m_exitIdle(void *userdata, vrpn_HANDLERPARAM);
191  static int VRPN_CALLBACK m_enterIdle(void *userdata, vrpn_HANDLERPARAM);
192 
195 
197  shared_ptr<pluginhost::RegistrationContext> m_ctx;
198 
200  std::vector<MainloopMethod> m_mainloopMethods;
201 
203  common::BaseDevicePtr m_systemDevice;
204 
206  common::SystemComponent *m_systemComponent = nullptr;
207 
209  common::CommonComponent *m_commonComponent = nullptr;
210 
213  bool m_triggeredDetect = false;
214 
216  common::PathTree m_tree;
217  util::Flag m_treeDirty;
218 
220  mutable boost::mutex m_mainThreadMutex;
221 
224  mutable boost::mutex m_runControl;
227  boost::thread m_thread;
229  bool m_running = false;
230  bool m_everStarted = false;
232 
235  mutable boost::thread::id m_mainThreadId;
236 
239  int m_sleepTime = 0;
240 
245  static const int IDLE_SLEEP_TIME = 1000;
246 
249  int m_currentSleepTime = IDLE_SLEEP_TIME;
250 
252  std::string m_host;
253 
255  int m_port;
256 
258  util::log::LoggerPtr m_log;
259 
261  unique_ptr<common::LowLatency> m_lowLatency;
262  };
263 
266  class TemporaryThreadIDChanger : boost::noncopyable {
267  public:
268  TemporaryThreadIDChanger(boost::thread::id &id)
269  : m_id(id), m_origID(id) {
270  m_id = boost::this_thread::get_id();
271  }
272  ~TemporaryThreadIDChanger() { m_id = m_origID; }
273 
274  private:
275  boost::thread::id &m_id;
276  boost::thread::id m_origID;
277  };
278 
279  inline bool ServerImpl::m_inServerThread() const {
280  boost::unique_lock<boost::mutex> lock(m_runControl);
281  return !m_running || (boost::this_thread::get_id() == m_mainThreadId);
282  }
283 
284  template <typename Callable>
285  inline void ServerImpl::m_callControlled(Callable f) {
286  boost::unique_lock<boost::mutex> lock(m_runControl);
287  if (m_running && boost::this_thread::get_id() != m_thread.get_id()) {
288  boost::unique_lock<boost::mutex> innerLock(m_mainThreadMutex);
289  TemporaryThreadIDChanger changer(m_mainThreadId);
290  f();
291  } else {
292  f();
293  }
294  }
295 
296  template <typename Callable>
297  inline void ServerImpl::m_callControlled(Callable f) const {
298  boost::unique_lock<boost::mutex> lock(m_runControl);
299  if (m_running && boost::this_thread::get_id() != m_thread.get_id()) {
300  boost::unique_lock<boost::mutex> innerLock(m_mainThreadMutex);
301  TemporaryThreadIDChanger changer(m_mainThreadId);
302  f();
303  } else {
304  f();
305  }
306  }
307 
308 } // namespace server
309 } // namespace osvr
310 
311 #endif // INCLUDED_ServerImpl_h_GUID_BA15589C_D1AD_4BBE_4F93_8AC87043A982
Header forward declaring MessageType and specifying a smart pointer.
Class to temporarily (in RAII style) change a thread ID variable to the current thread, then back again when we leave scope.
Definition: ServerImpl.h:266
void stop()
Signal the server to stop, and block until it does so.
Definition: ServerImpl.cpp:160
A tree representation, with path/url syntax, of the known OSVR system.
Definition: PathTree.h:43
The main namespace for all C++ elements of the framework, internal and external.
Definition: namespace_osvr.dox:3
bool addString(std::string const &path, std::string const &value)
Add a string entry to the tree.
Definition: ServerImpl.cpp:301
Header for an RAII object defining platform-specific actions to take to enter/exit a "low-latency" sy...
void setSleepTime(int microseconds)
Sets the amount of time (in microseconds) that the server loop will sleep each loop when a client is ...
Definition: ServerImpl.cpp:371
void registerMainloopMethod(MainloopMethod f)
Register a method to run during every time through the main loop.
Definition: ServerImpl.cpp:199
bool addAlias(std::string const &path, std::string const &source, common::AliasPriority priority)
Add an alias entry to the tree.
Definition: ServerImpl.cpp:255
std::function< void()> MainloopMethod
A function that can be registered by the server app to run in each mainloop iteration.
Definition: Server.h:52
void update()
The method to just do the update stuff, not in a thread.
Definition: ServerImpl.cpp:205
shared_ptr< Connection > ConnectionPtr
How one must hold a Connection.
Definition: ConnectionPtr.h:40
Header to bring unique_ptr into the osvr namespace.
BaseDevice component, for the VRPN built-in common messages.
Definition: CommonComponent.h:82
Header for basic internal log reference.
Header to bring shared_ptr into the osvr namespace.
void addExternalDevice(std::string const &path, std::string const &deviceName, std::string const &server, std::string const &descriptor)
Add an external device entry manually to the tree.
Definition: ServerImpl.cpp:272
void loadAutoPlugins()
Load all auto-loadable plugins.
Definition: ServerImpl.cpp:180
Header declaring osvr::server::Server.
void instantiateDriver(std::string const &plugin, std::string const &driver, std::string const &params)
Instantiate the named driver with parameters.
Definition: ServerImpl.cpp:187
ServerImpl(connection::ConnectionPtr const &conn, boost::optional< std::string > const &host, boost::optional< int > const &port)
Constructor.
Definition: ServerImpl.cpp:69
Private implementation class for Server.
Definition: ServerImpl.h:60
Header.
Header.
void signalStop()
Signal the server to stop (if it is running) but return immediately.
Definition: ServerImpl.cpp:171
void startAndAwaitShutdown()
Launch a thread running the server, and block until the server shuts down.
Definition: ServerImpl.cpp:153
BaseDevice component, to be used only with the "OSVR" special device.
Definition: SystemComponent.h:76
Definition: RunLoopManagerBoost.h:44
~ServerImpl()
Destructor (stops the thread first)
Definition: ServerImpl.cpp:123
bool addAliases(Json::Value const &aliases, common::AliasPriority priority)
Add alias entries to the tree from JSON.
Definition: ServerImpl.cpp:265
bool addRoute(std::string const &routingDirective)
Register a JSON string as a routing directive.
Definition: ServerImpl.cpp:249
void awaitShutdown()
Block until the server shuts down.
Definition: ServerImpl.cpp:158
A class that lightly wraps a bool, in order to provide easier maintenance of a "dirty" flag...
Definition: Flag.h:43
void setHardwareDetectOnConnection()
Adds the behavior that hardware detection should take place on client connection. ...
Definition: ServerImpl.cpp:182
Header forward-declaring RegistrationContext.
Header forward-declaring Connection and specifying the smart pointer to hold a Connection in...
void triggerHardwareDetect()
Run all hardware detect callbacks.
Definition: ServerImpl.cpp:195
void start()
Launch a thread running the server.
Definition: ServerImpl.cpp:129
void loadPlugin(std::string const &pluginName)
Load named plugin.
Definition: ServerImpl.cpp:176