diff options
Diffstat (limited to 'ACE/tests/Thread_Attrs_Test.cpp')
-rw-r--r-- | ACE/tests/Thread_Attrs_Test.cpp | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/ACE/tests/Thread_Attrs_Test.cpp b/ACE/tests/Thread_Attrs_Test.cpp new file mode 100644 index 00000000000..7a9c8351b79 --- /dev/null +++ b/ACE/tests/Thread_Attrs_Test.cpp @@ -0,0 +1,296 @@ + +//============================================================================= +/** + * @file Thread_Attrs_Test.cpp + * + * $Id$ + * + * This test program ensures that attributes set on a thread via the + * ACE_Task/ACE_Thread_Manager are honored. + * + * + * @author Steve Huston <shuston@riverace.com> + */ +//============================================================================= + + +#include "test_config.h" +#include "ace/Task.h" + + + +#if defined (ACE_HAS_THREADS) + +namespace +{ + // Change this to 'true' if you want lots of debugging messages in the log + const bool PRINT_DEBUG_MSGS = true; +} + +class Cancel_Check : public ACE_Task<ACE_MT_SYNCH> +{ +public: + // Create a checker with the state, type requested. + Cancel_Check (bool enable, bool async); + + //FUZZ: disable check_for_lack_ACE_OS + // Spawn the thread + virtual int open (void * = 0); + //FUZZ: enable check_for_lack_ACE_OS + + // Check the cancel settings against what is expected then exit. + virtual int svc (void); + + /// Returns true iff settings match what was requested. + bool operator! (); + +private: + bool enable_req_; + bool async_req_; + bool failed_; +}; + +bool +Cancel_Check::operator!() +{ + return this->failed_; +} + +Cancel_Check::Cancel_Check (bool enable, bool async) + : enable_req_ (enable), async_req_(async), failed_ (false) +{ +} + +int +Cancel_Check::svc (void) +{ +#if defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_PTHREAD_CANCEL) + int state; + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &state); + if (state == PTHREAD_CANCEL_ENABLE && !this->enable_req_) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Cancel found enabled, should not be\n"))); + this->failed_ = true; + } + else if (state == PTHREAD_CANCEL_DISABLE && this->enable_req_) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Cancel found disabled, should not be\n"))); + this->failed_ = true; + } + else + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Cancel found %s; ok\n"), + state == PTHREAD_CANCEL_ENABLE ? ACE_TEXT ("enabled") : + ACE_TEXT ("disabled"))); + } + + int type; + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &type); + if (type == PTHREAD_CANCEL_ASYNCHRONOUS && !this->async_req_) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Cancel type async, should not be\n"))); + this->failed_ = true; + } + else if (type == PTHREAD_CANCEL_DEFERRED && this->async_req_) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Cancel type deferred, should not be\n"))); + this->failed_ = true; + } + else + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Cancel type %s; ok\n"), + type == PTHREAD_CANCEL_DEFERRED ? ACE_TEXT ("deferred") : + ACE_TEXT ("asynchronous"))); + } + +#endif + return 0; +} + +int +Cancel_Check::open (void *) +{ + long flags = THR_NEW_LWP | THR_JOINABLE; + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Flags before cancels: 0x%x\n"), flags)); + flags |= (this->enable_req_ ? THR_CANCEL_ENABLE : THR_CANCEL_DISABLE); + flags |= (this->async_req_ ? THR_CANCEL_ASYNCHRONOUS : THR_CANCEL_DEFERRED); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Flags after cancels: 0x%x\n"), flags)); + if (this->activate (flags) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("Cancel_Check activate failed")), + -1); + return 0; +} + + +/** + * @class Stack_Size_Check + * + * @brief Defines a task that verifies its stack size. + */ +class Stack_Size_Check : public ACE_Task<ACE_MT_SYNCH> +{ + +public: + /// Create the thread with specified stack size + Stack_Size_Check (size_t stack_size); + + //FUZZ: disable check_for_lack_ACE_OS + /// Spawn the thread + virtual int open (void * = 0); + //FUZZ: enable check_for_lack_ACE_OS + + /// Check the stack size against what is expected then exit. + virtual int svc (void); + + /// Returns true iff failed_ == false. + bool operator! (); + +private: + size_t stack_size_; + + /// Flag indicating the test failed. + bool failed_; +}; + +bool +Stack_Size_Check::operator!() +{ + return this->failed_; +} + +Stack_Size_Check::Stack_Size_Check (size_t stack_size) + : stack_size_ (stack_size), failed_ (false) +{ +} + +int +Stack_Size_Check::svc (void) +{ + size_t my_size = 0; + +#ifdef __USE_GNU + pthread_attr_t my_attrs; + pthread_getattr_np (pthread_self (), &my_attrs); + pthread_attr_getstacksize (&my_attrs, &my_size); + pthread_attr_destroy (&my_attrs); +#else + // No known way to do this yet... feel free to fill this in. + my_size = this->stack_size_; +#endif /* __USE_GNU */ + + // The Posix docs say that the size set for the threads stack will be the + // *minimum* size allocated (the actual size may be bigger because of + // a) pagesize rounding, b) guardsize addition) so we can really only + // check if we have gotten *at least* what we asked for. + if (my_size < this->stack_size_) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%t: My stack size attr %B; expected %B\n"), + my_size, this->stack_size_)); + this->failed_ = true; + } + else + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("%t: My stack size attr %B; correct.\n"), + my_size)); + return 0; +} + +int +Stack_Size_Check::open (void *) +{ + if (this->activate (THR_NEW_LWP | THR_JOINABLE, + 1, + 0, + ACE_DEFAULT_THREAD_PRIORITY, + -1, + 0, + 0, + 0, + &stack_size_) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("Stack_Size_Check activate failed")), + -1); + + return 0; +} + +#endif /* ACE_HAS_THREADS */ + + +int +run_main (int, ACE_TCHAR *[]) +{ + ACE_START_TEST (ACE_TEXT ("Thread_Attrs_Test")); + + int status = 0; +#if defined (ACE_HAS_THREADS) + Stack_Size_Check size_checker (40*1024); + status = size_checker.open(0); + if (status == 0) + { + if (size_checker.wait () == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("size_checker %p\n"), + ACE_TEXT ("wait")), + 1); + if (!size_checker) + status = 1; + } + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Cancel flags sanity check:\n") + ACE_TEXT (" THR_CANCEL_ENABLE: 0x%x\n") + ACE_TEXT (" THR_CANCEL_DISABLE: 0x%x\n") + ACE_TEXT (" THR_CANCEL_DEFERRED: 0x%x\n") + ACE_TEXT (" THR_CANCEL_ASYNCHRONOUS: 0x%x\n"), + THR_CANCEL_ENABLE, + THR_CANCEL_DISABLE, + THR_CANCEL_DEFERRED, + THR_CANCEL_ASYNCHRONOUS)); + // Cancel check args: enable (yes/no), async/deferred + Cancel_Check check1 (true, true); + Cancel_Check check2 (true, false); + Cancel_Check check3 (false, true); + Cancel_Check check4 (false, false); + if (check1.open(0) == 0) + { + check1.wait (); + if (!check1) + status = 1; + + check2.open (0); + check2.wait (); + if (!check2) + status = 1; + + check3.open (0); + check3.wait (); + if (!check3) + status = 1; + + check4.open (0); + check4.wait (); + if (!check4) + status = 1; + } + else + { + ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("Cancel_Check open"))); + status = 1; + } +#else + ACE_ERROR ((LM_INFO, + ACE_TEXT ("threads not supported on this platform\n"))); +#endif /* ACE_HAS_THREADS */ + ACE_END_TEST; + return status; +} |