00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "config.h"
00022
00023 #undef DEBUG
00024
00025 #include <errno.h>
00026
00027 #if TIME_WITH_SYS_TIME
00028 # include <sys/time.h>
00029 # include <time.h>
00030 #else
00031 # if HAVE_SYS_TIME_H
00032 # include <sys/time.h>
00033 # else
00034 # include <time.h>
00035 # endif
00036 #endif
00037
00038 #include <time_util.h>
00039
00040 #include <iostream>
00041
00042 #include "RTServerC.h"
00043
00044 using namespace std;
00045
00046 #if !defined(timespecclear)
00047
00048
00049
00050
00051
00052 #define timespecclear(tvp) ((tvp)->tv_sec = (tvp)->tv_nsec = 0)
00053
00054
00055
00056
00057
00058
00059 #define timespecisset(tvp) ((tvp)->tv_sec || (tvp)->tv_nsec)
00060
00061
00062
00063
00064
00065
00066
00067
00068 #define timespeccmp(tvp, uvp, cmp) \
00069 (((tvp)->tv_sec == (uvp)->tv_sec) ? \
00070 ((tvp)->tv_nsec cmp (uvp)->tv_nsec) : \
00071 ((tvp)->tv_sec cmp (uvp)->tv_sec))
00072
00073
00074
00075
00076
00077
00078
00079 #define timespecadd(vvp, uvp) \
00080 do { \
00081 (vvp)->tv_sec += (uvp)->tv_sec; \
00082 (vvp)->tv_nsec += (uvp)->tv_nsec; \
00083 if ((vvp)->tv_nsec >= 1000000000) { \
00084 (vvp)->tv_sec++; \
00085 (vvp)->tv_nsec -= 1000000000; \
00086 } \
00087 } while (0)
00088
00089
00090
00091
00092
00093
00094
00095 #define timespecsub(vvp, uvp) \
00096 do { \
00097 (vvp)->tv_sec -= (uvp)->tv_sec; \
00098 (vvp)->tv_nsec -= (uvp)->tv_nsec; \
00099 if ((vvp)->tv_nsec < 0) { \
00100 (vvp)->tv_sec--; \
00101 (vvp)->tv_nsec += 1000000000; \
00102 } \
00103 } while (0)
00104 #endif
00105
00106
00107
00108
00109 static CORBA::ORB_var orb;
00110
00111
00112
00113
00114
00115
00116 static void sigalrm_handler(int sig)
00117 {
00118 orb->shutdown();
00119
00120 exit(0);
00121 }
00122
00123 int main(int argc, char *argv[])
00124 {
00125 int retval = EXIT_FAILURE;
00126
00127 try
00128 {
00129 const char *server_ior = "file://rtserver.ior";
00130 CORBA::ULong period = 1000000;
00131 unsigned long run_time = 0;
00132 struct timespec interval;
00133 int ch, g2g = 1;
00134
00135
00136 orb = CORBA::ORB_init(argc, argv);
00137
00138
00139 while( ((ch = getopt(argc, argv, "hVf:s:P:")) != -1) && g2g )
00140 {
00141 switch( ch )
00142 {
00143 case 'f':
00144 {
00145 unsigned long long run_time_ull;
00146
00147 if( string_to_microsec(&run_time_ull, optarg) )
00148 {
00149 run_time = run_time_ull;
00150 }
00151 else
00152 {
00153 cerr << "Error: Run for value not a time: "
00154 << period
00155 << endl;
00156 throw CORBA::BAD_PARAM();
00157 }
00158 }
00159 break;
00160 case 's':
00161 if( strlen(optarg) == 0 )
00162 {
00163 cerr << "Error: Server IOR is empty" << endl;
00164 throw CORBA::BAD_PARAM();
00165 }
00166 server_ior = optarg;
00167 break;
00168 case 'P':
00169 {
00170 unsigned long long period_ull;
00171
00172 if( string_to_microsec(&period_ull, optarg) )
00173 {
00174 period = period_ull;
00175 }
00176 else
00177 {
00178 cerr << "Error: Period value is not a number: "
00179 << optarg
00180 << endl;
00181 throw CORBA::BAD_PARAM();
00182 }
00183 }
00184 break;
00185 case 'V':
00186 cout << PACKAGE_VERSION << endl;
00187 exit(0);
00188 break;
00189 case 'h':
00190 case '?':
00191 default:
00192 g2g = 0;
00193 break;
00194 }
00195 }
00196
00197
00198 if( g2g && (optind != argc) )
00199 {
00200 cerr << "Error: Extra arguments" << endl;
00201 throw CORBA::BAD_PARAM();
00202 }
00203
00204
00205 if( g2g )
00206 {
00207 interval.tv_sec = period / 1000000;
00208 interval.tv_nsec = (period % 1000000) * 1000;
00209
00210 if( run_time > 0 )
00211 {
00212 struct itimerval itv;
00213
00214 signal(SIGALRM, sigalrm_handler);
00215 itv.it_interval.tv_sec = 0;
00216 itv.it_interval.tv_usec = 0;
00217 itv.it_value.tv_sec = run_time / 1000000;
00218 itv.it_value.tv_usec = run_time % 1000000;
00219 if( setitimer(ITIMER_REAL, &itv, NULL) < 0 )
00220 {
00221 perror("setitimer");
00222 }
00223 }
00224
00225 CORBA::Object_var obj = orb->string_to_object(server_ior);
00226
00227 RTServer_var rts;
00228
00229 rts = RTServer::_narrow(obj.in());
00230 if( CORBA::is_nil(rts.in()) )
00231 {
00232 cerr << "Invalid RTServer IOR: " << endl;
00233 throw CORBA::BAD_PARAM();
00234 }
00235 else
00236 {
00237 struct timespec start, end, next;
00238 int eventCount = 1;
00239
00240 for( ;; )
00241 {
00242 clock_gettime(CLOCK_REALTIME, &start);
00243 next = start;
00244 timespecadd(&next, &interval);
00245 rts->Periodic();
00246 clock_gettime(CLOCK_REALTIME, &end);
00247 timespecsub(&next, &end);
00248
00249 timespecsub(&end, &interval);
00250 eventCount -= 1;
00251 while( timespeccmp(&start, &end, <) )
00252 {
00253 timespecsub(&end, &interval);
00254 eventCount += 1;
00255 }
00256 #if defined(DEBUG)
00257 cout << "Queued Events = " << eventCount << endl;
00258 #endif
00259 if( eventCount == 0 )
00260 {
00261 int rc;
00262
00263 while( (rc = nanosleep(&next, NULL)) == -1 )
00264 {
00265 perror("nanosleep");
00266
00267 ensure(errno == EINTR);
00268 }
00269 eventCount += 1;
00270 }
00271 }
00272
00273 retval = EXIT_SUCCESS;
00274 }
00275 }
00276 }
00277 catch(const CORBA::SystemException &e)
00278 {
00279 cerr << "Caught Exception: " << e << endl;
00280 }
00281 catch(...)
00282 {
00283 cerr << "Caught an unhandled exception" << endl;
00284 }
00285 return( retval );
00286 }