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