GNU Radio Manual and C++ API Reference  3.7.13.4
The Free & Open Software Radio Ecosystem
thrift_application_base.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2015 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  *
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING. If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #ifndef THRIFT_APPLICATION_BASE_H
24 #define THRIFT_APPLICATION_BASE_H
25 
26 #include <gnuradio/api.h>
27 #include <gnuradio/logger.h>
28 #include <gnuradio/prefs.h>
29 #include <gnuradio/thread/thread.h>
30 #include <boost/date_time/posix_time/posix_time.hpp>
31 #include <boost/scoped_ptr.hpp>
32 
33 namespace {
34  // Time, in milliseconds, to wait between checks to the Thrift runtime to see if
35  // it has fully initialized.
36  static const unsigned int THRIFTAPPLICATION_ACTIVATION_TIMEOUT_MS(200);
37 };
38 
39 namespace apache { namespace thrift { namespace server { class TServer; } } }
40 
41 /*!
42  * \brief Class to be statically initialized by thrift_application_base. Used
43  * to store state for thrift_application_base's singleton functions.
44  */
45 
47 {
48 public:
50  d_application_initilized(false),
51  d_endpointStr(""),
52  d_start_thrift_thread() {;}
53 
54  // Used to ensure the Thrift runtime is initialized on the first call to ::i().
56  // Stores the generated endpoint string after the Thrift runtime has initialized.
57  std::string d_endpointStr;
58  // Thread to execute the Thrift runtime's blocking serve() function.
59  boost::shared_ptr<gr::thread::thread> d_start_thrift_thread;
60 };
61 
62 /*!
63  * \brief Base class for a Thrift application with a singleton with
64  * instance function thrift_application_base::i(). Lazy initialization
65  * is used to start the Thrift runtime, therefore the Thrift runtime
66  * is not started unless thrift_application_base::i() is called at
67  * least once. This typically means that at least one rpc variable
68  * must be registered by a block before the runtime will start.
69  *
70  * \param TserverBase Template parameter naming the type of the server
71  * base, which is typically rpcserverbase.
72  * \param TserverClass Template parameter naming the eventual type of
73  * the fully derived application.
74  * \param _app Reference to the fully derived application instance to
75  * be returned by thrift_application_base::i().
76  */
77 
78 template<typename TserverBase, typename TserverClass>
80 {
81 public:
82  thrift_application_base(TserverClass* _app);
83 
84  /*!
85  * Destructor for the application. Since shutdown and cleanup of the
86  * runtime is typically custom to a particular booter
87  * implementation, this must be implemented as a specialized function
88  * for a particular booter. Thus a template implementation is not
89  * provided here.
90  */
92 
93  /*!
94  * The application singleton instance function.
95  */
96  static TserverBase* i();
97 
98  /*!
99  * Returns the endpoint string of this application.
100  */
101  static const std::vector<std::string> endpoints();
102 
103 protected:
104  /*!
105  * Allows this application's booter to set the endpoint string after
106  * the Thrift runtime has initialized.
107  *
108  * \param[in] endpoint The endpoint string reported by this class.
109  */
110  void set_endpoint(const std::string& endpoint);
111 
112  virtual TserverBase* i_impl() = 0;
113 
114  /*!
115  * Reference to the fully derived application instance.
116  */
117  static TserverClass* d_application;
118 
119  /*!
120  * Reference to the Thrift runtime.
121  */
122  boost::scoped_ptr<apache::thrift::server::TServer> d_thriftserver;
123 
124  /*!
125  * Max number of attempts when checking the Thrift runtime for
126  * Initialization before giving up. Set in the Thrift config file
127  * (see \ref ctrlport_thrift_prefs).
128  */
129  static const unsigned int d_default_max_init_attempts;
130 
131  /*!
132  * Default port for the runtime to listen on, if a static port is
133  * not specified. Set in the Thrift config file (see \ref
134  * ctrlport_thrift_prefs).
135  */
136  static const unsigned int d_default_thrift_port;
137 
138  /*!
139  * Maximum number of threads to create when serving multiple rpc
140  * clients. Set in the Thrift config file (see \ref
141  * ctrlport_thrift_prefs).
142  */
143  static const unsigned int d_default_num_thrift_threads;
144 
145  /*!
146  * Default packet size for the IP payload of thrift packets. Set in
147  * the Thrift config file (see \ref ctrlport_thrift_prefs).
148  */
149  static const unsigned int d_default_thrift_buffer_size;
150 
151  /*!
152  * \ref page_logger instances.
153  */
154  gr::logger_ptr d_logger, d_debug_logger;
155 
156 private:
157 
158  // Function to be called in a separate thread to invoke the blocking
159  // ThriftServer::serve() function. Must be specialized for a particular
160  // booter implementation, therefore a template implementation is
161  // not provided here.
162  void start_thrift();
163 
164  // Non-blocking function that returns true when the Thrift
165  // runtime has finished initialization. Must be implemented
166  // as a specialized template function for a particular booter
167  // implementation, therefore template implementation is not
168  // provided here.
169  bool application_started();
170 
171  // Internal function to start the initialization of the runtime.
172  // Since this singleton uses lazy instantiation, this function
173  // will be called on the first call to the instance function ::i(),
174  // and since ::i() is static, this function must be static as well.
175  static void start_application();
176 
177  // Pointer to the structure containing statically allocated
178  // state information for the applicaiton_base singleton.
179  static boost::scoped_ptr<thrift_application_base_impl > p_impl;
180 
181  // Mutex to protect the endpoint string.
182  gr::thread::mutex d_lock;
183 
184  // Will be set to true by a the application_started() function,
185  // specialized for a particular booter implementation, once the
186  // thrift runtime has successfully initialized.
187  bool d_thirft_is_running;
188 };
189 
190 template<typename TserverBase, typename TserverClass>
192 
193 template<typename TserverBase, typename TserverClass>
195  : d_lock(),
196  d_thirft_is_running(false)
197 {
199  d_application = _app;
200 }
201 
202 template<typename TserverBase, typename TserverClass>
204 {
205  unsigned int max_init_attempts = \
206  static_cast<unsigned int>(gr::prefs::singleton()->get_long("thrift", "init_attempts",
208 
209  if(!p_impl->d_application_initilized) {
210  p_impl->d_start_thrift_thread.reset(
211  (new gr::thread::thread(boost::bind(&thrift_application_base::start_thrift, d_application))));
212 
213  bool app_started(false);
214  for(unsigned int attempts(0); (!app_started && attempts < max_init_attempts); ++attempts) {
215  boost::this_thread::sleep(boost::posix_time::milliseconds(THRIFTAPPLICATION_ACTIVATION_TIMEOUT_MS));
216  app_started = d_application->application_started();
217  }
218 
219  if(!app_started) {
220  GR_WARN("thrift_application_base", "thrift_application_base::start_application(), "
221  "timeout waiting to port number might have failed?");
222  }
223 
224  p_impl->d_application_initilized = true;
225  }
226 }
227 
228 template<typename TserverBase, typename TserverClass>
230 {
231  std::vector<std::string> ep;
232  ep.push_back(p_impl->d_endpointStr);
233  return ep;
234 }
235 
236 template<typename TserverBase, typename TserverClass>
238 {
239  gr::thread::scoped_lock guard(d_lock);
240  p_impl->d_endpointStr = endpoint;
241 }
242 
243 template<typename TserverBase, typename TserverClass>
245 {
246  if(!p_impl->d_application_initilized) {
247  start_application();
248  }
249  return d_application->i_impl();
250 }
251 
252 #endif
boost::unique_lock< boost::mutex > scoped_lock
Definition: thread.h:49
#define GR_WARN(name, msg)
Definition: logger.h:727
gr::logger_ptr d_logger
Definition: thrift_application_base.h:154
std::string d_endpointStr
Definition: thrift_application_base.h:57
static const unsigned int d_default_max_init_attempts
Definition: thrift_application_base.h:129
static const std::vector< std::string > endpoints()
Definition: thrift_application_base.h:229
static TserverClass * d_application
Definition: thrift_application_base.h:117
static const unsigned int d_default_num_thrift_threads
Definition: thrift_application_base.h:143
boost::thread thread
Definition: thread.h:47
void * logger_ptr
Definition: logger.h:696
static TserverBase * i()
Definition: thrift_application_base.h:244
virtual long get_long(const std::string &section, const std::string &option, long default_val)
If option exists and value can be converted to long, return it; else default_val. ...
boost::scoped_ptr< apache::thrift::server::TServer > d_thriftserver
Definition: thrift_application_base.h:122
Base class for a Thrift application with a singleton with instance function thrift_application_base::...
Definition: thrift_application_base.h:79
GR_RUNTIME_API bool configure_default_loggers(gr::logger_ptr &l, gr::logger_ptr &d, const std::string name)
Class to be statically initialized by thrift_application_base. Used to store state for thrift_applica...
Definition: thrift_application_base.h:46
thrift_application_base(TserverClass *_app)
Definition: thrift_application_base.h:194
Definition: thrift_application_base.h:39
static const unsigned int d_default_thrift_port
Definition: thrift_application_base.h:136
bool d_application_initilized
Definition: thrift_application_base.h:55
boost::mutex mutex
Definition: thread.h:48
static prefs * singleton()
thrift_application_base_impl()
Definition: thrift_application_base.h:49
boost::shared_ptr< gr::thread::thread > d_start_thrift_thread
Definition: thrift_application_base.h:59
static const unsigned int d_default_thrift_buffer_size
Definition: thrift_application_base.h:149
gr::logger_ptr d_debug_logger
Definition: thrift_application_base.h:154
void set_endpoint(const std::string &endpoint)
Definition: thrift_application_base.h:237