GNU Radio 3.7.1 C++ API
|
00001 /* -*- c++ -*- */ 00002 /* 00003 * Copyright 2012 Free Software Foundation, Inc. 00004 * 00005 * This file is part of GNU Radio 00006 * 00007 * GNU Radio is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 3, or (at your option) 00010 * any later version. 00011 * 00012 * GNU Radio is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with GNU Radio; see the file COPYING. If not, write to 00019 * the Free Software Foundation, Inc., 51 Franklin Street, 00020 * Boston, MA 02110-1301, USA. 00021 */ 00022 00023 #ifndef ICE_APPLICATION_BASE_H 00024 #define ICE_APPLICATION_BASE_H 00025 00026 #ifdef HAVE_WINDOWS_H 00027 #include <winsock2.h> 00028 #include <sys/time.h> 00029 #endif 00030 00031 #include <gnuradio/api.h> 00032 #include <gnuradio/prefs.h> 00033 #include <Ice/Ice.h> 00034 #include <boost/thread.hpp> 00035 #include <boost/thread/mutex.hpp> 00036 #include <stdio.h> 00037 #include <iostream> 00038 #include <set> 00039 #include <string> 00040 #include <stdio.h> 00041 00042 namespace { 00043 static const unsigned int ICEAPPLICATION_ACTIVATION_TIMEOUT_MS(600); 00044 }; 00045 00046 class GR_RUNTIME_API ice_application_common : public Ice::Application 00047 { 00048 public: 00049 template<typename TserverBase, typename TserverClass> friend class ice_application_base; 00050 static boost::shared_ptr<ice_application_common> Instance(); 00051 ~ice_application_common() {;} 00052 static int d_reacquire_attributes; 00053 00054 protected: 00055 static bool d_main_called; 00056 static bool d_have_ice_config; 00057 static std::string d_endpointStr; 00058 static boost::shared_ptr<boost::thread> d_thread; 00059 ice_application_common() {;} 00060 int run(int, char*[]); 00061 }; 00062 00063 template<typename TserverBase, typename TserverClass> 00064 class ice_application_base 00065 { 00066 public: 00067 boost::shared_ptr<ice_application_common> d_application; 00068 ice_application_base(TserverClass* _this); 00069 ~ice_application_base() {;} 00070 00071 static TserverBase* i(); 00072 static const std::vector<std::string> endpoints(); 00073 00074 protected: 00075 bool have_ice_config() { return d_application->d_have_ice_config; } 00076 void set_endpoint(const std::string& endpoint) { d_application->d_endpointStr = endpoint;} 00077 00078 //this one is the key... overwrite in templated/inherited variants 00079 virtual TserverBase* i_impl() = 0; 00080 00081 //tools for the i_impl... 00082 //tell it when it has to resync with the communicator 00083 virtual bool reacquire_sync(); 00084 virtual void sync_reacquire(); 00085 00086 static TserverClass* d_this; 00087 00088 int d_reacquire; 00089 //static int d_reacquire_attributes; 00090 00091 private: 00092 void starticeexample(); 00093 00094 bool application_started(); 00095 00096 int run(int, char*[]); 00097 00098 static void kickoff(); 00099 }; 00100 00101 template<typename TserverBase, typename TserverClass> 00102 TserverClass* ice_application_base<TserverBase, TserverClass>::d_this(0); 00103 00104 //template<typename TserverBase, typename TserverClass> 00105 //int ice_application_base<TserverBase, TserverClass>::d_reacquire_attributes(0); 00106 00107 template<typename TserverBase, typename TserverClass> 00108 ice_application_base<TserverBase, TserverClass>::ice_application_base(TserverClass* _this) 00109 : d_reacquire(0) 00110 { 00111 //d_reacquire_attributes = 0; 00112 d_this = _this; 00113 d_application = ice_application_common::Instance(); 00114 } 00115 00116 template<typename TserverBase, typename TserverClass> 00117 void ice_application_base<TserverBase, TserverClass>::starticeexample() 00118 { 00119 char* argv[2]; 00120 argv[0] = (char*)""; 00121 00122 std::string conffile = gr::prefs::singleton()->get_string("ControlPort", "config", ""); 00123 00124 if(conffile.size() > 0) { 00125 std::stringstream iceconf; 00126 ice_application_common::d_have_ice_config = true; 00127 ice_application_common::d_main_called = true; 00128 iceconf << conffile; 00129 d_application->main(0, argv, iceconf.str().c_str()); 00130 } 00131 else { 00132 ice_application_common::d_have_ice_config = false; 00133 ice_application_common::d_main_called = true; 00134 d_application->main(0, argv); 00135 } 00136 } 00137 00138 template<typename TserverBase, typename TserverClass> 00139 void ice_application_base<TserverBase, TserverClass>::kickoff() 00140 { 00141 static bool run_once = false; 00142 00143 //if(!d_this->application_started()) { 00144 if(!run_once) { 00145 ++d_this->d_application->d_reacquire_attributes; 00146 00147 ice_application_common::d_thread = boost::shared_ptr<boost::thread> 00148 (new boost::thread(boost::bind(&ice_application_base::starticeexample, d_this))); 00149 00150 ::timespec timer_ts, rem_ts; 00151 timer_ts.tv_sec = 0; timer_ts.tv_nsec = ICEAPPLICATION_ACTIVATION_TIMEOUT_MS*1000; 00152 00153 int iter = 0; 00154 while(!d_this->application_started()) { 00155 #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) 00156 ::Sleep(timer_ts.tv_nsec / 1000000); 00157 #else 00158 ::nanosleep(&timer_ts, &rem_ts); 00159 #endif 00160 if(!d_this->application_started()) 00161 std::cout << "@"; 00162 if(iter++ > 100) { 00163 std::cout << "ice_application_base::kickoff(), timeout waiting to get communicator() d_application->main() might have failed?!" << std::endl;; 00164 break; 00165 } 00166 } 00167 00168 run_once = true; 00169 } 00170 00171 return; 00172 } 00173 00174 00175 template<typename TserverBase, typename TserverClass> 00176 bool ice_application_base<TserverBase, TserverClass>::reacquire_sync() 00177 { 00178 return (d_this->d_reacquire != d_application->d_reacquire_attributes); 00179 } 00180 00181 template<typename TserverBase, typename TserverClass> 00182 void ice_application_base<TserverBase, TserverClass>::sync_reacquire() 00183 { 00184 d_this->d_reacquire = d_application->d_reacquire_attributes; 00185 } 00186 00187 00188 template<typename TserverBase, typename TserverClass> 00189 const std::vector<std::string> ice_application_base<TserverBase, TserverClass>::endpoints() 00190 { 00191 std::vector<std::string> ep; ep.push_back(d_this->d_application->d_endpointStr); return ep; 00192 } 00193 00194 template<typename TserverBase, typename TserverClass> 00195 TserverBase* ice_application_base<TserverBase, TserverClass>::i() 00196 { 00197 //printf("indacall\n"); 00198 00199 assert(d_this != 0); 00200 if(!d_this->application_started()) { 00201 //printf("anotherkickoff\n"); 00202 kickoff(); 00203 } 00204 //printf("donekickedoff\n"); 00205 00206 /*else if(!d_proxy) { 00207 d_proxy = d_this->i_impl(); 00208 assert(d_proxy != 0); 00209 }*/ 00210 00211 return d_this->i_impl(); 00212 } 00213 00214 /*template<typename TserverBase, typename TserverClass> 00215 int ice_application_base<TserverBase, TserverClass>::run(int argc, char* argv[]) { 00216 int implreturn(run_impl(argc, argv)); 00217 ice_application_base<TserverBase, TserverClass>::communicator()->waitForShutdown(); 00218 return implreturn; 00219 }*/ 00220 00221 template<typename TserverBase, typename TImplClass> 00222 bool ice_application_base<TserverBase, TImplClass>::application_started() 00223 { 00224 return ice_application_base<TserverBase, TImplClass>::d_this->d_application->communicator(); 00225 } 00226 00227 /*template<typename TserverBase, typename TImplClass> 00228 int ice_application_base<TserverBase, TImplClass>::run_impl(int argc, char* argv[]) { return EXIT_SUCCESS; } 00229 */ 00230 00231 #endif