1 #include "ace/Priority_Reactor.h"
2 #include "ace/Malloc_T.h"
6 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
8 typedef ACE_Unbounded_Queue_Iterator
<ACE_Event_Tuple
> QUEUE_ITERATOR
;
11 typedef ACE_Cached_Allocator
<ACE_Node
<ACE_Event_Tuple
>, ACE_SYNCH_NULL_MUTEX
> TUPLE_ALLOCATOR
;
12 // Defines the memory allocator used, no need for locking because it
13 // is only used in one thread of control.
15 ACE_ALLOC_HOOK_DEFINE(ACE_Priority_Reactor
)
17 // Initialize ACE_Select_Reactor.
20 ACE_Event_Handler::HI_PRIORITY-ACE_Event_Handler::LO_PRIORITY+1
23 ACE_Priority_Reactor::init_bucket (void)
25 // Allocate enough space for all the handles.
26 // TODO: This can be wrong, maybe we should use other kind of
28 ACE_NEW (this->tuple_allocator_
,
29 TUPLE_ALLOCATOR (ACE_Select_Reactor::DEFAULT_SIZE
));
31 // The event handlers are assigned to a new As the Event
32 #if defined (ACE_HAS_ALLOC_HOOKS)
33 ACE_ALLOCATOR (this->bucket_
,
34 static_cast<QUEUE
**>(ACE_Allocator::instance()->malloc(sizeof(QUEUE
*) * (npriorities
))));
36 ACE_NEW (this->bucket_
,
37 QUEUE
*[npriorities
]);
38 #endif /* ACE_HAS_ALLOC_HOOKS */
40 // This loops "ensures" exception safety.
41 for (int i
= 0; i
< npriorities
; ++i
)
42 ACE_NEW (this->bucket_
[i
],
43 QUEUE (this->tuple_allocator_
));
46 ACE_Priority_Reactor::ACE_Priority_Reactor (ACE_Sig_Handler
*sh
,
48 : ACE_Select_Reactor(sh
, tq
),
52 ACE_TRACE ("ACE_Priority_Reactor::ACE_Priority_Reactor");
56 ACE_Priority_Reactor::ACE_Priority_Reactor (size_t size
,
60 : ACE_Select_Reactor (size
, restart
, sh
, tq
),
64 ACE_TRACE ("ACE_Priority_Reactor::ACE_Priority_Reactor");
68 ACE_Priority_Reactor::~ACE_Priority_Reactor (void)
70 ACE_TRACE ("ACE_Priority_Reactor::~ACE_Priority_Reactor");
72 for (int i
= 0; i
< npriorities
; ++i
)
73 delete this->bucket_
[i
];
75 #if defined (ACE_HAS_ALLOC_HOOKS)
76 ACE_Allocator::instance()->free(this->bucket_
);
78 delete[] this->bucket_
;
79 #endif /* ACE_HAS_ALLOC_HOOKS */
80 delete tuple_allocator_
;
84 ACE_Priority_Reactor::build_bucket (ACE_Handle_Set
&dispatch_mask
,
88 ACE_Handle_Set_Iterator
handle_iter (dispatch_mask
);
90 for (ACE_HANDLE handle
;
91 (handle
= handle_iter ()) != ACE_INVALID_HANDLE
;
94 ACE_Event_Handler
*event_handler
=
95 this->handler_rep_
.find (handle
);
96 if (event_handler
== 0)
99 ACE_Event_Tuple
et (event_handler
,
101 int prio
= et
.event_handler_
->priority ();
103 // If the priority is out of range assign the minimum priority.
104 if (prio
< ACE_Event_Handler::LO_PRIORITY
105 || prio
> ACE_Event_Handler::HI_PRIORITY
)
106 prio
= ACE_Event_Handler::LO_PRIORITY
;
108 if (bucket_
[prio
]->enqueue_tail (et
) == -1)
111 // Update the priority ranges....
112 if (min_priority
> prio
)
114 if (max_priority
< prio
)
122 ACE_Priority_Reactor::dispatch_io_set (int number_of_active_handles
,
123 int& number_dispatched
,
125 ACE_Handle_Set
& dispatch_mask
,
126 ACE_Handle_Set
& ready_mask
,
127 ACE_EH_PTMF callback
)
129 ACE_TRACE ("ACE_Priority_Reactor::dispatch_io_set");
131 if (number_of_active_handles
== 0)
134 // The range for which there exists any Event_Tuple is computed on
135 // the ordering loop, minimizing iterations on the dispatching loop.
137 ACE_Event_Handler::HI_PRIORITY
;
139 ACE_Event_Handler::LO_PRIORITY
;
141 if (this->build_bucket (dispatch_mask
,
146 for (int i
= max_priority
; i
>= min_priority
; --i
)
148 while (!bucket_
[i
]->is_empty ()
149 && number_dispatched
< number_of_active_handles
)
154 bucket_
[i
]->dequeue_head (et
);
156 this->notify_handle (et
.handle_
,
163 // clear the bit from that dispatch mask,
164 // so when we need to restart the iteration (rebuilding the iterator...)
165 // we will not dispatch the already dispatched handlers
166 this->clear_dispatch_mask (et
.handle_
,
169 if (this->state_changed_
)
170 this->state_changed_
= false; // so it will not rebuild it ...
173 // Even if we are aborting the loop due to this->state_changed
174 // or another error we still want to cleanup the buckets.
175 bucket_
[i
]->reset ();
182 ACE_Priority_Reactor::dump (void) const
184 #if defined (ACE_HAS_DUMP)
185 ACE_TRACE ("ACE_Priority_Reactor::dump");
187 ACELIB_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
189 ACE_Select_Reactor::dump ();
191 ACELIB_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
192 #endif /* ACE_HAS_DUMP */
195 ACE_END_VERSIONED_NAMESPACE_DECL