diff options
author | irfan <irfan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1999-07-22 07:32:05 +0000 |
---|---|---|
committer | irfan <irfan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1999-07-22 07:32:05 +0000 |
commit | 9cc3d836eef7e45e68db52f59016aff22835d12e (patch) | |
tree | 0aec127460ba41c5aa1b565e0cf624874bbc0669 | |
parent | b77d0bb15156c7e8d717257b9e817f239524b14a (diff) | |
download | ATCD-9cc3d836eef7e45e68db52f59016aff22835d12e.tar.gz |
ChangeLogTag:Thu Jul 22 02:15:46 1999 Irfan Pyarali <irfan@cs.wustl.edu>
-rw-r--r-- | ChangeLog-99b | 18 | ||||
-rw-r--r-- | ace/Handle_Gobbler.h | 63 | ||||
-rw-r--r-- | ace/Handle_Gobbler.i | 81 | ||||
-rw-r--r-- | tests/Cached_Accept_Conn_Test.cpp | 63 | ||||
-rw-r--r-- | tests/Cached_Conn_Test.cpp | 57 |
5 files changed, 243 insertions, 39 deletions
diff --git a/ChangeLog-99b b/ChangeLog-99b index c2930bee4d3..3bc7c4232d9 100644 --- a/ChangeLog-99b +++ b/ChangeLog-99b @@ -1,3 +1,21 @@ +Thu Jul 22 02:15:46 1999 Irfan Pyarali <irfan@cs.wustl.edu> + + * ace/Handle_Gobbler (class ACE_Handle_Gobbler): New class that + gobbles up handles :) This class is useful when we need to + control the number of handles available for a process. Mostly + used for testing purposes. + + Note that even though the new files are in the ace directory, + they are not part of the ace library. The files only contain + inline functions and Handle_Gobbler.h is only included where + needed. + + * tests/Cached_Conn_Test.cpp: + * tests/Cached_Accept_Conn_Test.cpp: + + Added Handle_Gobbler to the test to reduce the iterations + required before handles run out and purging starts. + Wed Jul 21 21:45:22 1999 Nanbor Wang <nanbor@cs.wustl.edu> * ace/Reactor.cpp: Applied ACE_NOTREACHED to several diff --git a/ace/Handle_Gobbler.h b/ace/Handle_Gobbler.h new file mode 100644 index 00000000000..9f9dbe7ceb7 --- /dev/null +++ b/ace/Handle_Gobbler.h @@ -0,0 +1,63 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Handle_Gobbler.h +// +// = AUTHOR +// Kirthika Parameswaran <kirthika@cs.wustl.edu> +// Irfan Pyarali <irfan@cs.wustl.edu> +// +// ============================================================================ + +#ifndef ACE_HANDLE_GOBBLER_H +#define ACE_HANDLE_GOBBLER_H + +#include "ace/OS.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Containers_T.h" + +class ACE_Handle_Gobbler +{ + // = TITLE + // This class gobbles up handles. + // + // = DESCRIPTION + // This is useful when we need to control the number of handles + // available for a process. This class is mostly used for + // testing purposes. +public: + + ~ACE_Handle_Gobbler (void); + // Destructor. Cleans up any remaining handles. + + int consume_handles (size_t n_handles_to_keep_available); + // Handles are opened continously until the process runs out of + // them, and then <n_handles_to_keep_available> handles are closed + // (freed) thereby making them usable in the future. + + int free_handles (size_t n_handles); + // Free up <n_handles>. + + void close_remaining_handles (void); + // All remaining handles are closed. + +private: + + typedef ACE_Unbounded_Set<ACE_HANDLE> HANDLE_SET; + + HANDLE_SET handle_set_; + // The container which holds the open descriptors. +}; + +#include "ace/Handle_Gobbler.i" + +#endif /* ACE_HANDLE_GOBBLER_H */ diff --git a/ace/Handle_Gobbler.i b/ace/Handle_Gobbler.i new file mode 100644 index 00000000000..da5a30e697d --- /dev/null +++ b/ace/Handle_Gobbler.i @@ -0,0 +1,81 @@ +// $Id$ + +inline +ACE_Handle_Gobbler::~ACE_Handle_Gobbler (void) +{ + this->close_remaining_handles (); +} + +inline int +ACE_Handle_Gobbler::consume_handles (size_t n_handles_to_keep_available) +{ + int result = 0; + + // On Win32, this style of gobbling doesn't seem to work. +#if !defined (ACE_WIN32) + + while (1) + { + ACE_HANDLE handle = ACE_OS::open (ACE_DEV_NULL, O_WRONLY); + + if (handle == ACE_INVALID_HANDLE) + { + if (ACE::out_of_handles (errno)) + { + result = this->free_handles (n_handles_to_keep_available); + break; + } + else + { + result = -1; + break; + } + } + + result = this->handle_set_.insert (handle); + if (result == -1) + break; + } + +#endif /* ACE_WIN32 */ + + return result; +} + +inline int +ACE_Handle_Gobbler::free_handles (size_t n_handles) +{ + HANDLE_SET::iterator iterator = + this->handle_set_.begin (); + + HANDLE_SET::iterator end = + this->handle_set_.end (); + + for (; + iterator != end && n_handles > 0; + ++iterator, --n_handles) + { + int result = ACE_OS::close (*iterator); + if (result != 0) + return result; + } + + return 0; +} + +inline void +ACE_Handle_Gobbler::close_remaining_handles (void) +{ + HANDLE_SET::iterator iterator = + this->handle_set_.begin (); + + HANDLE_SET::iterator end = + this->handle_set_.end (); + + for (; + iterator != end; + ++iterator) + { + ACE_OS::close (*iterator); + } +} diff --git a/tests/Cached_Accept_Conn_Test.cpp b/tests/Cached_Accept_Conn_Test.cpp index ca63b15db22..20e5d348f8e 100644 --- a/tests/Cached_Accept_Conn_Test.cpp +++ b/tests/Cached_Accept_Conn_Test.cpp @@ -49,6 +49,7 @@ #include "ace/Get_Opt.h" #include "ace/Caching_Utility_T.h" #include "ace/Cached_Connect_Strategy_T.h" +#include "ace/Handle_Gobbler.h" #if defined(_MSC_VER) #pragma warning(disable:4503) @@ -182,10 +183,19 @@ enum Caching_Strategy_Type // Default number of clients/servers. static int listen_once = 1; -static int iterations = 2000; static int user_has_specified_iterations = 0; +static size_t keep_handles_available = 100; static double purge_percentage = 20; static Caching_Strategy_Type caching_strategy_type = ACE_ALL; +static CACHED_CONNECT_STRATEGY *connect_strategy = 0; + +// On Win32, the handle gobbling doesn't work. Therefore, we need +// more iterations to get to the handle limit. +#if defined (ACE_WIN32) +static int iterations = 2000; +#else +static int iterations = 500; +#endif /* ACE_WIN32 */ //==================================================================== @@ -253,10 +263,6 @@ Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::accept_svc_handler (SVC_HANDL int result = ACE_Reactor::instance ()->end_event_loop (); ACE_ASSERT (result != 1); - // Note: The base class method isnt called since it closes the - // svc_handler on error which we want to avoid as we are trying to - // accept after purging. - // Try to find out if the implementation of the reactor that we are // using requires us to reset the event association for the newly // created handle. This is because the newly created handle will @@ -478,7 +484,7 @@ test_caching_strategy_type (void) int parse_args (int argc, char *argv[]) { - ACE_Get_Opt get_opt (argc, argv, "l:i:p:c:d"); + ACE_Get_Opt get_opt (argc, argv, "l:i:p:c:a:d"); int cc; @@ -511,6 +517,9 @@ parse_args (int argc, char *argv[]) if (ACE_OS::strcmp (get_opt.optarg, "fifo") == 0) caching_strategy_type = ACE_FIFO; break; + case 'a': + keep_handles_available = atoi (get_opt.optarg); + break; case '?': case 'h': default: @@ -521,7 +530,8 @@ parse_args (int argc, char *argv[]) ASYS_TEXT ("[-i (iterations)] ") ASYS_TEXT ("[-l (listen once)] ") ASYS_TEXT ("[-d (addition debugging output)] ") - ASYS_TEXT ("[-p (purge percent)] "), + ASYS_TEXT ("[-p (purge percent)] ") + ASYS_TEXT ("[-a (keep handles available)] "), argv[0])); return -1; } @@ -552,6 +562,20 @@ main (int argc, // Remove the extra debugging attributes from Log_Msg output. ACE_LOG_MSG->clr_flags (ACE_Log_Msg::VERBOSE_LITE); + // The reactor's constructor changes the handle limit for the + // process. + ACE_Reactor::instance (); + + // Consume all handles in the process, leaving us + // <keep_handles_available> to play with. + ACE_Handle_Gobbler handle_gobbler; + result = handle_gobbler.consume_handles (keep_handles_available); + ACE_ASSERT (result == 0); + +#if defined ACE_HAS_BROKEN_EXTENDED_TEMPLATES + caching_strategy_type = ACE_LRU; +#endif /* ACE_HAS_BROKEN_EXTENDED_TEMPLATES */ + // Do we need to test all the strategies. Note, that the less // useful null strategy is ignored in this case. if (caching_strategy_type == ACE_ALL) @@ -598,6 +622,11 @@ main (int argc, #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +// = Consume handles +template class ACE_Node<ACE_HANDLE>; +template class ACE_Unbounded_Set<ACE_HANDLE>; +template class ACE_Unbounded_Set_Iterator<ACE_HANDLE>; + template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>; template class ACE_Refcounted_Hash_Recyclable<ACE_INET_Addr>; template class ACE_NOOP_Creation_Strategy<Client_Svc_Handler>; @@ -608,13 +637,6 @@ template class ACE_Creation_Strategy<Client_Svc_Handler>; template class ACE_Hash_Map_Entry<ADDR, Client_Svc_Handler *>; template class ACE_Hash<ADDR>; template class ACE_Equal_To<ADDR>; -template class ACE_Hash_Map_Manager<ADDR, Client_Svc_Handler *, ACE_SYNCH_RW_MUTEX>; -template class ACE_Hash_Map_Manager_Ex<ADDR, Client_Svc_Handler *, H_KEY, C_KEYS, ACE_SYNCH_RW_MUTEX>; -template class ACE_Hash_Map_Iterator_Base_Ex<ADDR, Client_Svc_Handler *, H_KEY, C_KEYS, ACE_SYNCH_RW_MUTEX>; -template class ACE_Hash_Map_Iterator<ADDR, Client_Svc_Handler *, ACE_SYNCH_RW_MUTEX>; -template class ACE_Hash_Map_Iterator_Ex<ADDR, Client_Svc_Handler *, H_KEY, C_KEYS, ACE_SYNCH_RW_MUTEX>; -template class ACE_Hash_Map_Reverse_Iterator<ADDR, Client_Svc_Handler *, ACE_SYNCH_RW_MUTEX>; -template class ACE_Hash_Map_Reverse_Iterator_Ex<ADDR, Client_Svc_Handler *, H_KEY, C_KEYS, ACE_SYNCH_RW_MUTEX>; template class ACE_Map_Entry<ACE_HANDLE, ACE_Svc_Tuple<Client_Svc_Handler> *>; template class ACE_Map_Manager<ACE_HANDLE, ACE_Svc_Tuple<Client_Svc_Handler> *, ACE_SYNCH_RW_MUTEX>; template class ACE_Map_Iterator_Base<ACE_HANDLE, ACE_Svc_Tuple<Client_Svc_Handler> *, ACE_SYNCH_RW_MUTEX>; @@ -693,7 +715,6 @@ template class ACE_Reverse_Lock<ACE_SYNCH_NULL_MUTEX>; template class ACE_Guard<ACE_Reverse_Lock<ACE_SYNCH_NULL_MUTEX> >; #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) - #pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> #pragma instantiate ACE_Refcounted_Hash_Recyclable<ACE_INET_Addr> #pragma instantiate ACE_NOOP_Creation_Strategy<Client_Svc_Handler> @@ -704,13 +725,6 @@ template class ACE_Guard<ACE_Reverse_Lock<ACE_SYNCH_NULL_MUTEX> >; #pragma instantiate ACE_Hash_Map_Entry<ADDR, Client_Svc_Handler *> #pragma instantiate ACE_Hash<ADDR> #pragma instantiate ACE_Equal_To<ADDR> -#pragma instantiate ACE_Hash_Map_Manager<ADDR, Client_Svc_Handler *, ACE_SYNCH_RW_MUTEX> -#pragma instantiate ACE_Hash_Map_Manager_Ex<ADDR, Client_Svc_Handler *, H_KEY, C_KEYS, ACE_SYNCH_RW_MUTEX> -#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<ADDR, Client_Svc_Handler *, H_KEY, C_KEYS, ACE_SYNCH_RW_MUTEX> -#pragma instantiate ACE_Hash_Map_Iterator<ADDR, Client_Svc_Handler *, ACE_SYNCH_RW_MUTEX> -#pragma instantiate ACE_Hash_Map_Iterator_Ex<ADDR, Client_Svc_Handler *, H_KEY, C_KEYS, ACE_SYNCH_RW_MUTEX> -#pragma instantiate ACE_Hash_Map_Reverse_Iterator<ADDR, Client_Svc_Handler *, ACE_SYNCH_RW_MUTEX> -#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<ADDR, Client_Svc_Handler *, H_KEY, C_KEYS, ACE_SYNCH_RW_MUTEX> #pragma instantiate ACE_Map_Entry<ACE_HANDLE, ACE_Svc_Tuple<Client_Svc_Handler> *> #pragma instantiate ACE_Map_Manager<ACE_HANDLE, ACE_Svc_Tuple<Client_Svc_Handler> *, ACE_SYNCH_RW_MUTEX> #pragma instantiate ACE_Map_Iterator_Base<ACE_HANDLE, ACE_Svc_Tuple<Client_Svc_Handler> *, ACE_SYNCH_RW_MUTEX> @@ -758,6 +772,11 @@ template class ACE_Guard<ACE_Reverse_Lock<ACE_SYNCH_NULL_MUTEX> >; #if !defined (ACE_HAS_BROKEN_EXTENDED_TEMPLATES) +// = Consume handles +#pragma instantiate ACE_Node<ACE_HANDLE> +#pragma instantiate ACE_Unbounded_Set<ACE_HANDLE> +#pragma instantiate ACE_Unbounded_Set_Iterator<ACE_HANDLE> + #pragma instantiate ACE_Caching_Strategy<ATTRIBUTES, CACHING_UTILITY> #pragma instantiate ACE_LFU_Caching_Strategy<ATTRIBUTES, CACHING_UTILITY> #pragma instantiate ACE_FIFO_Caching_Strategy<ATTRIBUTES, CACHING_UTILITY> diff --git a/tests/Cached_Conn_Test.cpp b/tests/Cached_Conn_Test.cpp index 2692f75b3d3..21a6f101012 100644 --- a/tests/Cached_Conn_Test.cpp +++ b/tests/Cached_Conn_Test.cpp @@ -47,6 +47,7 @@ #include "ace/Get_Opt.h" #include "ace/Caching_Utility_T.h" #include "ace/Cached_Connect_Strategy_T.h" +#include "ace/Handle_Gobbler.h" #if defined(_MSC_VER) #pragma warning(disable:4503) @@ -163,12 +164,20 @@ enum Caching_Strategy_Type // Default number of clients/servers. static int listen_once = 1; -static int iterations = 2000; static int user_has_specified_iterations = 0; +static size_t keep_handles_available = 100; static double purge_percentage = 20; static Caching_Strategy_Type caching_strategy_type = ACE_ALL; static CACHED_CONNECT_STRATEGY *connect_strategy = 0; +// On Win32, the handle gobbling doesn't work. Therefore, we need +// more iterations to get to the handle limit. +#if defined (ACE_WIN32) +static int iterations = 2000; +#else +static int iterations = 500; +#endif /* ACE_WIN32 */ + //==================================================================== static void @@ -378,7 +387,7 @@ test_caching_strategy_type (void) int parse_args (int argc, char *argv[]) { - ACE_Get_Opt get_opt (argc, argv, "l:i:p:c:d"); + ACE_Get_Opt get_opt (argc, argv, "l:i:p:c:a:d"); int cc; @@ -411,6 +420,9 @@ parse_args (int argc, char *argv[]) if (ACE_OS::strcmp (get_opt.optarg, "fifo") == 0) caching_strategy_type = ACE_FIFO; break; + case 'a': + keep_handles_available = atoi (get_opt.optarg); + break; case '?': case 'h': default: @@ -420,7 +432,8 @@ parse_args (int argc, char *argv[]) ASYS_TEXT ("[-i (iterations)] ") ASYS_TEXT ("[-l (listen once)] ") ASYS_TEXT ("[-d (addition debugging output)] ") - ASYS_TEXT ("[-p (purge percent)] "), + ASYS_TEXT ("[-p (purge percent)] ") + ASYS_TEXT ("[-a (keep handles available)] "), argv[0])); return -1; } @@ -451,6 +464,20 @@ main (int argc, // Remove the extra debugging attributes from Log_Msg output. ACE_LOG_MSG->clr_flags (ACE_Log_Msg::VERBOSE_LITE); + // The reactor's constructor changes the handle limit for the + // process. + ACE_Reactor::instance (); + + // Consume all handles in the process, leaving us + // <keep_handles_available> to play with. + ACE_Handle_Gobbler handle_gobbler; + result = handle_gobbler.consume_handles (keep_handles_available); + ACE_ASSERT (result == 0); + +#if defined ACE_HAS_BROKEN_EXTENDED_TEMPLATES + caching_strategy_type = ACE_LRU; +#endif /* ACE_HAS_BROKEN_EXTENDED_TEMPLATES */ + // Do we need to test all the strategies. Note, that the less // useful null strategy is ignored in this case. if (caching_strategy_type == ACE_ALL) @@ -498,6 +525,11 @@ main (int argc, #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +// = Consume handles +template class ACE_Node<ACE_HANDLE>; +template class ACE_Unbounded_Set<ACE_HANDLE>; +template class ACE_Unbounded_Set_Iterator<ACE_HANDLE>; + template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>; template class ACE_Refcounted_Hash_Recyclable<ACE_INET_Addr>; template class ACE_NOOP_Creation_Strategy<Svc_Handler>; @@ -508,13 +540,6 @@ template class ACE_Creation_Strategy<Svc_Handler>; template class ACE_Hash_Map_Entry<ADDR, Svc_Handler *>; template class ACE_Hash<ADDR>; template class ACE_Equal_To<ADDR>; -template class ACE_Hash_Map_Manager<ADDR, Svc_Handler *, ACE_SYNCH_RW_MUTEX>; -template class ACE_Hash_Map_Manager_Ex<ADDR, Svc_Handler *, H_KEY, C_KEYS, ACE_SYNCH_RW_MUTEX>; -template class ACE_Hash_Map_Iterator_Base_Ex<ADDR, Svc_Handler *, H_KEY, C_KEYS, ACE_SYNCH_RW_MUTEX>; -template class ACE_Hash_Map_Iterator<ADDR, Svc_Handler *, ACE_SYNCH_RW_MUTEX>; -template class ACE_Hash_Map_Iterator_Ex<ADDR, Svc_Handler *, H_KEY, C_KEYS, ACE_SYNCH_RW_MUTEX>; -template class ACE_Hash_Map_Reverse_Iterator<ADDR, Svc_Handler *, ACE_SYNCH_RW_MUTEX>; -template class ACE_Hash_Map_Reverse_Iterator_Ex<ADDR, Svc_Handler *, H_KEY, C_KEYS, ACE_SYNCH_RW_MUTEX>; template class ACE_Map_Entry<ACE_HANDLE, ACE_Svc_Tuple<Svc_Handler> *>; template class ACE_Map_Manager<ACE_HANDLE, ACE_Svc_Tuple<Svc_Handler> *, ACE_SYNCH_RW_MUTEX>; template class ACE_Map_Iterator_Base<ACE_HANDLE, ACE_Svc_Tuple<Svc_Handler> *, ACE_SYNCH_RW_MUTEX>; @@ -587,6 +612,11 @@ template class ACE_Guard<ACE_Reverse_Lock<ACE_SYNCH_NULL_MUTEX> >; #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +// = Consume handles +#pragma instantiate ACE_Node<ACE_HANDLE> +#pragma instantiate ACE_Unbounded_Set<ACE_HANDLE> +#pragma instantiate ACE_Unbounded_Set_Iterator<ACE_HANDLE> + #pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> #pragma instantiate ACE_Refcounted_Hash_Recyclable<ACE_INET_Addr> #pragma instantiate ACE_NOOP_Creation_Strategy<Svc_Handler> @@ -597,13 +627,6 @@ template class ACE_Guard<ACE_Reverse_Lock<ACE_SYNCH_NULL_MUTEX> >; #pragma instantiate ACE_Hash_Map_Entry<ADDR, Svc_Handler *> #pragma instantiate ACE_Hash<ADDR> #pragma instantiate ACE_Equal_To<ADDR> -#pragma instantiate ACE_Hash_Map_Manager<ADDR, Svc_Handler *, ACE_SYNCH_RW_MUTEX> -#pragma instantiate ACE_Hash_Map_Manager_Ex<ADDR, Svc_Handler *, H_KEY, C_KEYS, ACE_SYNCH_RW_MUTEX> -#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<ADDR, Svc_Handler *, H_KEY, C_KEYS, ACE_SYNCH_RW_MUTEX> -#pragma instantiate ACE_Hash_Map_Iterator<ADDR, Svc_Handler *, ACE_SYNCH_RW_MUTEX> -#pragma instantiate ACE_Hash_Map_Iterator_Ex<ADDR, Svc_Handler *, H_KEY, C_KEYS, ACE_SYNCH_RW_MUTEX> -#pragma instantiate ACE_Hash_Map_Reverse_Iterator<ADDR, Svc_Handler *, ACE_SYNCH_RW_MUTEX> -#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<ADDR, Svc_Handler *, H_KEY, C_KEYS, ACE_SYNCH_RW_MUTEX> #pragma instantiate ACE_Map_Entry<ACE_HANDLE, ACE_Svc_Tuple<Svc_Handler> *> #pragma instantiate ACE_Map_Manager<ACE_HANDLE, ACE_Svc_Tuple<Svc_Handler> *, ACE_SYNCH_RW_MUTEX> #pragma instantiate ACE_Map_Iterator_Base<ACE_HANDLE, ACE_Svc_Tuple<Svc_Handler> *, ACE_SYNCH_RW_MUTEX> |