summaryrefslogtreecommitdiff
path: root/examples/Timer_Queue/Driver.cpp
blob: fdb567143a5962f492c8c4228992e02bd84a5a27 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// $Id$

// ============================================================================
// = LIBRARY
//    examples
//
// = FILENAME
//    Driver.cpp
//
// = DESCRIPTION
//    This code builds an abstraction to factor out common code for
//    the different implementations of the Timer_Queue.
//
// = AUTHOR
//    Douglas Schmidt      <schmidt@cs.wustl.edu> &&
//    Sergio Flores-Gaitan <sergio@cs.wustl.edu>
//
// ============================================================================

#if !defined (_DRIVER_CPP_)
#define _DRIVER_CPP_

#include "ace/Auto_Ptr.h"
#include "Driver.h"

ACE_RCSID(Timer_Queue, Driver, "$Id$")

// constructor

template <class RECEIVER, class ACTION>
Command<RECEIVER, ACTION>::Command (RECEIVER &recvr,
                                    ACTION action)
  : receiver_ (recvr),
    action_ (action)
{
}

// invokes an operation.

template <class RECEIVER, class ACTION> int
Command<RECEIVER, ACTION>::execute (void *arg)
{
  return (receiver_.*action_) (arg);
}

// gets the next request from the user input.

template <class TQ, class RECEIVER, class ACTION>
Timer_Queue_Test_Driver<TQ, RECEIVER, ACTION>::~Timer_Queue_Test_Driver (void)
{
}

template <class TQ, class RECEIVER, class ACTION> int
Timer_Queue_Test_Driver<TQ, RECEIVER, ACTION>::get_next_request (void)
{
  char buf[BUFSIZ];

  this->display_menu ();

  ACE_OS::printf ("please enter your choice: ");
  ACE_OS::fflush (stdout);

  // reads input from the user
  if (this->read_input (buf, sizeof buf) <= 0)
    return -1;

  // Parse and run the command.
  return this->parse_commands (buf);
}

// Runs the test.

template <class TQ, class RECEIVER, class ACTION> int
Timer_Queue_Test_Driver<TQ, RECEIVER, ACTION>::run_test (void)
{
  this->init ();

  for (;;)
    if (this->get_next_request () == -1)
      return -1;

  ACE_NOTREACHED (return 0);
}

// Reads input from the user from ACE_STDIN into the buffer specified.

template <class TQ, class RECEIVER, class ACTION> ssize_t
Timer_Queue_Test_Driver<TQ, RECEIVER, ACTION>::read_input (char *buf, size_t bufsiz)
{
  ACE_OS::memset (buf, 0, bufsiz);

  // Wait for user to type commands.  This call is automatically
  // restarted when SIGINT or SIGALRM signals occur.
  return ACE_OS::read (ACE_STDIN, buf, bufsiz);
}

// Parse the input and executes the corresponding operation

template <class TQ, class RECEIVER, class ACTION> int
Timer_Queue_Test_Driver<TQ, RECEIVER, ACTION>::parse_commands (const char *buf)
{
  int option;

  if (::sscanf (buf, "%d", &option) <= 0)
    // If there was an error reading the option simply try on the next line.
    return 0;

  switch (option)
    {
    case 1: // Schedule a new timer.
      {
        u_long useconds;
        // We just reread the option, this simplies parsing (since
        // sscanf can do it for us.)
        if (::sscanf (buf, "%d %lu", &option, &useconds) < 2)
          return 0;

        if (schedule_cmd_->execute ((void *) &useconds) == -1)
          ACE_ERROR_RETURN ((LM_ERROR, "%t %p\n", "new timer failed"), -1);
      }
      break; // Cancel an existing timer.
      /* NOTREACHED */
    case 2:
      {
        u_long id;
        // We just reread the option, this simplies parsing (since
        // sscanf can do it for us.)
        if (::sscanf (buf, "%d %lu", &option, &id) < 2)
          return 0;

        if (cancel_cmd_->execute ((void *) &id) == -1)
          ACE_DEBUG ((LM_DEBUG, "Timer #%d is not valid\n", id));

      }
      break;
      /* NOTREACHED */

    case 3: // Dump the existing timers.
      return list_cmd_->execute (NULL);
      /* NOTREACHED */

    case 4: // Exit the program.
      return shutdown_cmd_->execute (NULL);
      /* NOTREACHED */

    default:
      // Display an error message.
      ACE_ERROR_RETURN ((LM_ERROR, "invalid input %s\n", buf), 0);
      ACE_NOTREACHED (break);
      /* NOTREACHED */
    }
  return 0;
}

#endif /* _DRIVER_CPP_ */