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
|
/**
* @file Bug_2820_Regression_Test.cpp
*
* $Id$
*
* Verify that the event handler reference counting works correctly
* when the reactor is destroyed.
*
* Pushing a notification through the reactor increments the reference
* count on the target event handler. Both dispatching and purging
* the notification decrement the reference count. However,
* destroying the reactor used to not decrement the reference count.
* This test reproduces the problem and serves as a regression for it.
*
* @author Carlos O'Ryan <coryan@atdesk.com>
*
*/
#include "test_config.h"
#include "ace/Auto_Ptr.h"
#include "ace/Reactor.h"
#include "ace/Select_Reactor.h"
ACE_RCSID(tests,
Bug_2820_Regression_Test, "$Id$")
/**
* @class Simple_Handler
*
* @brief A simple event handler for the test
*
*/
class Simple_Handler : public ACE_Event_Handler
{
public:
/// Constructor
Simple_Handler(ACE_Reactor * reactor);
/// Receive (and ignore) the notifications
virtual int handle_exception(ACE_HANDLE);
};
int
run_main (int, ACE_TCHAR *[])
{
ACE_START_TEST (ACE_TEXT ("Bug_2820_Regression_Test"));
int result = 0;
auto_ptr<ACE_Reactor> reactor(
new ACE_Reactor(new ACE_Select_Reactor, 1));
ACE_Event_Handler_var v(
new Simple_Handler(reactor.get()));
ACE_Event_Handler::Reference_Count pre_notify_count =
v->add_reference();
int const notify_count = 4;
for(int i = 0; i != notify_count; ++i)
{
reactor->notify(v.handler());
}
ACE_Event_Handler::Reference_Count pos_notify_count =
v->add_reference();
if(pos_notify_count != pre_notify_count + notify_count + 1)
{
result = -1;
ACE_ERROR((LM_ERROR,
ACE_TEXT("Reference count should increase by %d.")
ACE_TEXT(" Initial count=%d, final count = %d\n"),
notify_count, pre_notify_count, pos_notify_count));
}
reactor.reset();
ACE_Event_Handler::Reference_Count pos_release_count =
v->add_reference();
// Only our explicit calls to add_reference() should be reflected in
// the refence_count...
if (pos_release_count != pre_notify_count + 2)
{
result = -1;
ACE_ERROR((LM_ERROR,
ACE_TEXT("Reference count should have increased by 2.")
ACE_TEXT(" Initial count=%d, final count = %d\n"),
pre_notify_count, pos_release_count));
}
// Remove a reference for each time we explicitly increased it,
// minus one time because the _var will take care of that.
v->remove_reference();
v->remove_reference();
if (result == 0)
{
ACE_DEBUG ((LM_INFO,
ACE_TEXT("Test passed. pre_notify refcount=%d,")
ACE_TEXT(" pos_notify=%d, pos_delete=%d\n"),
pre_notify_count, pos_notify_count, pos_release_count));
}
ACE_END_TEST;
return result;
}
// ============================================
Simple_Handler::
Simple_Handler(
ACE_Reactor * r)
: ACE_Event_Handler(r)
{
reference_counting_policy().value(
ACE_Event_Handler::Reference_Counting_Policy::ENABLED);
}
int Simple_Handler::
handle_exception(ACE_HANDLE)
{
return 0;
}
|