Main Page   Packages   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Search  

C:/temp/src/j2k/QNX4/Timer1.c

Go to the documentation of this file.
00001 /*
00002 
00003 Example of a server that receives periodic messages from a timer,
00004 and regular messages from a client.
00005 
00006 Illustrates using the timer functions with a proxy.
00007 
00008 */
00009 
00010 #include <j2k/Fred/Basic.hpp>
00011 #include <j2k/Fred/System.hpp>
00012 #include <j2k/Fred/Boolean.hpp>
00013 #include <j2k/Fred/StdTypes.hpp>
00014 
00015 #define  DEBUG_ON
00016 
00017 // Message send definitions
00018 
00019 #define MT_TIMER      1      // Message from timer
00020 #define MT_WAIT_DATA  2      // Message from client
00021 #define MT_SEND_DATA  3      // Message from client
00022 
00023 // Message reply definitions
00024 #define MT_OK         0      // Message to client
00025 #define MT_TIME_OUT   1      // Message to client
00026 
00027 // Message structure
00028 typedef struct {
00029   int messageType;           // Contains both messages to and from client
00030   int messageData;           // Optional data, depending upon message
00031 } MessageT;
00032 
00033 // Client table
00034 #define MAX_CLIENT    16     // Maximum number of simultaneous client
00035 
00036 struct {
00037   int in_use;                // Is this client entry in use ?
00038   int pid;                   // Process ID of client
00039   int timeout;               // Timeout left for client
00040 } clients [MAX_CLIENT];      // Client Table
00041 
00042 char* progname = "time1.c";
00043 
00044 // The server
00045 
00046 int main() {
00047   int senderPID;             // Process ID of the sender
00048   int proxyPID;              // Process ID of the proxy
00049   MessageT msg;              // The message itself
00050 
00051   // Set up the proxy and timer
00052   proxyPID = setupProxyAndTimer();
00053 
00054   // Receive messages
00055   for(;;) {
00056     senderPID = Receive( 0, &msg, sizeof( msg ) );
00057 
00058     // Determine who the message came from
00059     if ( senderPID == proxyPID ) {
00060       fromProxy();
00061     } else {
00062       fromMessage( senderPID, &msg );
00063     }
00064   }
00065 
00066   // Shouldn't get here
00067   return ( EXIT_SUCCESS );
00068 }
00069 
00070 /*
00071  setupProxyAndTimer
00072 
00073  This routine is responsible for setting up a proxy so it
00074  sends a message of type MT_TIMER.  It then sets up a periodic timer
00075  that fires once per second.
00076 */
00077 
00078 int setupProxyAndTimer() {
00079   pid_t    pid;              // Process ID for proxy
00080   timer_t  tid;              // Timer ID for timer
00081   struct sigevent    event;  // event to deliver
00082   struct itimerspec  timer;  // the timer data structure
00083   MessageT   proxy_message;  // message for proxy to deliver
00084 
00085   // Set up the canned proxy message
00086   proxy_message.messageType = MT_TIMER
00087   proxy_message.messageData = 0;
00088 
00089   pid = qnx_proxy_attach( 0, &proxy_message, sizeof( proxy_message), 10 );
00090   if (pid == -1) {
00091     fprintf( stderr,
00092              "%s: couldn't attach a proxy, errno %d \n",
00093              progname, errno );
00094 
00095     perror( NULL );
00096     exit( EXIT_FAILURE );
00097   }
00098 
00099   // Set up the kind of event that we want to deliver -- a proxy
00100   event.sigev_signo = -pid;
00101 
00102   // Create the timer, binding it to the event
00103   tid = timer_create( CLOCK_REALTIME, &event );
00104   if (tid == -1) {
00105     fprintf( stderr,
00106              "%s: couldn't create a timer, errno %d \n",
00107              progname, errno );
00108 
00109     perror( NULL );
00110     exit( EXIT_FAILURE );
00111   }
00112 
00113   // Start the timer ( 1 sec delay, 1 sec reload )
00114   timer.it_value.tv_sec  = 1;
00115   timer.it_value.tv_nsec = 0;
00116 
00117   timer.it_interval.tv_sec  = 1;
00118   timer.it_interval.tv_nsec = 0;
00119 
00120   timer_settime( tid, 0, &timer, NULL );
00121 
00122   // Return value from the function is the proxy PID
00123   return (pid);
00124 }
00125 
00126 /*
00127 
00128  fromProxy                      
00129 
00130  This rountine is responsible for handling the fact that a timeout
00131  has occurred. It runs through the list of clients to see which client
00132  has timed out, and replies to it with a timed out message.
00133 
00134 */
00135 
00136 void fromProxy() {
00137   MessageT  msg;
00138   int i;
00139 
00140 #ifdef  DEBUG_ON
00141    time_t now;
00142    time ( &now );
00143    printf( "Got a Proxy at %s", ctime( &now ) );
00144 #endif
00145 
00146   // Prepare a response message
00147   msg.messageType = MT_TIME_OUT
00148 
00149   // Walk down list of clients
00150   for( i = 0; i < MAX_CLIENT; i++ ) {
00151 
00152     // Is this entry in use ?
00153     if ( clients[i].in_use ) {
00154 
00155       // Is it about to time out ?
00156       if (--client[i].timeout == 0) {
00157         // Send a reply
00158         Reply( clients[i].pid, &msg, sizeof( msg ) );
00159 
00160         // Entry no longer used
00161         clients[i].in_use = 0;
00162       }
00163     }
00164   }
00165 }
00166 
00167 /*
00168 
00169  fromMessage
00170 
00171  This routine is called whenever a message arrives.
00172  We look at the type of message (either a 'wait for data' message,
00173  or a 'here's some data' message), and act accordingly.
00174 
00175  For simplify, we'll assume that there is never any data waiting.
00176  See the text for more discussion about this.
00177 
00178 */
00179 
00180 void fromMessage( int pid, MessageT*  msg ) {
00181   int i;
00182 
00183   // Determine the kind of message that it is
00184   switch( msg->messageType ) {
00185 
00186     // Client wants to wait for data
00187     case  MT_WAIT_DATA:
00188 
00189       // See if we can find a blank spot in the client table
00190       for( i = 0; i < MAX_CLIENT; i++ ) {
00191         if ( !clients[i].in_use ) {
00192 
00193           // Found one -- mark as in use, save pid, set timeout
00194           clients[i].in_use  = 1;
00195           clients[i].pid     = pid;
00196           clients[i].timeout = 5;
00197           return;
00198         }
00199       }
00200 
00201       fprintf( stderr,
00202          "%s: Table full, message from PID %d ignored, client blocked\n",
00203          pid );
00204 
00205       break;
00206 
00207       case  MT_SEND_DATA:
00208 
00209         // See if we can find another client
00210         // to reply to with this client's data.
00211         for( i = 0; i < MAX_CLIENT; i++ ) {
00212           if ( clients[i].in_use ) {
00213             // Found one -- reuse the incoming message as an outgoing message
00214             msg->message_type = MT_OK;
00215 
00216             // Reply to BOTH CLIENTS:
00217             Reply( clients[i].pid, msg, sizeof( *msg ) );
00218             Reply( pid, msg, sizeof( *msg ) );
00219 
00220             clients[i].in_use = 0;
00221             return;
00222           }
00223         }
00224 
00225       fprintf( stderr,
00226          "%s: Table empty, message from PID %d ignored, client blocked\n",
00227          pid );
00228 
00229       break;
00230   }
00231 }
00232 

Generated on Sun Oct 14 18:46:42 2001 for Standard J2K Library by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001