OSVR Framework (Internal Development Docs)  0.6-1962-g59773924
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
AsyncDeviceToken.cpp
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 #define OSVR_DEV_VERBOSE_DISABLE
26 
27 // Internal Includes
28 #include "AsyncDeviceToken.h"
30 #include <osvr/Util/Verbosity.h>
31 
32 // Library/third-party includes
33 // - none
34 
35 // Standard includes
36 // - none
37 
38 namespace osvr {
39 namespace connection {
40  using boost::unique_lock;
41  using boost::mutex;
42 
43  AsyncDeviceToken::AsyncDeviceToken(std::string const &name)
44  : OSVR_DeviceTokenObject(name) {}
45 
46  AsyncDeviceToken::~AsyncDeviceToken() {
47  OSVR_DEV_VERBOSE("AsyncDeviceToken\t"
48  "In ~AsyncDeviceToken");
49 
50  signalAndWaitForShutdown();
51  }
52 
53  void AsyncDeviceToken::signalShutdown() {
54  OSVR_DEV_VERBOSE("AsyncDeviceToken\t"
55  "In signalShutdown");
56  m_run.signalShutdown();
57  m_accessControl.mainThreadDenyPermanently();
58  }
59 
60  void AsyncDeviceToken::signalAndWaitForShutdown() {
61  OSVR_DEV_VERBOSE("AsyncDeviceToken\t"
62  "In signalAndWaitForShutdown");
63  signalShutdown();
64  if (m_callbackThread) {
65  m_run.signalAndWaitForShutdown();
66  m_callbackThread->join();
67  }
68  }
69 
70  namespace {
73  class WaitCallbackLoop {
74  public:
75  WaitCallbackLoop(::util::RunLoopManagerBase &run,
76  DeviceUpdateCallback const &cb)
77  : m_cb(cb), m_run(&run) {}
78  void operator()() {
79  OSVR_DEV_VERBOSE("WaitCallbackLoop starting");
80  ::util::LoopGuard guard(*m_run);
81  while (m_run->shouldContinue()) {
82  m_cb();
83  }
84  OSVR_DEV_VERBOSE("WaitCallbackLoop exiting");
85  }
86 
87  private:
88  DeviceUpdateCallback m_cb;
89  ::util::RunLoopManagerBase *m_run;
90  };
91  } // end of anonymous namespace
92 
93  void AsyncDeviceToken::m_setUpdateCallback(DeviceUpdateCallback const &cb) {
95  m_cb = cb;
96  }
97  void AsyncDeviceToken::m_ensureThreadStarted() {
98  if ((!m_callbackThread) && m_cb) {
99  m_callbackThread.reset(
100  new boost::thread(WaitCallbackLoop(m_run, m_cb)));
101  m_run.signalAndWaitForStart();
102  }
103  }
104 
105  void AsyncDeviceToken::m_sendData(util::time::TimeValue const &timestamp,
106  MessageType *type, const char *bytestream,
107  size_t len) {
108  OSVR_DEV_VERBOSE("AsyncDeviceToken::m_sendData\t"
109  "about to create RTS object");
110  RequestToSend rts(m_accessControl);
111 
112  bool clear = rts.request();
113  if (!clear) {
114  OSVR_DEV_VERBOSE("AsyncDeviceToken::m_sendData\t"
115  "RTS request responded with not clear to send.");
116  return;
117  }
118 
119  OSVR_DEV_VERBOSE("AsyncDeviceToken::m_sendData\t"
120  "Have CTS!");
121  m_getConnectionDevice()->sendData(timestamp, type, bytestream, len);
122  OSVR_DEV_VERBOSE("AsyncDeviceToken::m_sendData\t"
123  "done!");
124  }
125 
127  public:
128  AsyncSendGuard(AsyncAccessControl &control) : m_rts(control) {}
129  virtual bool lock() { return m_rts.request(); }
130  virtual ~AsyncSendGuard() {}
131 
132  private:
133  RequestToSend m_rts;
134  };
135 
136  util::GuardPtr AsyncDeviceToken::m_getSendGuard() {
137  util::GuardPtr ret(new AsyncSendGuard(m_accessControl));
138  return ret;
139  }
140 
141  void AsyncDeviceToken::m_connectionInteract() {
142  m_ensureThreadStarted();
143  OSVR_DEV_VERBOSE("AsyncDeviceToken::m_connectionInteract\t"
144  "Going to send a CTS if waiting");
145  bool handled = m_accessControl.mainThreadCTS();
146  if (handled) {
147  OSVR_DEV_VERBOSE("AsyncDeviceToken::m_connectionInteract\t"
148  "Handled an RTS!");
149  } else {
150  OSVR_DEV_VERBOSE("AsyncDeviceToken::m_connectionInteract\t"
151  "No waiting RTS!");
152  }
153  }
154 
155  void AsyncDeviceToken::m_stopThreads() { signalAndWaitForShutdown(); }
156 
157 } // namespace connection
158 } // namespace osvr
A DeviceToken connects the generic device interaction code in PluginKit's C API with the workings of ...
Definition: DeviceToken.h:56
An interface to a (deferred) guard class: after instantiation and lock returning true, some resource is locked and available until destruction.
bool mainThreadDenyPermanently()
Permanently deny present and future requests.
::OSVR_TimeValue TimeValue
C++-friendly typedef for the OSVR_TimeValue structure.
Definition: TimeValue.h:48
Internal class handling the synchronization of an asynchronous thread wishing to communicate that has...
bool request()
Issues a blocking request to send.
Internal, configured header file for verbosity macros.
virtual bool lock()
Attempts to lock/request the resource, and returns true if successful.