//============================================================================= /** * @file Task_Group_Test.cpp * * This test program illustrates the logic of the grp_id handling * mechanism in and the . * Partially reuses test submitted by Paxton Mason in Bugzilla #2366 * * @author Martin Corino */ //============================================================================= #include "test_config.h" #include "ace/Atomic_Op.h" #include "ace/Task.h" #include "ace/OS_NS_unistd.h" #if defined (ACE_HAS_THREADS) const int MAX_GROUP_THREADS = ACE_MAX_THREADS * 2; static ACE_Atomic_Op run_count (0); class Waiter_Task : public ACE_Task_Base { public: Waiter_Task (ACE_Thread_Manager* tm = 0) : ACE_Task_Base (tm) {} int svc() override; }; int Waiter_Task::svc() { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t|grp_id=%d) waiting for thread cancellation.\n"), this->grp_id ())); run_count++; // wait until canceled while (!ACE_Task_Base::thr_mgr ()->testcancel (ACE_OS::thr_self ())) ACE_OS::sleep (0); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t|grp_id=%d) thread cancelled.\n"), this->grp_id ())); run_count--; return 0; } #endif /* ACE_HAS_THREADS */ int run_main (int, ACE_TCHAR *[]) { ACE_START_TEST (ACE_TEXT ("Task_Group_Test")); #if defined (ACE_HAS_THREADS) ACE_thread_t thread_list[MAX_GROUP_THREADS] = {0}; int group_id = -1; Waiter_Task waiter_task (ACE_Thread_Manager::instance ()); // activate a single thread waiter_task.activate (THR_NEW_LWP | THR_DETACHED, 1); // get the assigned grp_id group_id = waiter_task.grp_id (); // attempt to add a thread -> this should fail without force_activate if (waiter_task.activate (THR_NEW_LWP | THR_DETACHED, 1) != 1) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("ACE_Task_Base::activate should have failed to add new thread."))); } // force addition of new thread if (waiter_task.activate (THR_NEW_LWP | THR_DETACHED, 1, 1) != 0) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("ACE_Task_Base::activate should have succeeded to force addition of new thread."))); } // force addition of new thread ignoring specific group id if (waiter_task.activate (THR_NEW_LWP | THR_DETACHED, 1, 1, ACE_DEFAULT_THREAD_PRIORITY, group_id+1) != 0) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("ACE_Task_Base::activate should have succeeded to force addition of new thread."))); } // we should now have 3 threads in group 'group_id' if (waiter_task.thr_mgr ()->thread_grp_list (group_id, &thread_list[0], MAX_GROUP_THREADS) != 3) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("Should have found 3 threads in group %d."), group_id)); } // cancel all threads waiter_task.thr_mgr ()->cancel_all (); // wait for threads to exit cleanly while (waiter_task.thr_mgr ()->num_threads_in_task (&waiter_task) > 0) ACE_OS::sleep (0); // restart 2 threads reusing the group id if (waiter_task.activate (THR_NEW_LWP | THR_DETACHED, 2) != 0) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("ACE_Task_Base::activate should have succeeded to add new threads."))); } // attempt to add a thread -> this should fail without force_activate if (waiter_task.activate (THR_NEW_LWP | THR_DETACHED, 1) != 1) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("ACE_Task_Base::activate should have failed to add new thread."))); } // force addition of new thread if (waiter_task.activate (THR_NEW_LWP | THR_DETACHED, 1, 1) != 0) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("ACE_Task_Base::activate should have succeeded to force addition of new thread."))); } // force addition of new thread ignoring specific group id if (waiter_task.activate (THR_NEW_LWP | THR_DETACHED, 1, 1, ACE_DEFAULT_THREAD_PRIORITY, group_id+1) != 0) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("ACE_Task_Base::activate should have succeeded to force addition of new thread."))); } // we should now have 4 threads in group 'group_id' if (waiter_task.thr_mgr ()->thread_grp_list (group_id, &thread_list[0], MAX_GROUP_THREADS) != 4) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("Should have found 4 threads in group %d."), group_id)); } // wait till the threads actually started up while (run_count != 4) ACE_OS::sleep (0); // change the group id of all threads of the task group_id += 1; waiter_task.grp_id (group_id); // we should still have 4 threads in group with new 'group_id' if (waiter_task.thr_mgr ()->thread_grp_list (group_id, &thread_list[0], MAX_GROUP_THREADS) != 4) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("Should have found 4 threads in group %d."), group_id)); } // cancel all threads waiter_task.thr_mgr ()->cancel_all (); // wait for threads to exit cleanly while (waiter_task.thr_mgr ()->num_threads_in_task (&waiter_task) > 0) ACE_OS::sleep (0); // restart 3 threads using explicit new group id group_id = 33; if (waiter_task.activate (THR_NEW_LWP | THR_DETACHED, 3, 0, ACE_DEFAULT_THREAD_PRIORITY, group_id) != 0) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("ACE_Task_Base::activate should have succeeded to add new threads."))); } // attempt to add a thread -> this should fail without force_activate if (waiter_task.activate (THR_NEW_LWP | THR_DETACHED, 1) != 1) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("ACE_Task_Base::activate should have failed to add new thread."))); } // force addition of new thread if (waiter_task.activate (THR_NEW_LWP | THR_DETACHED, 1, 1) != 0) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("ACE_Task_Base::activate should have succeeded to force addition of new thread."))); } // force addition of new thread ignoring specific group id if (waiter_task.activate (THR_NEW_LWP | THR_DETACHED, 1, 1, ACE_DEFAULT_THREAD_PRIORITY, group_id+1) != 0) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("ACE_Task_Base::activate should have succeeded to force addition of new thread."))); } // we should now have 5 threads in group 'group_id' if (waiter_task.thr_mgr ()->thread_grp_list (group_id, &thread_list[0], MAX_GROUP_THREADS) != 5) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("Should have found 5 threads in group %d."), group_id)); } // cancel all threads waiter_task.thr_mgr ()->cancel_all (); // wait for threads to exit cleanly while (waiter_task.thr_mgr ()->num_threads_in_task (&waiter_task) > 0) ACE_OS::sleep (0); #else ACE_ERROR ((LM_INFO, ACE_TEXT ("threads not supported on this platform\n"))); #endif /* ACE_HAS_THREADS */ ACE_END_TEST; return 0; }