From 7a54cdf86705c08a738a11f5fa4982adc67be6f3 Mon Sep 17 00:00:00 2001 From: Steve Huston Date: Tue, 15 Nov 2005 14:32:27 +0000 Subject: ChangeLogTag:Tue Nov 15 09:31:29 2005 Steve Huston --- ChangeLog | 11 ++++++++++ ace/Dev_Poll_Reactor.cpp | 48 ++++++++++++++++++----------------------- ace/Dev_Poll_Reactor.h | 5 +++-- tests/Dev_Poll_Reactor_Test.cpp | 7 +++--- 4 files changed, 38 insertions(+), 33 deletions(-) diff --git a/ChangeLog b/ChangeLog index fa6b9624ca5..bc108980e14 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +Tue Nov 15 09:31:29 2005 Steve Huston + + * ace/Dev_Poll_Reactor.{h cpp}: Add an optional decr_refcnt parameter + to ACE_Dev_Poll_Rector_Repository::unbind () to control whether or + not the unbound event handler's refcount is to be decremented. + When registering a handler, remember to increment its refcount if + needed; conversely, decrement it when all events are removed. + Be sure to initialize epoll_event structs. + + * tests/Dev_Poll_Reactor_Test.cpp (handle_input): Fix buffer overrun. + Tue Nov 15 13:57:12 UTC 2005 Johnny Willemsen * ace/OS_NS_stdio.{cpp.inl}: diff --git a/ace/Dev_Poll_Reactor.cpp b/ace/Dev_Poll_Reactor.cpp index 20d57ea0d62..170f4063b0c 100644 --- a/ace/Dev_Poll_Reactor.cpp +++ b/ace/Dev_Poll_Reactor.cpp @@ -700,18 +700,22 @@ ACE_Dev_Poll_Reactor_Handler_Repository::bind ( this->handlers_[handle].event_handler = event_handler; this->handlers_[handle].mask = mask; + event_handler->add_reference (); return 0; } int -ACE_Dev_Poll_Reactor_Handler_Repository::unbind (ACE_HANDLE handle) +ACE_Dev_Poll_Reactor_Handler_Repository::unbind (ACE_HANDLE handle, + bool decr_refcnt) { ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::unbind"); if (this->find (handle) == 0) return -1; + if (decr_refcnt) + this->handlers_[handle].event_handler->remove_reference (); this->handlers_[handle].event_handler = 0; this->handlers_[handle].mask = ACE_Event_Handler::NULL_MASK; this->handlers_[handle].suspended = 0; @@ -1542,7 +1546,7 @@ ACE_Dev_Poll_Reactor::register_handler_i (ACE_HANDLE handle, #if defined (ACE_HAS_EVENT_POLL) struct epoll_event epev; - + ACE_OS::memset (&epev, 0, sizeof (epev)); static const int op = EPOLL_CTL_ADD; epev.events = this->reactor_mask_to_poll_event (mask); @@ -1564,11 +1568,7 @@ ACE_Dev_Poll_Reactor::register_handler_i (ACE_HANDLE handle, // current one. ACE_DEBUG ((LM_DEBUG, "Adding mask 0x%x for handle %d\n", mask, handle)); if (this->mask_ops_i (handle, mask, ACE_Reactor::ADD_MASK) == -1) - { - ACE_ERROR ((LM_ERROR, "%p\n", "mask_ops_i")); - (void) this->handler_rep_.unbind (handle); - return -1; - } + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "mask_ops_i"), -1); } #ifndef ACE_HAS_EVENT_POLL @@ -1583,7 +1583,6 @@ ACE_Dev_Poll_Reactor::register_handler_i (ACE_HANDLE handle, if (ACE_OS::write (this->poll_fd_, &pfd, sizeof (pfd)) != sizeof (pfd)) { (void) this->handler_rep_.unbind (handle); - return -1; } #endif /*ACE_HAS_EVENT_POLL*/ @@ -1706,27 +1705,22 @@ ACE_Dev_Poll_Reactor::remove_handler_i (ACE_HANDLE handle, ACE_Event_Handler *eh = this->handler_rep_.find (handle); - if (eh == 0 - || this->mask_ops_i (handle, mask, ACE_Reactor::CLR_MASK) == -1) + if (eh == 0 || + this->mask_ops_i (handle, mask, ACE_Reactor::CLR_MASK) == -1) return -1; - // If there are no longer any outstanding events on the given handle - // then remove it from the handler repository. - if (this->handler_rep_.mask (handle) == ACE_Event_Handler::NULL_MASK - && this->handler_rep_.unbind (handle) != 0) - return -1; + // Check for ref counting now - handle_close() may delete eh. + int requires_reference_counting = + eh->reference_counting_policy ().value () == + ACE_Event_Handler::Reference_Counting_Policy::ENABLED; if (ACE_BIT_DISABLED (mask, ACE_Event_Handler::DONT_CALL)) - { - // Release the lock during the "close" upcall. - ACE_Reverse_Lock reverse_lock (this->token_); - ACE_GUARD_RETURN (ACE_Reverse_Lock, - reverse_guard, - reverse_lock, - -1); + (void) eh->handle_close (handle, mask); - (void) eh->handle_close (handle, mask); - } + // If there are no longer any outstanding events on the given handle + // then remove it from the handler repository. + if (this->handler_rep_.mask (handle) == ACE_Event_Handler::NULL_MASK) + this->handler_rep_.unbind (handle, requires_reference_counting); // Note the fact that we've changed the state of the wait_set, // i.e. the "interest set," which is used by the dispatching loop to @@ -1880,7 +1874,7 @@ ACE_Dev_Poll_Reactor::suspend_handler_i (ACE_HANDLE handle) #if defined (ACE_HAS_EVENT_POLL) struct epoll_event epev; - + ACE_OS::memset (&epev, 0, sizeof (epev)); static const int op = EPOLL_CTL_DEL; epev.events = 0; @@ -1990,7 +1984,7 @@ ACE_Dev_Poll_Reactor::resume_handler_i (ACE_HANDLE handle) #if defined (ACE_HAS_EVENT_POLL) struct epoll_event epev; - + ACE_OS::memset (&epev, 0, sizeof (epev)); static const int op = EPOLL_CTL_ADD; epev.events = this->reactor_mask_to_poll_event (mask); @@ -2432,7 +2426,7 @@ ACE_Dev_Poll_Reactor::mask_ops_i (ACE_HANDLE handle, #elif defined (ACE_HAS_EVENT_POLL) struct epoll_event epev; - + ACE_OS::memset (&epev, 0, sizeof (epev)); int op; // ACE_Event_Handler::NULL_MASK ??? diff --git a/ace/Dev_Poll_Reactor.h b/ace/Dev_Poll_Reactor.h index 22925164dbd..5e9f054a6d9 100644 --- a/ace/Dev_Poll_Reactor.h +++ b/ace/Dev_Poll_Reactor.h @@ -382,8 +382,9 @@ public: ACE_Event_Handler *handler, ACE_Reactor_Mask mask); - /// Remove the binding of @c ACE_HANDLE in accordance with the . - int unbind (ACE_HANDLE handle); + /// Remove the binding for @c ACE_HANDLE; optionally decrement the associated + /// handler's reference count. + int unbind (ACE_HANDLE handle, bool decr_refcnt = true); /// Remove all the (@c ACE_HANDLE, @c ACE_Event_Handler) tuples. int unbind_all (void); diff --git a/tests/Dev_Poll_Reactor_Test.cpp b/tests/Dev_Poll_Reactor_Test.cpp index be103246c93..2b48767b875 100644 --- a/tests/Dev_Poll_Reactor_Test.cpp +++ b/tests/Dev_Poll_Reactor_Test.cpp @@ -203,14 +203,13 @@ Server::Server (void) int Server::handle_input (ACE_HANDLE /* handle */) { - char buffer[BUFSIZ] = { 0 }; - + char buffer[BUFSIZ+1] = { 0 }; // Insure a trailing nul ssize_t bytes_read = 0; char * const begin = buffer; char * const end = buffer + BUFSIZ; - for (char * buf = begin; buf != end; buf += bytes_read) + for (char * buf = begin; buf < end; buf += bytes_read) { // Keep reading until it is no longer possible to do so. // @@ -218,7 +217,7 @@ Server::handle_input (ACE_HANDLE /* handle */) // mechanism may have a "state change" interface (as opposed to // "state monitoring"), in which case a "speculative" read is // done. - bytes_read = this->peer ().recv (buf, BUFSIZ - bytes_read); + bytes_read = this->peer ().recv (buf, end - buf); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("****** bytes_read = %d\n"), -- cgit v1.2.1