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
|
/**
* @file Bug_2820_Regression_Test.cpp
*
* $Id: Bug_2820_Regression_Test.cpp 91673 2010-09-08 18:49:47Z johnnyw $
*
* 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"
/**
* @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);
/// Destructor
~Simple_Handler();
/// 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));
}
ACE_auto_ptr_reset(reactor, (ACE_Reactor*)0);
// Reset the reactor in the event handler, since it is gone.p
v->reactor(0);
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));
}
ACE_DEBUG ((LM_INFO,
ACE_TEXT("Ref count results. pre_notify refcount=%d,")
ACE_TEXT(" pos_notify=%d, pos_delete=%d\n"),
pre_notify_count, pos_notify_count, pos_release_count));
// Remove a reference for each time we explicitly increased it.
v->remove_reference();
v->remove_reference();
ACE_Event_Handler::Reference_Count pos_remove_count =
v->remove_reference();
ACE_DEBUG ((LM_INFO,
ACE_TEXT("Ref count results. pre_notify refcount=%d,")
ACE_TEXT(" pos_notify=%d, pos_delete=%d, pos_remove=%d\n"),
pre_notify_count, pos_notify_count, pos_release_count,
pos_remove_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);
}
Simple_Handler::
~Simple_Handler()
{
}
int Simple_Handler::
handle_exception(ACE_HANDLE)
{
return 0;
}
|