| 36 | } |
| 37 | |
| 38 | void DispatchService::shutdown(bool immediate, EventQueue* const pending) |
| 39 | { |
| 40 | ACE_Guard<ACE_Thread_Mutex> guard(mutex_); |
| 41 | allow_dispatch_ = false; |
| 42 | stop_when_empty_ = true; |
| 43 | running_ = running_ && !immediate; // && with existing state in case shutdown has already been called |
| 44 | cv_.notify_all(); |
| 45 | |
| 46 | if (pool_.contains(ACE_Thread::self())) { |
| 47 | if (log_level >= LogLevel::Error) { |
| 48 | ACE_ERROR((LM_ERROR, "(%P|%t) ERROR :: DispatchService::shutdown: Contained Thread Attempting To Call Shutdown.\n")); |
| 49 | } |
| 50 | if (pending) { |
| 51 | pending->clear(); |
| 52 | } |
| 53 | return; |
| 54 | } |
| 55 | |
| 56 | while (running_threads_) { |
| 57 | cv_.wait(TheServiceParticipant->get_thread_status_manager()); |
| 58 | } |
| 59 | |
| 60 | if (pending) { |
| 61 | pending->clear(); |
| 62 | pending->swap(event_queue_); |
| 63 | const TimerQueueMap& cmap = timer_queue_map_; |
| 64 | for (TimerQueueMap::const_iterator it = cmap.begin(), limit = cmap.end(); it != limit; ++it) { |
| 65 | pending->push_back(it->second.first); |
| 66 | } |
| 67 | } else { |
| 68 | event_queue_.clear(); |
| 69 | } |
| 70 | timer_queue_map_.clear(); |
| 71 | timer_id_map_.clear(); |
| 72 | } |
| 73 | |
| 74 | DispatchService::DispatchStatus DispatchService::dispatch(FunPtr fun, void* arg) |
| 75 | { |