diff options
-rw-r--r-- | ChangeLog | 31 | ||||
-rw-r--r-- | ace/Makefile.am | 3 | ||||
-rw-r--r-- | ace/Message_Queue.cpp | 4 | ||||
-rw-r--r-- | ace/Message_Queue_T.cpp | 15 | ||||
-rw-r--r-- | ace/Service_Manager.cpp | 4 | ||||
-rw-r--r-- | ace/Timer_Heap_T.cpp | 65 | ||||
-rw-r--r-- | ace/Truncate.cpp | 15 | ||||
-rw-r--r-- | ace/Truncate.h | 52 | ||||
-rw-r--r-- | ace/Truncate.inl | 44 | ||||
-rw-r--r-- | ace/UPIPE_Connector.cpp | 2 | ||||
-rw-r--r-- | ace/WIN32_Asynch_IO.cpp | 36 | ||||
-rw-r--r-- | ace/ace.mpc | 1 |
12 files changed, 240 insertions, 32 deletions
diff --git a/ChangeLog b/ChangeLog index f3906871db2..e33259c4795 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,34 @@ +Tue Feb 21 23:49:20 UTC 2006 Steve Huston <shuston@riverace.com> + + * ace/Truncate.{h inl cpp}: New function template, ACE_Utils::Truncate, + for truncating types to int. Compares the value to the maximum int + value and, if passed value is greater, returns the max int; else + returns the original value cast to int. Useful for the many places + that return int but maintain larger types (such as size_t) + internally. There's a specialization for size_t since it's used so + much. + + * ace/ace.mpc: Add Truncate.cpp + + * ace/Makefile.am: Added Truncate.{h inl cpp} + + * ace/Message_Queue_T.cpp: + * ace/Message_Queue.cpp: Use ACE_Utils::Truncate() to return size/count + related values that may overflow the range of an int. Prevents odd + conditions that may appear as failures when dealing with very large + numbers of items in a queue. And, resolves compile warnings. + + * ace/Timer_Heap_T.cpp: In constructor, add checks to see if max_size_ + is outside the range of a long and reduce it if so. This ensures we + can cast size_t values to a long as a timer ID (pop_freelist). + NOTE!!! In grow_heap(), the size is doubled and there's no check for + failures in range or in allocation. This a problem that should be + looked at. + + * ace/Service_Manager.cpp (reconfigure_services): + * ace/WIN32_Asynch_IO.cpp: + * ace/UPIPE_Connector.cpp (connect): Fix compiler warnings. + Tue Feb 21 23:08:38 UTC 2006 Steve Huston <shuston@riverace.com> * ace/OS_NS_time.cpp: Add missing close brace for blank namespace diff --git a/ace/Makefile.am b/ace/Makefile.am index d61777b8544..470cb81ab75 100644 --- a/ace/Makefile.am +++ b/ace/Makefile.am @@ -323,6 +323,7 @@ libACE_la_SOURCES = \ Token_Manager.cpp \ Token_Request_Reply.cpp \ Trace.cpp \ + Truncate.cpp \ UNIX_Addr.cpp \ UPIPE_Acceptor.cpp \ UPIPE_Connector.cpp \ @@ -1043,6 +1044,8 @@ nobase_include_HEADERS += \ Token_Request_Reply.h \ Token_Request_Reply.inl \ Trace.h \ + Truncate.h \ + Truncate.inl \ Typed_SV_Message.cpp \ Typed_SV_Message.h \ Typed_SV_Message.inl \ diff --git a/ace/Message_Queue.cpp b/ace/Message_Queue.cpp index 32a4f534551..4e4cc1a461d 100644 --- a/ace/Message_Queue.cpp +++ b/ace/Message_Queue.cpp @@ -446,7 +446,7 @@ ACE_Message_Queue_NT::enqueue (ACE_Message_Block *new_item, // Update the states once I succeed. this->cur_bytes_ += msize; this->cur_length_ += mlength; - return ++this->cur_count_; + return ACE_Utils::Truncate (++this->cur_count_); } } else @@ -497,7 +497,7 @@ ACE_Message_Queue_NT::dequeue (ACE_Message_Block *&first_item, --this->cur_count_; this->cur_bytes_ -= msize; this->cur_length_ -= first_item->total_length (); - return this->cur_count_; + return ACE_Utils::Truncate (this->cur_count_); } else // Woken up by deactivate () or pulse (). errno = ESHUTDOWN; diff --git a/ace/Message_Queue_T.cpp b/ace/Message_Queue_T.cpp index 0ece6377375..9bfcd5cc5f2 100644 --- a/ace/Message_Queue_T.cpp +++ b/ace/Message_Queue_T.cpp @@ -14,6 +14,7 @@ #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "ace/Notification_Strategy.h" +#include "ace/Truncate.h" ACE_BEGIN_VERSIONED_NAMESPACE_DECL @@ -1015,7 +1016,7 @@ ACE_Message_Queue<ACE_SYNCH_USE>::enqueue_tail_i (ACE_Message_Block *new_item) if (this->signal_dequeue_waiters () == -1) return -1; else - return this->cur_count_; + return ACE_Utils::Truncate (this->cur_count_); } // Actually put the node(s) at the head (no locking) @@ -1059,7 +1060,7 @@ ACE_Message_Queue<ACE_SYNCH_USE>::enqueue_head_i (ACE_Message_Block *new_item) if (this->signal_dequeue_waiters () == -1) return -1; else - return this->cur_count_; + return ACE_Utils::Truncate (this->cur_count_); } // Actually put the node at its proper position relative to its @@ -1130,7 +1131,7 @@ ACE_Message_Queue<ACE_SYNCH_USE>::enqueue_i (ACE_Message_Block *new_item) if (this->signal_dequeue_waiters () == -1) return -1; else - return this->cur_count_; + return ACE_Utils::Truncate (this->cur_count_); } // Actually put the node at its proper position relative to its @@ -1246,7 +1247,7 @@ ACE_Message_Queue<ACE_SYNCH_USE>::dequeue_head_i (ACE_Message_Block *&first_item && this->signal_enqueue_waiters () == -1) return -1; else - return this->cur_count_; + return ACE_Utils::Truncate (this->cur_count_); } // Get the earliest (i.e., FIFO) ACE_Message_Block with the lowest @@ -1322,7 +1323,7 @@ ACE_Message_Queue<ACE_SYNCH_USE>::dequeue_prio_i (ACE_Message_Block *&dequeued) && this->signal_enqueue_waiters () == -1) return -1; else - return this->cur_count_; + return ACE_Utils::Truncate (this->cur_count_); } // Actually get the last ACE_Message_Block (no locking, so must be @@ -1371,7 +1372,7 @@ ACE_Message_Queue<ACE_SYNCH_USE>::dequeue_tail_i (ACE_Message_Block *&dequeued) && this->signal_enqueue_waiters () == -1) return -1; else - return this->cur_count_; + return ACE_Utils::Truncate (this->cur_count_); } // Actually get the ACE_Message_Block with the lowest deadline time @@ -1467,7 +1468,7 @@ ACE_Message_Queue<ACE_SYNCH_USE>::peek_dequeue_head (ACE_Message_Block *&first_i return -1; first_item = this->head_; - return this->cur_count_; + return ACE_Utils::Truncate (this->cur_count_); } template <ACE_SYNCH_DECL> int diff --git a/ace/Service_Manager.cpp b/ace/Service_Manager.cpp index fe74df4ec7b..446302ce87a 100644 --- a/ace/Service_Manager.cpp +++ b/ace/Service_Manager.cpp @@ -233,8 +233,8 @@ ACE_Service_Manager::reconfigure_services (void) // the rug" out from underneath the existing services in a // problematic way. ACE_Service_Config::reconfig_occurred ((sig_atomic_t) 1); - return this->client_stream_.send_n ("done\n", - sizeof ("done\n")); + return static_cast<int> (this->client_stream_.send_n ("done\n", + sizeof ("done\n"))); } // isolate the request-processing code diff --git a/ace/Timer_Heap_T.cpp b/ace/Timer_Heap_T.cpp index 690bd0e9971..36e08839197 100644 --- a/ace/Timer_Heap_T.cpp +++ b/ace/Timer_Heap_T.cpp @@ -6,12 +6,31 @@ #include "ace/Timer_Heap_T.h" #include "ace/Log_Msg.h" #include "ace/Guard_T.h" +#include "ace/OS_NS_errno.h" #include "ace/OS_NS_string.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ +/* +** The ACE_Timer_Heap::max_size_ and array loops, checks, etc. are all size_t. +** The timer IDs are long, and since they are indices into the heap, we need +** to be sure that the timer heap size can fit in a long. Hence, when size +** is (re)set, limit it to the maximum long value. We use the C++ standard +** limits if available. +*/ +#if !defined(ACE_LACKS_NUMERIC_LIMITS) +// some platforms pollute the namespace by defining max() and min() macros +#ifdef max +#undef max +#endif +#ifdef min +#undef min +#endif +#include <limits> +#endif /* ACE_LACKS_NUMERIC_LIMITS */ + ACE_BEGIN_VERSIONED_NAMESPACE_DECL // Define some simple macros to clarify the code. @@ -89,6 +108,21 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_Heap_T (size_t size, { ACE_TRACE ("ACE_Timer_Heap_T::ACE_Timer_Heap_T"); + // Possibly reduce size to fit in a long. +#if !defined(ACE_LACKS_NUMERIC_LIMITS) + if (size > std::numeric_limits<long>::max ()) + { + size = std::numeric_limits<long>::max (); + this->max_size_ = size; + } +#else + if (size > LONG_MAX) + { + size = LONG_MAX; + this->max_size_ = size; + } +#endif /* ACE_LACKS_NUMERIC_LIMITS */ + // Create the heap array. ACE_NEW (this->heap_, ACE_Timer_Node_T<TYPE> *[size]); @@ -146,6 +180,15 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_Heap_T (FUNCTOR *upcall_fun { ACE_TRACE ("ACE_Timer_Heap_T::ACE_Timer_Heap_T"); + // Possibly reduce size to fit in a long. +#if !defined(ACE_LACKS_NUMERIC_LIMITS) + if (this->max_size_ > static_cast<size_t> (std::numeric_limits<long>::max ())) + this->max_size_ = static_cast<size_t> (std::numeric_limits<long>::max ()); +#else + if (this->max_size_ > LONG_MAX) + this->max_size_ = LONG_MAX; +#endif /* ACE_LACKS_NUMERIC_LIMITS */ + // Create the heap array. #if defined (__IBMCPP__) && (__IBMCPP__ >= 400) && defined (_WINDOWS) ACE_NEW (this->heap_, @@ -237,7 +280,7 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::pop_freelist (void) this->timer_ids_min_free_ = this->max_size_; } - return this->timer_ids_curr_; + return static_cast<long> (this->timer_ids_curr_); } template <class TYPE, class FUNCTOR, class ACE_LOCK> void @@ -474,9 +517,27 @@ ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::insert (ACE_Timer_Node_T<TYPE> *new_n template <class TYPE, class FUNCTOR, class ACE_LOCK> void ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::grow_heap (void) { - // All the containers will double in size from max_size_ + // All the containers will double in size from max_size_. size_t new_size = this->max_size_ * 2; +#if 0 + // Yikes - there's no way to flag a failure of going out of range of + // a 'long' - this is a problem that should be addressed at some point. +#if !defined(ACE_LACKS_NUMERIC_LIMITS) + if (new_size > std::numeric_limits<long>::max ()) + new_size = std::numeric_limits<long>::max (); +#else + if (new_size > LONG_MAX) + new_size = LONG_MAX; +#endif /* ACE_LACKS_NUMERIC_LIMITS */ + + if (new_size <= this->max_size_) // We are already at the limit + { + errno = ENOMEM; + return -1; + } +#endif /* 0 */ + // First grow the heap itself. ACE_Timer_Node_T<TYPE> **new_heap = 0; diff --git a/ace/Truncate.cpp b/ace/Truncate.cpp new file mode 100644 index 00000000000..722f34027d9 --- /dev/null +++ b/ace/Truncate.cpp @@ -0,0 +1,15 @@ +// $Id$ + +#ifndef ACE_TRUNCATE_CPP +#define ACE_TRUNCATE_CPP + +#include "ace/Truncate.h" + +#if !defined(__ACE_INLINE__) +# include "ace/Truncate.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL +ACE_END_VERSIONED_NAMESPACE_DECL + +#endif /*ACE_TRUNCATE_CPP*/ diff --git a/ace/Truncate.h b/ace/Truncate.h new file mode 100644 index 00000000000..f982ff7e3a5 --- /dev/null +++ b/ace/Truncate.h @@ -0,0 +1,52 @@ +// -*- C++ -*- +//============================================================================= +/** + * @file Truncate.h + * + * $Id$ + * + * @author Steve Huston <shuston@riverace.com> + */ +//============================================================================= +#ifndef ACE_TRUNCATE_H +#define ACE_TRUNCATE_H +#include /**/ "ace/pre.h" + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Global_Macros.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +namespace ACE_Utils +{ +/** + * @class Truncate + * + * @brief Helper function to truncate an integral value to an int. + * Very useful since ACE methods return int very often and the value's + * source is often a different-size integral type, such as size_t. + * This function hides the truncation logic and resolves compiler + * diagnostics. + */ +template<typename X> +ACE_NAMESPACE_INLINE_FUNCTION int Truncate (const X& val); + +// Specialize one for size_t to alleviate the explicit instantiation pain. +template<> +ACE_NAMESPACE_INLINE_FUNCTION int Truncate<size_t> (const size_t& val); + +} // namespace ACE_Utils + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined(__ACE_INLINE__) +# include "ace/Truncate.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_TRUNCATE_H*/ diff --git a/ace/Truncate.inl b/ace/Truncate.inl new file mode 100644 index 00000000000..825559a8004 --- /dev/null +++ b/ace/Truncate.inl @@ -0,0 +1,44 @@ +// -*- C++ -*- +// +// $Id$ + +#if !defined(ACE_LACKS_NUMERIC_LIMITS) +// some platforms pollute the namespace by defining max() and min() macros +#ifdef max +#undef max +#endif +#ifdef min +#undef min +#endif +#include <limits> +#endif /* ACE_LACKS_NUMERIC_LIMITS */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +template<typename X> ACE_NAMESPACE_INLINE_FUNCTION int +ACE_Utils::Truncate (const X &val) +{ +#if !defined (ACE_LACKS_NUMERIC_LIMITS) + if (val > static_cast<X> (std::numeric_limits<int>::max ())) + return std::numeric_limits<int>::max (); +#else + if (val > static_cast<X> (INT_MAX)) + return INT_MAX; +#endif /* ACE_LACKS_NUMERIC_LIMITS */ + return static_cast<int> (val); +} + +template<> ACE_NAMESPACE_INLINE_FUNCTION int +ACE_Utils::Truncate<size_t> (const size_t &val) +{ +#if !defined (ACE_LACKS_NUMERIC_LIMITS) + if (val > static_cast<size_t> (std::numeric_limits<int>::max ())) + return std::numeric_limits<int>::max (); +#else + if (val > static_cast<size_t> (INT_MAX)) + return INT_MAX; +#endif /* ACE_LACKS_NUMERIC_LIMITS */ + return static_cast<int> (val); +} + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/ace/UPIPE_Connector.cpp b/ace/UPIPE_Connector.cpp index afe3056ae3b..ba0b4592d2f 100644 --- a/ace/UPIPE_Connector.cpp +++ b/ace/UPIPE_Connector.cpp @@ -92,7 +92,7 @@ ACE_UPIPE_Connector::connect (ACE_UPIPE_Stream &new_stream, // connection anymore since we're linked via the Message_Queue // now. new_stream.ACE_SPIPE::close (); - return result; + return static_cast<int> (result); } } diff --git a/ace/WIN32_Asynch_IO.cpp b/ace/WIN32_Asynch_IO.cpp index 8aa96b229fb..63b5ed4f63f 100644 --- a/ace/WIN32_Asynch_IO.cpp +++ b/ace/WIN32_Asynch_IO.cpp @@ -3340,15 +3340,15 @@ ACE_WIN32_Asynch_Read_Dgram::recv (ACE_Message_Block *message_block, -1); // do the scatter/gather recv - int initiate_result = ACE_OS::recvfrom (result->handle (), - iov, - iovcnt, - number_of_bytes_recvd, - result->flags_, - result->saddr (), - &(result->addr_len_), - result, - 0); + ssize_t initiate_result = ACE_OS::recvfrom (result->handle (), + iov, + iovcnt, + number_of_bytes_recvd, + result->flags_, + result->saddr (), + &(result->addr_len_), + result, + 0); if (initiate_result == SOCKET_ERROR) { // If initiate failed, check for a bad error. @@ -3667,15 +3667,15 @@ ACE_WIN32_Asynch_Write_Dgram::send (ACE_Message_Block *message_block, // do the scatter/gather send - int initiate_result = ACE_OS::sendto (result->handle (), - iov, - iovcnt, - number_of_bytes_sent, - result->flags_, - (sockaddr *) addr.get_addr (), - addr.get_size(), - result, - 0); + ssize_t initiate_result = ACE_OS::sendto (result->handle (), + iov, + iovcnt, + number_of_bytes_sent, + result->flags_, + (sockaddr *) addr.get_addr (), + addr.get_size(), + result, + 0); if (initiate_result == SOCKET_ERROR) diff --git a/ace/ace.mpc b/ace/ace.mpc index 503c7c3123b..63df606091b 100644 --- a/ace/ace.mpc +++ b/ace/ace.mpc @@ -270,6 +270,7 @@ project(ACE) : acedefaults, core, other, codecs, token, svcconf, uuid, filecache Token.cpp TP_Reactor.cpp Trace.cpp + Truncate.cpp TSS_Adapter.cpp TTY_IO.cpp UNIX_Addr.cpp |