summaryrefslogtreecommitdiff
path: root/ACE/tests/Timer_Cancellation_Test.cpp
blob: b48f2a8849ce10ee78de1eaffc96c96cccff8390 (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
//=============================================================================
/**
 *  @file    Timer_Cancellation_Test.cpp
 *
 *  A test to ensure the timer cancellation works correctly.
 *
 *  @author Irfan Pyarali <irfan@oomworks.com>
 */
//=============================================================================

#include "test_config.h"
#include "ace/OS_NS_unistd.h"
#include "ace/Reactor.h"
#include "ace/TP_Reactor.h"
#include "ace/Task.h"

#if defined (ACE_HAS_THREADS)

class Deadlock : public ACE_Task_Base
{
public:

  int svc (void);

  int handle_timeout (const ACE_Time_Value &current_time,
                      const void *act);
};

int
Deadlock::svc (void)
{
  ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT ("Deadlock starts accessing Reactor and Timer Queue....\n")));

  this->reactor ()->schedule_timer (this,
                                    0,
                                    ACE_Time_Value (1));

  ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT ("Deadlock completes accessing Reactor and Timer Queue....\n")));

  return 0;
}

int
Deadlock::handle_timeout (const ACE_Time_Value &,
                          const void *)
{
  ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT ("Deadlock timeout\n")));

  return 0;
}

class Event_Handler : public ACE_Event_Handler
{
public:

  Event_Handler (Deadlock &deadlock);

  int handle_timeout (const ACE_Time_Value &current_time,
                      const void *act);

  int handle_close (ACE_HANDLE handle,
                    ACE_Reactor_Mask close_mask);

  Deadlock &deadlock_;
};

Event_Handler::Event_Handler (Deadlock &deadlock)
  : deadlock_ (deadlock)
{
}

int
Event_Handler::handle_timeout (const ACE_Time_Value &,
                               const void *)
{
  ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT ("Event_Handler timeout\n")));

  return -1;
}

int
Event_Handler::handle_close (ACE_HANDLE,
                             ACE_Reactor_Mask)
{
  ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT ("Event_Handler closed\n")));

  // Activate Deadlock.
  this->deadlock_.activate ();

  // Give Deadlock a chance to deadlock... ;-)
  ACE_OS::sleep (1);

  ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT ("Event Handler starts accessing Reactor....\n")));

  // This is a superfluous call to the Reactor to acquire its lock.
  this->reactor ()->max_notify_iterations ();

  ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT ("Event Handler completes accessing Reactor....\n")));

  return 0;
}

int
run_main (int, ACE_TCHAR *[])
{
  ACE_START_TEST (ACE_TEXT ("Timer_Cancellation_Test"));

  ACE_Reactor reactor (new ACE_TP_Reactor, true);

  Deadlock deadlock;
  deadlock.reactor (&reactor);

  Event_Handler handler (deadlock);

  // Scheduler a timer to kick things off.
  reactor.schedule_timer (&handler,
                          0,
                          ACE_Time_Value (1));

  // Run the event loop for a while.
  ACE_Time_Value timeout (4);
  reactor.run_reactor_event_loop (timeout);

  ACE_END_TEST;

  return 0;
}

#else /* ACE_HAS_THREADS */

int
run_main (int, ACE_TCHAR *[])
{
  ACE_START_TEST (ACE_TEXT ("Timer_Cancellation_Test"));

  ACE_ERROR ((LM_INFO,
              ACE_TEXT ("threads not supported on this platform\n")));

  ACE_END_TEST;

  return 0;
}

#endif /* ACE_HAS_THREADS */