| 329 | } |
| 330 | |
| 331 | void ReactorTask::stop() |
| 332 | { |
| 333 | ACE_Reactor* reactor = 0; |
| 334 | { |
| 335 | GuardType guard(lock_); |
| 336 | |
| 337 | if (state_ == STATE_UNINITIALIZED || state_ == STATE_SHUT_DOWN) { |
| 338 | // We are already "stopped". Just return. |
| 339 | return; |
| 340 | } |
| 341 | |
| 342 | state_ = STATE_SHUT_DOWN; |
| 343 | |
| 344 | #if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || defined (ACE_HAS_AIO_CALLS) |
| 345 | // Remove the proactor handler so the reactor stops forwarding messages. |
| 346 | if (proactor_) { |
| 347 | reactor_->remove_handler( |
| 348 | proactor_->implementation()->get_handle(), |
| 349 | ACE_Event_Handler::DONT_CALL); |
| 350 | } |
| 351 | #endif |
| 352 | reactor = reactor_; |
| 353 | } |
| 354 | |
| 355 | if (reactor) { |
| 356 | // We can't hold the lock when we call this, because the reactor threads may need to |
| 357 | // access the lock as part of normal execution before they return to the reactor control loop |
| 358 | reactor->end_reactor_event_loop(); |
| 359 | } |
| 360 | |
| 361 | reactor_wrapper_.close(); |
| 362 | |
| 363 | // In the future, we will likely want to replace this assert with a new "SHUTTING_DOWN" state |
| 364 | // which can be used to delay any potential new calls to open_reactor_task() |
| 365 | OPENDDS_ASSERT(state_ == STATE_SHUT_DOWN); |
| 366 | |
| 367 | // Let's wait for the reactor task's thread to complete before we |
| 368 | // leave this stop method. |
| 369 | ThreadStatusManager::Sleeper sleeper(thread_status_manager_); |
| 370 | wait(); |
| 371 | |
| 372 | // Reset the thread manager in case it goes away before the next open. |
| 373 | thr_mgr(0); |
| 374 | } |
| 375 | |
| 376 | bool ReactorTask::on_thread() const |
| 377 | { |
nothing calls this directly
no test coverage detected