void SB_Thread::Thread::suspend() { int lv_rc = pthread_sigmask(SIG_BLOCK, &gv_rs_sigset, NULL); SB_util_assert_ine(lv_rc, -1); gv_rs_queue.push(std::make_pair(static_cast<int>(RS_SUSPEND), this)); lv_rc = kill(SIGUSR1); SB_util_assert_ieq(lv_rc, 0); lv_rc = pthread_sigmask(SIG_UNBLOCK, &gv_rs_sigset, NULL); SB_util_assert_ine(lv_rc, -1); }
// // Purpose: emulate WAIT // // short XWAIT_com(short pv_mask, int pv_time, bool pv_residual) { const char *WHERE = "XWAIT"; SB_Int64_Type lv_curr_time; if (gv_ms_trace_wait) trace_where_printf(WHERE, "ENTER mask=%d(0x%x), time=%d\n", pv_mask, pv_mask, pv_time); if (!gv_ms_calls_ok) { ms_err_rtn_msg(WHERE, "msg_init() not called or shutdown", XZFIL_ERR_INVALIDSTATE); return 0; } // wait order LCAN, LDONE, LTMF, LREQ SB_util_assert_ige(pv_time, -2); // sw fault if (!pv_residual) SB_util_assert_ine(pv_time, 0); // sw fault int lv_events; long lv_to; bool lv_first; SB_Ms_Event_Mgr *lp_mgr = gv_ms_event_mgr.get_mgr(&lv_first); // If first time, set LREQ. // This is in case something was received before XWAIT called. // The application may see spurious LREQ. if (lv_first) { lp_mgr->set_event(LREQ, NULL); if (gv_ms_trace_wait) trace_where_printf(WHERE, "setting LREQ\n"); } #ifdef USE_EVENT_REG if (gv_ms_event_wait_abort) { if (pv_mask & LREQ) { if (!lp_mgr->register_event_check(LREQ)) { char *lp_str = "XWAIT called with LREQ without proc_event_register(LREQ)\n"; if (gv_ms_trace_wait) trace_where_printf(WHERE, lp_str); fprintf(stderr, lp_str); SB_util_assert_bt(lp_mgr->register_event_check(LREQ)); } } if (pv_mask & LDONE) { if (!lp_mgr->register_event_check(LDONE)) { char *lp_str = "XWAIT called with LDONE without proc_event_register(LDONE)\n"; if (gv_ms_trace_wait) trace_where_printf(WHERE, lp_str); fprintf(stderr, lp_str); SB_util_assert_bt(lp_mgr->register_event_check(LDONE)); } } } #endif // USE_EVENT_REG // lv_curr_time contains cached current time // so that getting the current-time is minimized lp_mgr->set_wait_start_time(pv_time, &lv_curr_time); lv_to = lp_mgr->get_wait_time_start(pv_time); bool lv_check = (lv_to == -2); lv_first = true; do { lv_events = lp_mgr->get_event(pv_mask); if (lv_events) break; if (lv_check) break; if (lp_mgr->get_timedout(&lv_curr_time)) break; if (lv_first) lv_first = false; else lv_to = lp_mgr->get_wait_time_rem(lv_curr_time); lp_mgr->wait(lv_to); lv_curr_time = 0; } while (!lv_events); if (pv_residual) lp_mgr->set_wait_time(pv_time); if (gv_ms_trace_wait) trace_where_printf(WHERE, "EXIT events=%d(0x%x)\n", lv_events, lv_events); return static_cast<short>(lv_events); }