lagopus_result_t dp_thread_stop(lagopus_thread_t *threadptr, bool *runptr) { bool is_canceled = false; lagopus_result_t ret; ret = lagopus_thread_is_canceled(threadptr, &is_canceled); if (ret == LAGOPUS_RESULT_OK && is_canceled == false) { ret = lagopus_thread_cancel(threadptr); } *runptr = false; return ret; }
static inline lagopus_result_t s_stop_module(a_module *mptr) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; if (mptr != NULL) { if (mptr->m_status == MODULE_STATE_STARTED) { if (mptr->m_stop_proc != NULL) { ret = (mptr->m_stop_proc)(); } else { if (mptr->m_thdptr != NULL) { ret = lagopus_thread_cancel(mptr->m_thdptr); } else { /* * Means this module doesn't support any stop/cancel * methods. Do nothing. */ return LAGOPUS_RESULT_OK; } } if (ret == LAGOPUS_RESULT_OK) { if (mptr->m_thdptr == NULL) { /* * Means that this module doesn't have any lagopus'd threads * nor pthreads. Just change the state to shutdwon. */ mptr->m_status = MODULE_STATE_SHUTDOWN; } else { mptr->m_status = MODULE_STATE_CANCELLING; } } } else { if (mptr->m_status == MODULE_STATE_CANCELLING || mptr->m_status == MODULE_STATE_SHUTDOWN || mptr->m_status == MODULE_STATE_STOPPED) { ret = LAGOPUS_RESULT_OK; } else { ret = LAGOPUS_RESULT_INVALID_STATE_TRANSITION; } } } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }
static inline bool s_check_cancel(lagopus_thread_t *thd_ptr, lagopus_result_t require_ret) { bool result = false; lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; ret = lagopus_thread_cancel(thd_ptr); if (ret != require_ret) { s_check_is_canceled(thd_ptr, LAGOPUS_RESULT_OK, true); lagopus_perror(ret); TEST_FAIL_MESSAGE("cancel failed"); result = false; } else { result = true; } return result; }
static lagopus_result_t dummy_module_stop(void) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; lagopus_msg_debug(5, "called.\n"); if (s_thd != NULL) { s_lock(); { if (s_is_initialized == true) { ret = lagopus_thread_cancel(&s_thd); } else { ret = LAGOPUS_RESULT_INVALID_STATE_TRANSITION; } } s_unlock(); } else { ret = LAGOPUS_RESULT_INVALID_OBJECT; } return ret; }
static inline lagopus_result_t snmpmgr_stop_thread(void) { return lagopus_thread_cancel(&snmpmgr); }
int main(int argc, const char *const argv[]) { int ret = 1; lagopus_result_t r; null_thread_t nt; size_t i; a_obj_t o; (void)argc; (void)argv; o = a_obj_create(); if (o == NULL) { goto done; } for (i = 0; i < NTHDS; i++) { nt = &s_thds[i]; if ((r = s_create(&nt, o)) != LAGOPUS_RESULT_OK) { lagopus_perror(r); goto done; } } for (i = 0; i < NTHDS; i++) { nt = &s_thds[i]; if ((r = lagopus_thread_start((lagopus_thread_t *)&nt, false)) != LAGOPUS_RESULT_OK) { lagopus_perror(r); goto done; } } sleep(1); /* * Cancel all the thread. */ for (i = 0; i < NTHDS; i++) { nt = &s_thds[i]; if ((r = lagopus_thread_cancel((lagopus_thread_t *)&nt)) != LAGOPUS_RESULT_OK) { lagopus_perror(r); goto done; } } /* * Destroy all the thread. If any deadlocks occur, we failed. */ for (i = 0; i < NTHDS; i++) { nt = &s_thds[i]; lagopus_thread_destroy((lagopus_thread_t *)&nt); } /* * And destroy a_obj. If a deadlock occurs, we failed. */ a_obj_destroy(o); ret = 0; done: return ret; }
void test_thread_cancel_params(void) { TEST_ASSERT_EQUAL_MESSAGE(LAGOPUS_RESULT_INVALID_ARGS, lagopus_thread_cancel(NULL), "thread is NULL"); }
int main(int argc, char const *const argv[]) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; int i; int n = 10000; lagopus_thread_t thread = NULL; pthread_t tid = LAGOPUS_INVALID_THREAD; lagopus_log_set_debug_level(10); if (argc > 1) { int tmp; if (lagopus_str_parse_int32(argv[1], &tmp) == LAGOPUS_RESULT_OK && tmp > 0) { n = tmp; } } /* create, start, wait, destroy */ for (i = 0; i < n; i++) { thread = NULL; if ((ret = lagopus_thread_create( (lagopus_thread_t *)&thread, (lagopus_thread_main_proc_t)s_main_proc, (lagopus_thread_finalize_proc_t)s_finalize_proc, (lagopus_thread_freeup_proc_t)s_freeup_proc, (const char *) "thread", (void *) NULL)) != LAGOPUS_RESULT_OK) { lagopus_perror(ret); lagopus_exit_fatal("Can't create a thread.\n"); } else { fprintf(stderr, "create a thread [%d]\n", i); if ((ret = lagopus_thread_get_pthread_id(&thread, &tid)) != LAGOPUS_RESULT_NOT_STARTED) { lagopus_perror(ret); goto done; } } if ((ret = lagopus_thread_start(&thread, false)) != LAGOPUS_RESULT_OK) { lagopus_perror(ret); lagopus_exit_fatal("Can't start the thread.\n"); } else { ret = lagopus_thread_get_pthread_id(&thread, &tid); if (ret == LAGOPUS_RESULT_OK || ret == LAGOPUS_RESULT_ALREADY_HALTED) { fprintf(stderr, " start thread: %lu\n", tid); } else { lagopus_perror(ret); goto done; } } s_check_cancelled(&thread, false); if ((ret = lagopus_thread_wait(&thread, 1000LL * 1000LL * 1000LL)) != LAGOPUS_RESULT_OK) { lagopus_perror(ret); lagopus_msg_error("Can't wait the thread.\n"); } else { if ((ret = lagopus_thread_get_pthread_id(&thread, &tid)) == LAGOPUS_RESULT_OK) { lagopus_msg_error( "Thread has been completed, but I can get thread ID, %lu\n", tid); } else if (ret != LAGOPUS_RESULT_ALREADY_HALTED) { lagopus_perror(ret); goto done; } } s_check_cancelled(&thread, false); lagopus_thread_destroy(&thread); fprintf(stderr, "destroy the thread [%d]\n", i); fprintf(stderr, "\n"); } /* create, start, cancel, destroy */ for (i = 0; i < n; i++) { thread = NULL; if ((ret = lagopus_thread_create( (lagopus_thread_t *)&thread, (lagopus_thread_main_proc_t)s_main_proc_with_sleep, (lagopus_thread_finalize_proc_t)s_finalize_proc, (lagopus_thread_freeup_proc_t)s_freeup_proc, (const char *) "thread", (void *) NULL)) != LAGOPUS_RESULT_OK) { lagopus_perror(ret); lagopus_exit_fatal("Can't create a thread.\n"); } else { fprintf(stderr, "create a thread [%d]\n", i); if ((ret = lagopus_thread_get_pthread_id(&thread, &tid)) != LAGOPUS_RESULT_NOT_STARTED) { lagopus_perror(ret); goto done; } } if ((ret = lagopus_thread_start(&thread, false)) != LAGOPUS_RESULT_OK) { lagopus_perror(ret); lagopus_exit_fatal("Can't start the thread.\n"); } else { ret = lagopus_thread_get_pthread_id(&thread, &tid); if (ret == LAGOPUS_RESULT_OK || ret == LAGOPUS_RESULT_ALREADY_HALTED) { fprintf(stderr, " start thread: %lu\n", tid); } else { lagopus_perror(ret); goto done; } } s_check_cancelled(&thread, false); if ((ret = lagopus_thread_cancel(&thread)) != LAGOPUS_RESULT_OK) { lagopus_perror(ret); lagopus_msg_error("Can't cancel the thread.\n"); } else { if ((ret = lagopus_thread_get_pthread_id(&thread, &tid)) == LAGOPUS_RESULT_OK) { lagopus_msg_error( "Thread has been canceled, but I can get thread ID, %lu\n", tid); } else if (ret != LAGOPUS_RESULT_NOT_STARTED && ret != LAGOPUS_RESULT_ALREADY_HALTED) { lagopus_perror(ret); goto done; } } s_check_cancelled(&thread, true); lagopus_thread_destroy(&thread); fprintf(stderr, "destroy the thread [%d]\n", i); fprintf(stderr, "\n"); } /* create, start, destroy */ for (i = 0; i < n; i++) { thread = NULL; if ((ret = lagopus_thread_create( (lagopus_thread_t *)&thread, (lagopus_thread_main_proc_t)s_main_proc_with_sleep, (lagopus_thread_finalize_proc_t)s_finalize_proc, (lagopus_thread_freeup_proc_t)s_freeup_proc, (const char *) "thread", (void *) NULL)) != LAGOPUS_RESULT_OK) { lagopus_perror(ret); lagopus_exit_fatal("Can't create a thread.\n"); } else { fprintf(stderr, "create a thread [%d]\n", i); if ((ret = lagopus_thread_get_pthread_id(&thread, &tid)) != LAGOPUS_RESULT_NOT_STARTED) { lagopus_perror(ret); goto done; } } if ((ret = lagopus_thread_start(&thread, false)) != LAGOPUS_RESULT_OK) { lagopus_perror(ret); lagopus_exit_fatal("Can't start the thread.\n"); } else { ret = lagopus_thread_get_pthread_id(&thread, &tid); if (ret == LAGOPUS_RESULT_OK || ret == LAGOPUS_RESULT_ALREADY_HALTED) { fprintf(stderr, " start thread: %lu\n", tid); } else { lagopus_perror(ret); goto done; } } lagopus_thread_destroy(&thread); fprintf(stderr, "destroy the thread [%d]\n", i); fprintf(stderr, "\n"); } done: return (ret == LAGOPUS_RESULT_OK) ? 0 : 1; }
int main(int argc, const char *const argv[]) { test_thread_record ttr; test_thread_t tt; bool is_canceled; int ret = 1; (void)argc; (void)argv; fprintf(stderr, "Pthread wrapper check: start\n\n"); /* * Heap object */ fprintf(stderr, "Heap object, regular: start\n"); tt = NULL; if (test_thread_create(&tt, 100) != true) { lagopus_exit_fatal("Can't create a test thread object.\n"); } if (lagopus_thread_start((lagopus_thread_t *)&tt, false) != LAGOPUS_RESULT_OK) { lagopus_exit_fatal("Can't start a thread.\n"); } lagopus_chrono_nanosleep(5LL * 1000LL * 1000LL * 1000LL, NULL); test_thread_request_stop(tt); if (lagopus_thread_wait((lagopus_thread_t *)&tt, -1) != LAGOPUS_RESULT_OK) { lagopus_exit_fatal("Can't wait the thread.\n"); } lagopus_thread_destroy((lagopus_thread_t *)&tt); fprintf(stderr, "Heap object, regular: end\n\n"); /* * Stack object */ fprintf(stderr, "Stack object, regular: start\n"); tt = &ttr; if (test_thread_create(&tt, 100) != true) { lagopus_exit_fatal("Can't initialize a test thread object.\n"); } if (lagopus_thread_start((lagopus_thread_t *)&tt, false) != LAGOPUS_RESULT_OK) { lagopus_exit_fatal("Can't start a thread.\n"); } lagopus_chrono_nanosleep(5LL * 1000LL * 1000LL * 1000LL, NULL); test_thread_request_stop(tt); if (lagopus_thread_wait((lagopus_thread_t *)&tt, -1) != LAGOPUS_RESULT_OK) { lagopus_exit_fatal("Can't wait the thread.\n"); } lagopus_thread_destroy((lagopus_thread_t *)&tt); fprintf(stderr, "Stack object, regular: end\n\n"); /* * Cancel */ fprintf(stderr, "Stack object, cancel: start\n"); tt = &ttr; if (test_thread_create(&tt, 100) != true) { lagopus_exit_fatal("Can't initialize a test thread object.\n"); } if (lagopus_thread_start((lagopus_thread_t *)&tt, false) != LAGOPUS_RESULT_OK) { lagopus_exit_fatal("Can't start a thread.\n"); } lagopus_chrono_nanosleep(5LL * 1000LL * 1000LL * 1000LL, NULL); if (lagopus_thread_cancel((lagopus_thread_t *)&tt) != LAGOPUS_RESULT_OK) { lagopus_exit_fatal("Can't cancel the thread.\n"); } if (lagopus_thread_wait((lagopus_thread_t *)&tt, -1) != LAGOPUS_RESULT_OK) { lagopus_exit_fatal("Can't wait the thread.\n"); } if (lagopus_thread_is_canceled((lagopus_thread_t *)&tt, &is_canceled) != LAGOPUS_RESULT_OK) { lagopus_exit_fatal("The returned value must be \"canceled\".\n"); } lagopus_thread_destroy((lagopus_thread_t *)&tt); fprintf(stderr, "Stack object, cancel: end\n\n"); /* * Heap object auto deletion */ fprintf(stderr, "Heap object, auto deletion: start\n"); s_is_deleted = false; tt = NULL; if (test_thread_create(&tt, 100) != true) { lagopus_exit_fatal("Can't initialize a test thread object.\n"); } if (lagopus_thread_start((lagopus_thread_t *)&tt, true) != LAGOPUS_RESULT_OK) { lagopus_exit_fatal("Can't start a thread.\n"); } lagopus_chrono_nanosleep(5LL * 1000LL * 1000LL * 1000LL, NULL); test_thread_request_stop(tt); lagopus_chrono_nanosleep(2LL * 1000LL * 1000LL * 1000LL, NULL); if (s_is_deleted == false) { lagopus_exit_fatal("The thread object must be freed and " "the flag must be true.\n"); } fprintf(stderr, "Heap object, auto deletion: end\n\n"); /* * Stack object auto deletion */ fprintf(stderr, "Stack object, auto deletion: start\n"); s_is_deleted = false; tt = &ttr; if (test_thread_create(&tt, 100) != true) { lagopus_exit_fatal("Can't initialize a test thread object.\n"); } if (lagopus_thread_start((lagopus_thread_t *)&tt, true) != LAGOPUS_RESULT_OK) { lagopus_exit_fatal("Can't start a thread.\n"); } lagopus_chrono_nanosleep(5LL * 1000LL * 1000LL * 1000LL, NULL); test_thread_request_stop(tt); lagopus_chrono_nanosleep(2LL * 1000LL * 1000LL * 1000LL, NULL); if (s_is_deleted == false) { lagopus_exit_fatal("The thread object must be freed and " "the flag must be true.\n"); } fprintf(stderr, "Stack object, auto deletion: end\n\n"); /* * Heap object cancel, auto deletion */ fprintf(stderr, "Heap object, cancel, auto deletion: start\n"); s_is_deleted = false; tt = NULL; if (test_thread_create(&tt, 100) != true) { lagopus_exit_fatal("Can't initialize a test thread object.\n"); } if (lagopus_thread_start((lagopus_thread_t *)&tt, true) != LAGOPUS_RESULT_OK) { lagopus_exit_fatal("Can't start a thread.\n"); } lagopus_chrono_nanosleep(5LL * 1000LL * 1000LL * 1000LL, NULL); if (lagopus_thread_cancel((lagopus_thread_t *)&tt) != LAGOPUS_RESULT_OK) { lagopus_exit_fatal("Can't cancel the thread.\n"); } lagopus_chrono_nanosleep(2LL * 1000LL * 1000LL * 1000LL, NULL); if (s_is_deleted == false) { lagopus_exit_fatal("The thread object must be freed and " "the flag must be true.\n"); } fprintf(stderr, "Heap object, cancel, auto deletion: end\n\n"); /* * Stack object cancel, auto deletion */ fprintf(stderr, "Stack object, cancel, auto deletion: start\n"); s_is_deleted = false; tt = &ttr; if (test_thread_create(&tt, 100) != true) { lagopus_exit_fatal("Can't initialize a test thread object.\n"); } if (lagopus_thread_start((lagopus_thread_t *)&tt, true) != LAGOPUS_RESULT_OK) { lagopus_exit_fatal("Can't start a thread.\n"); } lagopus_chrono_nanosleep(5LL * 1000LL * 1000LL * 1000LL, NULL); if (lagopus_thread_cancel((lagopus_thread_t *)&tt) != LAGOPUS_RESULT_OK) { lagopus_exit_fatal("Can't cancel the thread.\n"); } lagopus_chrono_nanosleep(2LL * 1000LL * 1000LL * 1000LL, NULL); if (s_is_deleted == false) { lagopus_exit_fatal("The thread object must be freed and " "the flag must be true.\n"); } fprintf(stderr, "Stack object, cancel, auto deletion: end\n\n"); /* * Timed wait */ fprintf(stderr, "Timed wait: start\n"); tt = &ttr; if (test_thread_create(&tt, 100) != true) { lagopus_exit_fatal("Can't initialize a test thread object.\n"); } if (lagopus_thread_start((lagopus_thread_t *)&tt, false) != LAGOPUS_RESULT_OK) { lagopus_exit_fatal("Can't start a thread.\n"); } if (lagopus_thread_wait((lagopus_thread_t *)&tt, 5LL * 1000LL * 1000LL * 1000LL) != LAGOPUS_RESULT_TIMEDOUT) { lagopus_exit_fatal("Must be timed out.\n"); } test_thread_request_stop(tt); if (lagopus_thread_wait((lagopus_thread_t *)&tt, -1) != LAGOPUS_RESULT_OK) { lagopus_exit_fatal("Can't wait the thread.\n"); } lagopus_thread_destroy((lagopus_thread_t *)&tt); fprintf(stderr, "Timed wait: end\n\n"); /* * Force destroy */ fprintf(stderr, "Force destroy: start\n"); s_is_deleted = false; tt = NULL; if (test_thread_create(&tt, 100) != true) { lagopus_exit_fatal("Can't create a test thread object.\n"); } if (lagopus_thread_start((lagopus_thread_t *)&tt, false) != LAGOPUS_RESULT_OK) { lagopus_exit_fatal("Can't start a thread.\n"); } lagopus_thread_destroy((lagopus_thread_t *)&tt); if (s_is_deleted == false) { lagopus_exit_fatal("The thread object must be freed and " "the flag must be true.\n"); } fprintf(stderr, "Force destroy: end\n\n"); /* * Force destroy, not started */ fprintf(stderr, "Force destroy, not started: start\n"); s_is_deleted = false; tt = NULL; if (test_thread_create(&tt, 100) != true) { lagopus_exit_fatal("Can't create a test thread object.\n"); } lagopus_thread_destroy((lagopus_thread_t *)&tt); if (s_is_deleted == false) { lagopus_exit_fatal("The thread object must be freed and " "the flag must be true.\n"); } fprintf(stderr, "Force destroy, not started: end\n\n"); ret = 0; fprintf(stderr, "Pthread wrapper check: end\n"); return ret; }