Dev_Poll_Reactor.cpp

Go to the documentation of this file.
00001 // Dev_Poll_Reactor.cpp,v 4.51 2006/05/11 11:15:07 jwillemsen Exp
00002 
00003 #include "ace/OS_NS_errno.h"
00004 #include "ace/Dev_Poll_Reactor.h"
00005 #include "ace/Signal.h"
00006 
00007 ACE_RCSID (ace,
00008            Dev_Poll_Reactor,
00009            "Dev_Poll_Reactor.cpp,v 4.51 2006/05/11 11:15:07 jwillemsen Exp")
00010 
00011 #if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL)
00012 
00013 # include "ace/OS_NS_unistd.h"
00014 # include "ace/OS_NS_fcntl.h"
00015 # include "ace/OS_NS_stropts.h"
00016 
00017 # if defined (ACE_HAS_EVENT_POLL) && defined (linux)
00018 #  include /**/ <sys/epoll.h>
00019 # elif defined (ACE_HAS_DEV_POLL)
00020 #    if defined (linux)
00021 #      include /**/ <linux/devpoll.h>
00022 #    else
00023 #      include /**/ <sys/devpoll.h>
00024 #    endif  /* linux */
00025 # endif  /* ACE_HAS_DEV_POLL */
00026 
00027 #if !defined (__ACE_INLINE__)
00028 # include "ace/Dev_Poll_Reactor.inl"
00029 #endif /* __ACE_INLINE__ */
00030 
00031 
00032 #include "ace/Handle_Set.h"
00033 #include "ace/Reactor.h"
00034 #include "ace/Timer_Heap.h"
00035 #include "ace/Timer_Queue.h"
00036 #include "ace/ACE.h"
00037 #include "ace/Reverse_Lock_T.h"
00038 #include "ace/Recursive_Thread_Mutex.h"
00039 #include "ace/Null_Mutex.h"
00040 #include "ace/os_include/os_poll.h"
00041 #include "ace/OS_NS_sys_mman.h"
00042 
00043 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00044 
00045 ACE_Dev_Poll_Reactor_Notify::ACE_Dev_Poll_Reactor_Notify (void)
00046   : dp_reactor_ (0)
00047   , notification_pipe_ ()
00048   , max_notify_iterations_ (-1)
00049 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
00050   , alloc_queue_ ()
00051   , notify_queue_ ()
00052   , free_queue_ ()
00053   , notify_queue_lock_ ()
00054 #endif  /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */
00055 {
00056 }
00057 
00058 int
00059 ACE_Dev_Poll_Reactor_Notify::open (ACE_Reactor_Impl *r,
00060                                    ACE_Timer_Queue * /* timer_queue */,
00061                                    int disable_notify_pipe)
00062 {
00063   ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::open");
00064 
00065   if (disable_notify_pipe == 0)
00066     {
00067       this->dp_reactor_ = dynamic_cast<ACE_Dev_Poll_Reactor *> (r);
00068 
00069       if (this->dp_reactor_ == 0)
00070         {
00071           errno = EINVAL;
00072           return -1;
00073         }
00074 
00075       if (this->notification_pipe_.open () == -1)
00076         return -1;
00077 
00078 #if defined (F_SETFD)
00079       // close-on-exec
00080       ACE_OS::fcntl (this->notification_pipe_.read_handle (), F_SETFD, 1);
00081       ACE_OS::fcntl (this->notification_pipe_.write_handle (), F_SETFD, 1);
00082 #endif /* F_SETFD */
00083 
00084 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
00085       ACE_Notification_Buffer *temp;
00086 
00087       ACE_NEW_RETURN (temp,
00088                       ACE_Notification_Buffer[ACE_REACTOR_NOTIFICATION_ARRAY_SIZE],
00089                       -1);
00090 
00091       if (this->alloc_queue_.enqueue_head (temp) == -1)
00092         return -1;
00093 
00094       for (size_t i = 0; i < ACE_REACTOR_NOTIFICATION_ARRAY_SIZE; ++i)
00095         if (free_queue_.enqueue_head (temp + i) == -1)
00096           return -1;
00097 
00098       if (ACE::set_flags (this->notification_pipe_.write_handle (),
00099                           ACE_NONBLOCK) == -1)
00100         return -1;
00101 #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */
00102 
00103       // Set the read handle into non-blocking mode since we need to
00104       // perform a "speculative" read when determining if their are
00105       // notifications to dispatch.
00106       if (ACE::set_flags (this->notification_pipe_.read_handle (),
00107                           ACE_NONBLOCK) == -1)
00108         return -1;
00109     }
00110 
00111   return 0;
00112 }
00113 
00114 int
00115 ACE_Dev_Poll_Reactor_Notify::close (void)
00116 {
00117   ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::close");
00118 
00119 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
00120   // Free up the dynamically allocated resources.
00121   ACE_Notification_Buffer **b;
00122 
00123   for (ACE_Unbounded_Queue_Iterator<ACE_Notification_Buffer *> alloc_iter (this->alloc_queue_);
00124        alloc_iter.next (b) != 0;
00125        alloc_iter.advance ())
00126     {
00127       delete [] *b;
00128       *b = 0;
00129     }
00130 
00131   this->alloc_queue_.reset ();
00132   this->notify_queue_.reset ();
00133   this->free_queue_.reset ();
00134 #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */
00135 
00136   return this->notification_pipe_.close ();
00137 }
00138 
00139 int
00140 ACE_Dev_Poll_Reactor_Notify::notify (ACE_Event_Handler *eh,
00141                                      ACE_Reactor_Mask mask,
00142                                      ACE_Time_Value *timeout)
00143 {
00144   ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::notify");
00145 
00146   // Just consider this method a "no-op" if there's no
00147   // ACE_Dev_Poll_Reactor configured.
00148   if (this->dp_reactor_ == 0)
00149     return 0;
00150 
00151   ACE_Notification_Buffer buffer (eh, mask);
00152 
00153 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
00154 
00155   ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, mon, this->notify_queue_lock_, -1);
00156 
00157   // Locate a free buffer in the queue. Enlarge the queue if needed.
00158   ACE_Notification_Buffer *temp = 0;
00159 
00160   if (free_queue_.dequeue_head (temp) == -1)
00161     {
00162       // Grow the queue of available buffers.
00163       ACE_Notification_Buffer *temp1;
00164 
00165       ACE_NEW_RETURN (temp1,
00166                       ACE_Notification_Buffer[ACE_REACTOR_NOTIFICATION_ARRAY_SIZE],
00167                       -1);
00168 
00169       if (this->alloc_queue_.enqueue_head (temp1) == -1)
00170         return -1;
00171 
00172       // Start at 1 and enqueue only
00173       // (ACE_REACTOR_NOTIFICATION_ARRAY_SIZE - 1) elements since
00174       // the first one will be used right now.
00175       for (size_t i = 1;
00176            i < ACE_REACTOR_NOTIFICATION_ARRAY_SIZE;
00177            ++i)
00178         this->free_queue_.enqueue_head (temp1 + i);
00179 
00180       temp = temp1;
00181     }
00182 
00183   ACE_ASSERT (temp != 0);
00184   *temp = buffer;
00185 
00186   ACE_Dev_Poll_Handler_Guard eh_guard (eh);
00187 
00188   if (notify_queue_.enqueue_tail (temp) == -1)
00189     return -1;
00190 
00191   // Now pop the pipe to force the callback for dispatching when ready. If
00192   // the send fails due to a full pipe, don't fail - assume the already-sent
00193   // pipe bytes will cause the entire notification queue to be processed.
00194   ssize_t n = ACE::send (this->notification_pipe_.write_handle (),
00195                          (char *) &buffer,
00196                          1,             // Only need one byte to pop the pipe
00197                          timeout);
00198   if (n == -1 && (errno != ETIME && errno != EAGAIN))
00199     return -1;
00200 
00201   // Since the notify is queued (and maybe already delivered by now)
00202   // we can simply release the guard. The dispatch of this notification
00203   // will decrement the reference count.
00204   eh_guard.release ();
00205 
00206   return 0;
00207 #else
00208 
00209   ACE_Dev_Poll_Handler_Guard eh_guard (eh);
00210 
00211   ssize_t n = ACE::send (this->notification_pipe_.write_handle (),
00212                          (char *) &buffer,
00213                          sizeof buffer,
00214                          timeout);
00215   if (n == -1)
00216     return -1;
00217 
00218   eh_guard.release ();
00219 
00220   return 0;
00221 #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */
00222 }
00223 
00224 int
00225 ACE_Dev_Poll_Reactor_Notify::dispatch_notifications (
00226   int & /* number_of_active_handles */,
00227   ACE_Handle_Set & /* rd_mask */)
00228 {
00229   ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::dispatch_notifications");
00230 
00231   // This method is unimplemented in the ACE_Dev_Poll_Reactor.
00232   // Instead, the notification handler is invoked as part of the IO
00233   // event set.  Doing so alters the some documented semantics that
00234   // state that the notifications are handled before IO events.
00235   // Enforcing such semantics does not appear to be beneficial, and
00236   // also serves to slow down event dispatching particularly with this
00237   // ACE_Dev_Poll_Reactor.
00238 
00239 #if 0
00240   ACE_HANDLE read_handle =
00241     this->notification_pipe_.read_handle ();
00242 
00243   // Note that we do not check if the handle has received any events.
00244   // Instead a non-blocking "speculative" read is performed.  If the
00245   // read returns with errno == EWOULDBLOCK then no notifications are
00246   // dispatched.  See ACE_Dev_Poll_Reactor_Notify::read_notify_pipe()
00247   // for details.
00248   if (read_handle != ACE_INVALID_HANDLE)
00249     {
00250       --number_of_active_handles;
00251 
00252       return this->handle_input (read_handle);
00253     }
00254   else
00255     return 0;
00256 #else
00257   ACE_NOTSUP_RETURN (-1);
00258 #endif  /* 0 */
00259 }
00260 
00261 int
00262 ACE_Dev_Poll_Reactor_Notify::read_notify_pipe (ACE_HANDLE handle,
00263                                                ACE_Notification_Buffer &buffer)
00264 {
00265   ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::read_notify_pipe");
00266 
00267   // This is a (non-blocking) "speculative" read, i.e., we attempt to
00268   // read even if no event was polled on the read handle.  A
00269   // speculative read is necessary since notifications must be
00270   // dispatched before IO events.  We can avoid the speculative read
00271   // by "walking" the array of pollfd structures returned from
00272   // `/dev/poll' or `/dev/epoll' but that is potentially much more
00273   // expensive than simply checking for an EWOULDBLOCK.
00274   size_t to_read;
00275   char *read_p;
00276   bool have_one = false;
00277 
00278 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
00279   // For the queued case, we'll try to read one byte (since that's what
00280   // the notify() tried to put in) but we don't need it - notifications can
00281   // be queued even if the pipe fills, so there may be more notifications
00282   // queued than there are bytes in the pipe.
00283   char b;
00284   read_p = &b;
00285   to_read = 1;
00286   ACE_Notification_Buffer *temp;
00287 
00288   // New scope to release the guard before trying the recv().
00289   {
00290     ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, mon, this->notify_queue_lock_, -1);
00291 
00292     if (notify_queue_.is_empty ())
00293       return 0;
00294     else if (notify_queue_.dequeue_head (temp) == -1)
00295       ACE_ERROR_RETURN ((LM_ERROR,
00296                          ACE_LIB_TEXT ("%p\n"),
00297                          ACE_LIB_TEXT ("read_notify_pipe: dequeue_head")),
00298                         -1);
00299     buffer = *temp;
00300     have_one = true;
00301     if (free_queue_.enqueue_head (temp) == -1)
00302       ACE_ERROR ((LM_ERROR,
00303                   ACE_LIB_TEXT ("%p\n"),
00304                   ACE_LIB_TEXT ("read_notify_pipe: enqueue_head")));
00305   }
00306 
00307 #else
00308   to_read = sizeof buffer;
00309   read_p = (char *)&buffer;
00310 #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */
00311 
00312   ssize_t n = ACE::recv (handle, read_p, to_read);
00313 
00314   if (n > 0)
00315     {
00316       // Check to see if we've got a short read.
00317       if (static_cast<size_t>(n) != to_read)
00318         {
00319           size_t remainder = to_read - n;
00320 
00321           // If so, try to recover by reading the remainder.  If this
00322           // doesn't work we're in big trouble since the input stream
00323           // won't be aligned correctly.  I'm not sure quite what to
00324           // do at this point.  It's probably best just to return -1.
00325           if (ACE::recv (handle, &read_p[n], remainder) <= 0)
00326             return -1;
00327         }
00328 
00329       return 1;
00330     }
00331 
00332   // Return -1 if things have gone seriously wrong.
00333   if (n <= 0 && (errno != EWOULDBLOCK && errno != EAGAIN))
00334     return -1;
00335 
00336   return have_one ? 1 : 0;
00337 }
00338 
00339 
00340 int
00341 ACE_Dev_Poll_Reactor_Notify::handle_input (ACE_HANDLE handle)
00342 {
00343   ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::handle_input");
00344 
00345   // @@ We may end up dispatching this event handler twice:  once when
00346   //    performing the speculative read on the notification pipe
00347   //    handle, and once more when dispatching the IO events.
00348 
00349   // Precondition: this->select_reactor_.token_.current_owner () ==
00350   // ACE_Thread::self ();
00351 
00352   int number_dispatched = 0;
00353   int result = 0;
00354   ACE_Notification_Buffer buffer;
00355 
00356   while ((result = this->read_notify_pipe (handle, buffer)) > 0)
00357     {
00358       // Dispatch the buffer
00359       // NOTE: We count only if we made any dispatches ie. upcalls.
00360       if (this->dispatch_notify (buffer) > 0)
00361         ++number_dispatched;
00362 
00363       // Bail out if we've reached the <notify_threshold_>.  Note that
00364       // by default <notify_threshold_> is -1, so we'll loop until all
00365       // the available notifications have been dispatched.
00366       if (number_dispatched == this->max_notify_iterations_)
00367         break;
00368     }
00369 
00370   if (result == -1)
00371     {
00372       // Reassign number_dispatched to -1 if things have gone
00373       // seriously wrong.
00374       number_dispatched = -1;
00375     }
00376 
00377   // Enqueue ourselves into the list of waiting threads.  When we
00378   // reacquire the token we'll be off and running again with ownership
00379   // of the token.  The postcondition of this call is that
00380   // <select_reactor_.token_.current_owner> == <ACE_Thread::self>.
00381   //this->select_reactor_->renew ();
00382 
00383   return number_dispatched;
00384 }
00385 
00386 ACE_HANDLE
00387 ACE_Dev_Poll_Reactor_Notify::notify_handle (void)
00388 {
00389   ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::notify_handle");
00390 
00391   return this->notification_pipe_.read_handle ();
00392 }
00393 
00394 int
00395 ACE_Dev_Poll_Reactor_Notify::is_dispatchable (ACE_Notification_Buffer &)
00396 {
00397   ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::is_dispatchable");
00398 
00399   ACE_NOTSUP_RETURN (-1);
00400 }
00401 
00402 int
00403 ACE_Dev_Poll_Reactor_Notify::dispatch_notify (ACE_Notification_Buffer &buffer)
00404 {
00405   ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::dispatch_notify");
00406 
00407   // If eh == 0 then another thread is unblocking the
00408   // ACE_Dev_Poll_Reactor to update the ACE_Dev_Poll_Reactor's
00409   // internal structures.  Otherwise, we need to dispatch the
00410   // appropriate handle_* method on the ACE_Event_Handler
00411   // pointer we've been passed.
00412   if (buffer.eh_ != 0)
00413     {
00414       int result = 0;
00415 
00416       // Guard the handler's refcount. Recall that when the notify
00417       // was queued, the refcount was incremented, so it need not be
00418       // now. The guard insures that it is decremented properly.
00419       ACE_Dev_Poll_Handler_Guard eh_guard (buffer.eh_, false);
00420 
00421       switch (buffer.mask_)
00422         {
00423         case ACE_Event_Handler::READ_MASK:
00424         case ACE_Event_Handler::ACCEPT_MASK:
00425           result = buffer.eh_->handle_input (ACE_INVALID_HANDLE);
00426           break;
00427         case ACE_Event_Handler::WRITE_MASK:
00428           result = buffer.eh_->handle_output (ACE_INVALID_HANDLE);
00429           break;
00430         case ACE_Event_Handler::EXCEPT_MASK:
00431           result = buffer.eh_->handle_exception (ACE_INVALID_HANDLE);
00432           break;
00433         default:
00434           // Should we bail out if we get an invalid mask?
00435           ACE_ERROR ((LM_ERROR,
00436                       ACE_LIB_TEXT ("dispatch_notify invalid mask = %d\n"),
00437                       buffer.mask_));
00438         }
00439       if (result == -1)
00440         buffer.eh_->handle_close (ACE_INVALID_HANDLE, buffer.mask_);
00441     }
00442 
00443   return 1;
00444 }
00445 
00446 void
00447 ACE_Dev_Poll_Reactor_Notify::max_notify_iterations (int iterations)
00448 {
00449   ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::max_notify_iterations");
00450 
00451   // Must always be > 0 or < 0 to optimize the loop exit condition.
00452   if (iterations == 0)
00453     iterations = 1;
00454 
00455   this->max_notify_iterations_ = iterations;
00456 }
00457 
00458 int
00459 ACE_Dev_Poll_Reactor_Notify::max_notify_iterations (void)
00460 {
00461   ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::max_notify_iterations");
00462 
00463   return this->max_notify_iterations_;
00464 }
00465 
00466 int
00467 ACE_Dev_Poll_Reactor_Notify::purge_pending_notifications (
00468   ACE_Event_Handler *eh,
00469   ACE_Reactor_Mask mask)
00470 {
00471   ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::purge_pending_notifications");
00472 
00473 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
00474 
00475   ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, mon, this->notify_queue_lock_, -1);
00476 
00477   if (this->notify_queue_.is_empty ())
00478     return 0;
00479 
00480   ACE_Notification_Buffer *temp;
00481   ACE_Unbounded_Queue <ACE_Notification_Buffer *> local_queue;
00482 
00483   size_t queue_size = this->notify_queue_.size ();
00484   int number_purged = 0;
00485   size_t i;
00486   for (i = 0; i < queue_size; ++i)
00487     {
00488       if (-1 == this->notify_queue_.dequeue_head (temp))
00489         ACE_ERROR_RETURN ((LM_ERROR,
00490                            ACE_LIB_TEXT ("%p\n"),
00491                            ACE_LIB_TEXT ("dequeue_head")),
00492                           -1);
00493 
00494       // If this is not a Reactor notify (it is for a particular
00495       // handler), and it matches the specified handler (or purging
00496       // all), and applying the mask would totally eliminate the
00497       // notification, then release it and count the number purged.
00498       if ((0 != temp->eh_) &&
00499           (0 == eh || eh == temp->eh_) &&
00500           ACE_BIT_DISABLED (temp->mask_, ~mask)) // The existing
00501                                                  // notification mask
00502                                                  // is left with
00503                                                  // nothing when
00504                                                  // applying the mask.
00505         {
00506           if (this->free_queue_.enqueue_head (temp) == -1)
00507             ACE_ERROR_RETURN ((LM_ERROR,
00508                                ACE_LIB_TEXT ("%p\n"),
00509                                ACE_LIB_TEXT ("enqueue_head")),
00510                               -1);
00511           ++number_purged;
00512         }
00513       else
00514         {
00515           // To preserve it, move it to the local_queue.
00516           // But first, if this is not a Reactor notify (it is for a
00517           // particular handler), and it matches the specified handler
00518           // (or purging all), then apply the mask.
00519           if ((0 != temp->eh_) &&
00520               (0 == eh || eh == temp->eh_))
00521             ACE_CLR_BITS(temp->mask_, mask);
00522           if (-1 == local_queue.enqueue_head (temp))
00523             return -1;
00524         }
00525     }
00526 
00527   if (this->notify_queue_.size ())
00528     {
00529       // Should be empty!
00530       ACE_ASSERT (0);
00531       return -1;
00532     }
00533 
00534   // Now put it back in the notify queue.
00535   queue_size = local_queue.size ();
00536   for (i = 0; i < queue_size; ++i)
00537     {
00538       if (-1 == local_queue.dequeue_head (temp))
00539         ACE_ERROR_RETURN ((LM_ERROR,
00540                            ACE_LIB_TEXT ("%p\n"),
00541                            ACE_LIB_TEXT ("dequeue_head")),
00542                           -1);
00543 
00544       if (-1 == this->notify_queue_.enqueue_head (temp))
00545         ACE_ERROR_RETURN ((LM_ERROR,
00546                            ACE_LIB_TEXT ("%p\n"),
00547                            ACE_LIB_TEXT ("enqueue_head")),
00548                           -1);
00549     }
00550 
00551   return number_purged;
00552 
00553 #else /* defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE) */
00554   ACE_UNUSED_ARG (eh);
00555   ACE_UNUSED_ARG (mask);
00556   ACE_NOTSUP_RETURN (-1);
00557 #endif  /* defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE) */
00558 }
00559 
00560 void
00561 ACE_Dev_Poll_Reactor_Notify::dump (void) const
00562 {
00563 #if defined (ACE_HAS_DUMP)
00564   ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::dump");
00565 
00566   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00567   ACE_DEBUG ((LM_DEBUG,
00568               ACE_LIB_TEXT ("dp_reactor_ = %@"),
00569               this->dp_reactor_));
00570   this->notification_pipe_.dump ();
00571   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00572 #endif /* ACE_HAS_DUMP */
00573 }
00574 
00575 // -----------------------------------------------------------------
00576 
00577 ACE_Dev_Poll_Reactor_Handler_Repository::
00578 ACE_Dev_Poll_Reactor_Handler_Repository (void)
00579   : max_size_ (0),
00580     handlers_ (0)
00581 {
00582   ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::ACE_Dev_Poll_Reactor_Handler_Repository");
00583 }
00584 
00585 int
00586 ACE_Dev_Poll_Reactor_Handler_Repository::invalid_handle (
00587   ACE_HANDLE handle) const
00588 {
00589   ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::invalid_handle");
00590 
00591   if (handle < 0 || handle >= this->max_size_)
00592     {
00593       errno = EINVAL;
00594       return 1;
00595     }
00596   else
00597     return 0;
00598 }
00599 
00600 int
00601 ACE_Dev_Poll_Reactor_Handler_Repository::handle_in_range (
00602   ACE_HANDLE handle) const
00603 {
00604   ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::handle_in_range");
00605 
00606   if (handle >= 0 && handle < this->max_size_)
00607     return 1;
00608   else
00609     {
00610       errno = EINVAL;
00611       return 0;
00612     }
00613 }
00614 
00615 int
00616 ACE_Dev_Poll_Reactor_Handler_Repository::open (size_t size)
00617 {
00618   ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::open");
00619 
00620   this->max_size_ = size;
00621 
00622   // Try to allocate the memory.
00623   ACE_NEW_RETURN (this->handlers_,
00624                   ACE_Dev_Poll_Event_Tuple[size],
00625                   -1);
00626 
00627   // Try to increase the number of handles if <size> is greater than
00628   // the current limit.
00629   return ACE::set_handle_limit (size);
00630 }
00631 
00632 int
00633 ACE_Dev_Poll_Reactor_Handler_Repository::unbind_all (void)
00634 {
00635   ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::unbind_all");
00636 
00637   // Unbind all of the event handlers.
00638   for (int handle = 0;
00639        handle < this->max_size_;
00640        ++handle)
00641     this->unbind (handle);
00642 
00643   return 0;
00644 }
00645 
00646 int
00647 ACE_Dev_Poll_Reactor_Handler_Repository::close (void)
00648 {
00649   ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::close");
00650 
00651   if (this->handlers_ != 0)
00652     {
00653       this->unbind_all ();
00654 
00655       delete [] this->handlers_;
00656       this->handlers_ = 0;
00657     }
00658 
00659   return 0;
00660 }
00661 
00662 ACE_Event_Handler *
00663 ACE_Dev_Poll_Reactor_Handler_Repository::find (ACE_HANDLE handle,
00664                                                size_t *index_p)
00665 {
00666   ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::find");
00667 
00668   ACE_Event_Handler *eh = 0;
00669 
00670   // Only bother to search for the <handle> if it's in range.
00671   if (this->handle_in_range (handle))
00672     {
00673       eh = this->handlers_[handle].event_handler;
00674       if (eh != 0)
00675         {
00676           if (index_p != 0)
00677             *index_p = handle;
00678         }
00679       else
00680         errno = ENOENT;
00681     }
00682 
00683   return eh;
00684 }
00685 
00686 int
00687 ACE_Dev_Poll_Reactor_Handler_Repository::bind (
00688   ACE_HANDLE handle,
00689   ACE_Event_Handler *event_handler,
00690   ACE_Reactor_Mask mask)
00691 {
00692   ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::bind");
00693 
00694   if (handle == ACE_INVALID_HANDLE)
00695     handle = event_handler->get_handle ();
00696 
00697   if (this->invalid_handle (handle))
00698     return -1;
00699 
00700   this->handlers_[handle].event_handler = event_handler;
00701   this->handlers_[handle].mask = mask;
00702   event_handler->add_reference ();
00703 
00704   return 0;
00705 }
00706 
00707 int
00708 ACE_Dev_Poll_Reactor_Handler_Repository::unbind (ACE_HANDLE handle,
00709                                                  bool decr_refcnt)
00710 {
00711   ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::unbind");
00712 
00713   if (this->find (handle) == 0)
00714     return -1;
00715 
00716   if (decr_refcnt)
00717     this->handlers_[handle].event_handler->remove_reference ();
00718   this->handlers_[handle].event_handler = 0;
00719   this->handlers_[handle].mask = ACE_Event_Handler::NULL_MASK;
00720   this->handlers_[handle].suspended = 0;
00721 
00722   return 0;
00723 }
00724 
00725 // -----------------------------------------------------------------
00726 
00727 ACE_Dev_Poll_Reactor::ACE_Dev_Poll_Reactor (ACE_Sig_Handler *sh,
00728                                             ACE_Timer_Queue *tq,
00729                                             int disable_notify_pipe,
00730                                             ACE_Reactor_Notify *notify,
00731                                             int mask_signals,
00732                                             int s_queue)
00733   : initialized_ (false)
00734   , poll_fd_ (ACE_INVALID_HANDLE)
00735   , size_ (0)
00736   // , ready_set_ ()
00737 #if defined (ACE_HAS_EVENT_POLL)
00738   , events_ (0)
00739   , start_pevents_ (0)
00740   , end_pevents_ (0)
00741 #else
00742   , dp_fds_ (0)
00743   , start_pfds_ (0)
00744   , end_pfds_ (0)
00745 #endif  /* ACE_HAS_EVENT_POLL */
00746   , deactivated_ (0)
00747   , token_ (*this, s_queue)
00748   , lock_adapter_ (token_)
00749   , timer_queue_ (0)
00750   , delete_timer_queue_ (0)
00751   , signal_handler_ (0)
00752   , delete_signal_handler_ (0)
00753   , notify_handler_ (0)
00754   , delete_notify_handler_ (0)
00755   , mask_signals_ (mask_signals)
00756   , restart_ (0)
00757 {
00758   ACE_TRACE ("ACE_Dev_Poll_Reactor::ACE_Dev_Poll_Reactor");
00759 
00760   if (this->open (ACE::max_handles (),
00761                   0,
00762                   sh,
00763                   tq,
00764                   disable_notify_pipe,
00765                   notify) == -1)
00766     ACE_ERROR ((LM_ERROR,
00767                 ACE_LIB_TEXT ("%p\n"),
00768                 ACE_LIB_TEXT ("ACE_Dev_Poll_Reactor::open ")
00769                 ACE_LIB_TEXT ("failed inside ")
00770                 ACE_LIB_TEXT ("ACE_Dev_Poll_Reactor::CTOR")));
00771 }
00772 
00773 ACE_Dev_Poll_Reactor::ACE_Dev_Poll_Reactor (size_t size,
00774                                             int rs,
00775                                             ACE_Sig_Handler *sh,
00776                                             ACE_Timer_Queue *tq,
00777                                             int disable_notify_pipe,
00778                                             ACE_Reactor_Notify *notify,
00779                                             int mask_signals,
00780                                             int s_queue)
00781   : initialized_ (false)
00782   , poll_fd_ (ACE_INVALID_HANDLE)
00783   , size_ (0)
00784   // , ready_set_ ()
00785 #if defined (ACE_HAS_EVENT_POLL)
00786   , events_ (0)
00787   , start_pevents_ (0)
00788   , end_pevents_ (0)
00789 #else
00790   , dp_fds_ (0)
00791   , start_pfds_ (0)
00792   , end_pfds_ (0)
00793 #endif  /* ACE_HAS_EVENT_POLL */
00794   , deactivated_ (0)
00795   , token_ (*this, s_queue)
00796   , lock_adapter_ (token_)
00797   , timer_queue_ (0)
00798   , delete_timer_queue_ (0)
00799   , signal_handler_ (0)
00800   , delete_signal_handler_ (0)
00801   , notify_handler_ (0)
00802   , delete_notify_handler_ (0)
00803   , mask_signals_ (mask_signals)
00804   , restart_ (0)
00805 {
00806   if (this->open (size,
00807                   rs,
00808                   sh,
00809                   tq,
00810                   disable_notify_pipe,
00811                   notify) == -1)
00812     ACE_ERROR ((LM_ERROR,
00813                 ACE_LIB_TEXT ("%p\n"),
00814                 ACE_LIB_TEXT ("ACE_Dev_Poll_Reactor::open ")
00815                 ACE_LIB_TEXT ("failed inside ACE_Dev_Poll_Reactor::CTOR")));
00816 }
00817 
00818 ACE_Dev_Poll_Reactor::~ACE_Dev_Poll_Reactor (void)
00819 {
00820   ACE_TRACE ("ACE_Dev_Poll_Reactor::~ACE_Dev_Poll_Reactor");
00821 
00822   (void) this->close ();
00823 }
00824 
00825 int
00826 ACE_Dev_Poll_Reactor::open (size_t size,
00827                             int restart,
00828                             ACE_Sig_Handler *sh,
00829                             ACE_Timer_Queue *tq,
00830                             int disable_notify_pipe,
00831                             ACE_Reactor_Notify *notify)
00832 {
00833   ACE_TRACE ("ACE_Dev_Poll_Reactor::open");
00834 
00835   ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
00836 
00837   // Can't initialize ourselves more than once.
00838   if (this->initialized_)
00839     return -1;
00840 
00841   this->restart_ = restart;
00842   this->signal_handler_ = sh;
00843   this->timer_queue_ = tq;
00844   this->notify_handler_ = notify;
00845 
00846   int result = 0;
00847 
00848   // Allows the signal handler to be overridden.
00849   if (this->signal_handler_ == 0)
00850     {
00851       ACE_NEW_RETURN (this->signal_handler_,
00852                       ACE_Sig_Handler,
00853                       -1);
00854 
00855       if (this->signal_handler_ == 0)
00856         result = -1;
00857       else
00858         this->delete_signal_handler_ = 1;
00859     }
00860 
00861   // Allows the timer queue to be overridden.
00862   if (result != -1 && this->timer_queue_ == 0)
00863     {
00864       ACE_NEW_RETURN (this->timer_queue_,
00865                       ACE_Timer_Heap,
00866                       -1);
00867 
00868       if (this->timer_queue_ == 0)
00869         result = -1;
00870       else
00871         this->delete_timer_queue_ = 1;
00872     }
00873 
00874   // Allows the Notify_Handler to be overridden.
00875   if (result != -1 && this->notify_handler_ == 0)
00876     {
00877       ACE_NEW_RETURN (this->notify_handler_,
00878                       ACE_Dev_Poll_Reactor_Notify,
00879                       -1);
00880 
00881       if (this->notify_handler_ == 0)
00882         result = -1;
00883       else
00884         this->delete_notify_handler_ = 1;
00885     }
00886 
00887 #if defined (ACE_HAS_EVENT_POLL)
00888 
00889   // Allocating event table:
00890   ACE_NEW_RETURN (this->events_, epoll_event[size], -1);
00891 
00892   // Initializing epoll:
00893   this->poll_fd_ = ::epoll_create (size);
00894   if (this->poll_fd_ == -1)
00895     result = -1;
00896 
00897 #else
00898 
00899   // Allocate the array before opening the device to avoid a potential
00900   // resource leak if allocation fails.
00901   ACE_NEW_RETURN (this->dp_fds_,
00902                   pollfd[size],
00903                   -1);
00904 
00905   // Open the `/dev/poll' character device.
00906   this->poll_fd_ = ACE_OS::open ("/dev/poll", O_RDWR);
00907   if (this->poll_fd_ == ACE_INVALID_HANDLE)
00908     result = -1;
00909 
00910 #endif  /* ACE_HAS_EVENT_POLL */
00911 
00912   if (result != -1 && this->handler_rep_.open (size) == -1)
00913     result = -1;
00914 
00915   // Registration of the notification handler must be done after the
00916   // /dev/poll device has been fully initialized.
00917   else if (this->notify_handler_->open (this,
00918                                         0,
00919                                         disable_notify_pipe) == -1
00920            || (disable_notify_pipe == 0
00921                && this->register_handler_i (
00922                                             this->notify_handler_->notify_handle (),
00923                                             this->notify_handler_,
00924                                             ACE_Event_Handler::READ_MASK)) == -1)
00925     result = -1;
00926 
00927   this->size_ = size;
00928 
00929   if (result != -1)
00930     // We're all set to go.
00931     this->initialized_ = true;
00932   else
00933     // This will close down all the allocated resources properly.
00934     (void) this->close ();
00935 
00936   return result;
00937 }
00938 
00939 int
00940 ACE_Dev_Poll_Reactor::current_info (ACE_HANDLE, size_t & /* size */)
00941 {
00942   ACE_NOTSUP_RETURN (-1);
00943 }
00944 
00945 
00946 int
00947 ACE_Dev_Poll_Reactor::set_sig_handler (ACE_Sig_Handler *signal_handler)
00948 {
00949   if (this->delete_signal_handler_ && this->signal_handler_)
00950     delete this->signal_handler_;
00951 
00952   this->signal_handler_ = signal_handler;
00953   this->delete_signal_handler_ = 0;
00954 
00955   return 0;
00956 }
00957 
00958 int
00959 ACE_Dev_Poll_Reactor::timer_queue (ACE_Timer_Queue *tq)
00960 {
00961   if (this->delete_timer_queue_ && this->timer_queue_)
00962     delete this->timer_queue_;
00963 
00964   this->timer_queue_ = tq;
00965   this->delete_timer_queue_ = 0;
00966 
00967   return 0;
00968 
00969 }
00970 
00971 ACE_Timer_Queue *
00972 ACE_Dev_Poll_Reactor::timer_queue (void) const
00973 {
00974   return this->timer_queue_;
00975 }
00976 
00977 int
00978 ACE_Dev_Poll_Reactor::close (void)
00979 {
00980   ACE_TRACE ("ACE_Dev_Poll_Reactor::close");
00981 
00982   ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
00983 
00984   int result = 0;
00985 
00986   if (this->poll_fd_ != ACE_INVALID_HANDLE)
00987     {
00988       result = ACE_OS::close (this->poll_fd_);
00989     }
00990 
00991 #if defined (ACE_HAS_EVENT_POLL)
00992 
00993   delete [] this->events_;
00994   this->events_ = 0;
00995 
00996 #else
00997 
00998   delete [] this->dp_fds_;
00999   this->dp_fds_ = 0;
01000 
01001 #endif  /* ACE_HAS_EVENT_POLL */
01002 
01003   if (this->delete_signal_handler_)
01004     {
01005       delete this->signal_handler_;
01006       this->signal_handler_ = 0;
01007       this->delete_signal_handler_ = 0;
01008     }
01009 
01010   (void) this->handler_rep_.close ();
01011 
01012   if (this->delete_timer_queue_)
01013     {
01014       delete this->timer_queue_;
01015       this->timer_queue_ = 0;
01016       this->delete_timer_queue_ = 0;
01017     }
01018 
01019   if (this->notify_handler_ != 0)
01020     this->notify_handler_->close ();
01021 
01022   if (this->delete_notify_handler_)
01023     {
01024       delete this->notify_handler_;
01025       this->notify_handler_ = 0;
01026       this->delete_notify_handler_ = 0;
01027     }
01028 
01029   this->poll_fd_ = ACE_INVALID_HANDLE;
01030 
01031 #if defined (ACE_HAS_EVENT_POLL)
01032   this->start_pevents_ = 0;
01033   this->end_pevents_   = 0;
01034 #else
01035   this->start_pfds_ = 0;
01036   this->end_pfds_ = 0;
01037 #endif /* ACE_HAS_EVENT_POLL */
01038 
01039   this->initialized_ = false;
01040 
01041   return result;
01042 }
01043 
01044 int
01045 ACE_Dev_Poll_Reactor::work_pending (const ACE_Time_Value & max_wait_time)
01046 {
01047   ACE_TRACE ("ACE_Dev_Poll_Reactor::work_pending");
01048 
01049   // Stash the current time
01050   //
01051   // The destructor of this object will automatically compute how much
01052   // time elapsed since this method was called.
01053   ACE_Time_Value mwt (max_wait_time);
01054   ACE_MT (ACE_Countdown_Time countdown (&mwt));
01055 
01056   Token_Guard guard (this->token_);
01057   int result = guard.acquire_quietly (&mwt);
01058 
01059   // If the guard is NOT the owner just return the retval
01060   if (!guard.is_owner ())
01061     return result;
01062 
01063   // Update the countdown to reflect time waiting for the mutex.
01064   ACE_MT (countdown.update ());
01065 
01066   return this->work_pending_i (&mwt);
01067 }
01068 
01069 int
01070 ACE_Dev_Poll_Reactor::work_pending_i (ACE_Time_Value * max_wait_time)
01071 {
01072   ACE_TRACE ("ACE_Dev_Poll_Reactor::work_pending_i");
01073 
01074   if (this->deactivated_)
01075     return 0;
01076 
01077 #if defined (ACE_HAS_EVENT_POLL)
01078   if (this->start_pevents_ != this->end_pevents_)
01079 #else
01080   if (this->start_pfds_ != this->end_pfds_)
01081 #endif /* ACE_HAS_EVENT_POLL */
01082     return 1;  // We still have work_pending(). Do not poll for
01083                // additional events.
01084 
01085   ACE_Time_Value timer_buf (0);
01086   ACE_Time_Value *this_timeout = 0;
01087 
01088   this_timeout = this->timer_queue_->calculate_timeout (max_wait_time,
01089                                                         &timer_buf);
01090 
01091   // Check if we have timers to fire.
01092   const int timers_pending =
01093     ((this_timeout != 0 && max_wait_time == 0)
01094      || (this_timeout != 0 && max_wait_time != 0
01095          && *this_timeout != *max_wait_time) ? 1 : 0);
01096 
01097   const long timeout =
01098     (this_timeout == 0
01099      ? -1 /* Infinity */
01100      : static_cast<long> (this_timeout->msec ()));
01101 
01102 #if defined (ACE_HAS_EVENT_POLL)
01103 
01104    // Wait for events.
01105    const int nfds = ::epoll_wait (this->poll_fd_,
01106                                   this->events_,
01107                                   this->size_,
01108                                   static_cast<int> (timeout));
01109 
01110   if (nfds > 0)
01111     {
01112       this->start_pevents_ = this->events_;
01113       this->end_pevents_ = this->start_pevents_ + nfds;
01114     }
01115 
01116 #else
01117 
01118   struct dvpoll dvp;
01119 
01120   dvp.dp_fds = this->dp_fds_;
01121   dvp.dp_nfds = this->size_;
01122   dvp.dp_timeout = timeout;  // Milliseconds
01123 
01124   // Poll for events
01125   const int nfds = ACE_OS::ioctl (this->poll_fd_, DP_POLL, &dvp);
01126 
01127   // Retrieve the results from the pollfd array.
01128   this->start_pfds_ = dvp.dp_fds;
01129 
01130   // If nfds == 0 then end_pfds_ == start_pfds_ meaning that there is
01131   // no work pending.  If nfds > 0 then there is work pending.
01132   // Otherwise an error occurred.
01133   if (nfds > -1)
01134     this->end_pfds_ = this->start_pfds_ + nfds;
01135 #endif  /* ACE_HAS_EVENT_POLL */
01136 
01137   // If timers are pending, override any timeout from the poll.
01138   return (nfds == 0 && timers_pending != 0 ? 1 : nfds);
01139 }
01140 
01141 
01142 int
01143 ACE_Dev_Poll_Reactor::handle_events (ACE_Time_Value *max_wait_time)
01144 {
01145   ACE_TRACE ("ACE_Dev_Poll_Reactor::handle_events");
01146 
01147   // Stash the current time
01148   //
01149   // The destructor of this object will automatically compute how much
01150   // time elapsed since this method was called.
01151   ACE_MT (ACE_Countdown_Time countdown (max_wait_time));
01152 
01153   Token_Guard guard (this->token_);
01154   int result = guard.acquire_quietly (max_wait_time);
01155 
01156   // If the guard is NOT the owner just return the retval
01157   if (!guard.is_owner ())
01158     return result;
01159 
01160   if (this->deactivated_)
01161     return -1;
01162 
01163   // Update the countdown to reflect time waiting for the mutex.
01164   ACE_MT (countdown.update ());
01165 
01166   return this->handle_events_i (max_wait_time, guard);
01167 }
01168 
01169 int
01170 ACE_Dev_Poll_Reactor::handle_events_i (ACE_Time_Value *max_wait_time,
01171                                        Token_Guard &guard)
01172 {
01173   ACE_TRACE ("ACE_Dev_Poll_Reactor::handle_events_i");
01174 
01175   int result = 0;
01176   // int active_handle_count = 0;
01177 
01178   // Poll for events
01179   //
01180   // If the underlying ioctl() call was interrupted via the interrupt
01181   // signal (i.e. returned -1 with errno == EINTR) then the loop will
01182   // be restarted if so desired.
01183   do
01184     {
01185       result = this->work_pending_i (max_wait_time);
01186       if (result == -1)
01187         ACE_ERROR((LM_ERROR, "%t: %p\n", "work_pending_i"));
01188     }
01189   while (result == -1 && this->restart_ != 0 && errno == EINTR);
01190 
01191   if (result == 0 || (result == -1 && errno == ETIME))
01192     return 0;
01193   else if (result == -1)
01194     {
01195       if (errno != EINTR)
01196         return -1;
01197 
01198       // Bail out -- we got here since the poll was interrupted.
01199       // If it was due to a signal registered through our ACE_Sig_Handler,
01200       // then it was dispatched, so we count it in the number of events
01201       // handled rather than cause an error return.
01202       if (ACE_Sig_Handler::sig_pending () != 0)
01203         {
01204           ACE_Sig_Handler::sig_pending (0);
01205           return 1;
01206         }
01207       return -1;
01208     }
01209 
01210   // Dispatch an event.
01211   return this->dispatch (guard);
01212 }
01213 
01214 // Dispatch an event. On entry, the token is held by the caller. If an
01215 // event is found to dispatch, the token is released before dispatching it.
01216 int
01217 ACE_Dev_Poll_Reactor::dispatch (Token_Guard &guard)
01218 {
01219   ACE_TRACE ("ACE_Dev_Poll_Reactor::dispatch");
01220 
01221   // Perform the Template Method for dispatching the first located event.
01222   // We dispatch only one to effectively dispatch events concurrently.
01223   // As soon as an event is located, the token is released, allowing the
01224   // next waiter to begin getting an event while we dispatch one here.
01225   int result = 0;
01226 
01227   // Handle timers early since they may have higher latency
01228   // constraints than I/O handlers.  Ideally, the order of
01229   // dispatching should be a strategy...
01230   if ((result = this->dispatch_timer_handler (guard)) != 0)
01231     return result;
01232 
01233   // Check to see if there are no more I/O handles left to
01234   // dispatch AFTER we've handled the timers.
01235 
01236   // Finally, dispatch the I/O handlers.
01237   result = this->dispatch_io_event (guard);
01238 
01239   return result;
01240 }
01241 
01242 int
01243 ACE_Dev_Poll_Reactor::dispatch_timer_handler (Token_Guard &guard)
01244 {
01245   if (this->timer_queue_->is_empty())
01246     return 0;       // Empty timer queue so cannot have any expired timers.
01247 
01248   // Get the current time
01249   ACE_Time_Value cur_time (this->timer_queue_->gettimeofday () +
01250                            this->timer_queue_->timer_skew ());
01251 
01252   // Look for a node in the timer queue whose timer <= the present
01253   // time.
01254   ACE_Timer_Node_Dispatch_Info info;
01255   if (this->timer_queue_->dispatch_info (cur_time, info))
01256     {
01257       const void *upcall_act = 0;
01258 
01259       // Preinvoke (handles refcount if needed, etc.)
01260       this->timer_queue_->preinvoke (info, cur_time, upcall_act);
01261 
01262       // Release the token before expiration upcall.
01263       guard.release_token ();
01264 
01265       // call the functor
01266       this->timer_queue_->upcall (info, cur_time);
01267 
01268       // Postinvoke (undo refcount if needed, etc.)
01269       this->timer_queue_->postinvoke (info, cur_time, upcall_act);
01270 
01271       // We have dispatched a timer
01272       return 1;
01273     }
01274 
01275   return 0;
01276 }
01277 
01278 #if 0
01279 int
01280 ACE_Dev_Poll_Reactor::dispatch_notification_handlers (
01281   ACE_Select_Reactor_Handle_Set &dispatch_set,
01282   int &number_of_active_handles,
01283   int &number_of_handlers_dispatched)
01284 {
01285   // Check to see if the ACE_HANDLE associated with the
01286   // Dev_Poll_Reactor's notify hook is enabled.  If so, it means that
01287   // one or more other threads are trying to update the
01288   // ACE_Dev_Poll_Reactor's internal tables or the notify pipe is
01289   // enabled.  We'll handle all these threads and notifications, and
01290   // then break out to continue the event loop.
01291 
01292   const int n =
01293     this->notify_handler_->dispatch_notifications (number_of_active_handles,
01294                                                    dispatch_set.rd_mask_);
01295 
01296   if (n == -1)
01297     return -1;
01298   else
01299     number_of_handlers_dispatched += n;
01300 
01301   return /* this->state_changed_ ? -1 : */ 0;
01302 }
01303 #endif  /* 0 */
01304 
01305 int
01306 ACE_Dev_Poll_Reactor::dispatch_io_event (Token_Guard &guard)
01307 {
01308 
01309   // Define bits to check for while dispatching.
01310 #if defined (ACE_HAS_EVENT_POLL)
01311   const __uint32_t out_event = EPOLLOUT;
01312   const __uint32_t exc_event = EPOLLPRI;
01313   const __uint32_t in_event  = EPOLLIN;
01314   const __uint32_t err_event = EPOLLHUP | EPOLLERR;
01315 #else
01316   const short out_event = POLLOUT;
01317   const short exc_event = POLLPRI;
01318   const short in_event  = POLLIN;
01319   const short err_event = 0;              // No known bits for this
01320 #endif /* ACE_HAS_EVENT_POLL */
01321 
01322   // Since the underlying event demultiplexing mechansim (`/dev/poll'
01323   // or '/dev/epoll') is stateful, and since only one result buffer is
01324   // used, all pending events (i.e. those retrieved from a previous
01325   // poll) must be dispatched before any additional event can be
01326   // polled.  As such, the Dev_Poll_Reactor keeps track of the
01327   // progress of events that have been dispatched.
01328 
01329   // Dispatch the events.
01330   //
01331   // Select the first available handle with event(s) pending. Check for
01332   // event type in defined order of dispatch: output, exception, input.
01333   // When an event is located, clear its bit in the dispatch set. If there
01334   // are no more events for the handle, also increment the pfds pointer
01335   // to move to the next handle ready.
01336   //
01337   // Notice that pfds only contains file descriptors that have
01338   // received events.
01339 #if defined (ACE_HAS_EVENT_POLL)
01340   struct epoll_event *& pfds = this->start_pevents_;
01341   if (pfds < this->end_pevents_)
01342 #else
01343   struct pollfd *& pfds = this->start_pfds_;
01344   if (pfds < this->end_pfds_)
01345 #endif /* ACE_HAS_EVENT_POLL */
01346     {
01347 #if defined (ACE_HAS_EVENT_POLL)
01348       const ACE_HANDLE handle   = pfds->data.fd;
01349       __uint32_t &revents       = pfds->events;
01350 #else
01351       const ACE_HANDLE handle = pfds->fd;
01352       short &revents          = pfds->revents;
01353 #endif /* ACE_HAS_EVENT_POLL */
01354 
01355       // Figure out what to do first in order to make it easier to manage
01356       // the bit twiddling and possible pfds increment before releasing
01357       // the token for dispatch.
01358       // Note that if there's an error (such as the handle was closed
01359       // without being removed from the event set) the EPOLLHUP and/or
01360       // EPOLLERR bits will be set in revents.
01361       bool disp_out = false;
01362       bool disp_exc = false;
01363       bool disp_in  = false;
01364       if (ACE_BIT_ENABLED (revents, out_event))
01365         {
01366           disp_out = true;
01367           ACE_CLR_BITS (revents, out_event);
01368         }
01369       else if (ACE_BIT_ENABLED (revents, exc_event))
01370         {
01371           disp_exc = true;
01372           ACE_CLR_BITS (revents, exc_event);
01373         }
01374       else if (ACE_BIT_ENABLED (revents, in_event))
01375         {
01376           disp_in = true;
01377           ACE_CLR_BITS (revents, in_event);
01378         }
01379       else if (ACE_BIT_ENABLED (revents, err_event))
01380         {
01381           this->remove_handler_i (handle, ACE_Event_Handler::ALL_EVENTS_MASK);
01382           ++pfds;
01383           return 1;
01384         }
01385       else
01386         {
01387           ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%t) dispatch_io h %d unknown events 0x%x\n"), handle, revents));
01388           // ACE_ASSERT (0);
01389         }
01390 
01391       // Increment the pointer to the next element before we
01392       // release the token.  Otherwise event handlers end up being
01393       // dispatched multiple times for the same poll.
01394       if (revents == 0)
01395         ++pfds;
01396 
01397       /* When using sys_epoll, we can attach arbitrary user
01398          data to the descriptor, so it can be delivered when
01399          activity is detected. Perhaps we should store event
01400          handler together with descriptor, instead of looking
01401          it up in a repository ? Could it boost performance ?
01402       */
01403       ACE_Event_Handler *eh = this->handler_rep_.find (handle);
01404 
01405       if (eh)
01406         {
01407           // Modify the reference count in an exception-safe way.
01408           // Note that eh could be the notify handler. It's not strictly
01409           // necessary to manage its refcount, but since we don't enable
01410           // the counting policy, it won't do much. Management of the
01411           // notified handlers themselves is done in the notify handler.
01412           ACE_Dev_Poll_Handler_Guard eh_guard (eh);
01413 
01414           // Release the reactor token before upcall.
01415           guard.release_token ();
01416 
01417           // Dispatch the detected event
01418           if (disp_out)
01419             {
01420               const int status =
01421                 this->upcall (eh, &ACE_Event_Handler::handle_output, handle);
01422 
01423               if (status < 0)
01424                 // Note that the token is reacquired in remove_handler().
01425                 this->remove_handler (handle, ACE_Event_Handler::WRITE_MASK);
01426               return 1;
01427             }
01428 
01429           if (disp_exc)
01430             {
01431               const int status =
01432                 this->upcall (eh, &ACE_Event_Handler::handle_exception, handle);
01433 
01434               if (status < 0)
01435                 // Note that the token is reacquired in remove_handler().
01436                 this->remove_handler (handle, ACE_Event_Handler::EXCEPT_MASK);
01437               return 1;
01438             }
01439 
01440           if (disp_in)
01441             {
01442               const int status =
01443                 this->upcall (eh, &ACE_Event_Handler::handle_input, handle);
01444 
01445               if (status < 0)
01446                 // Note that the token is reacquired in remove_handler().
01447                 this->remove_handler (handle, ACE_Event_Handler::READ_MASK);
01448               return 1;
01449             }
01450         } // The reactor token is reacquired upon leaving this scope.
01451     }
01452 
01453   return 0;
01454 }
01455 
01456 int
01457 ACE_Dev_Poll_Reactor::alertable_handle_events (ACE_Time_Value *max_wait_time)
01458 {
01459   ACE_TRACE ("ACE_Dev_Poll_Reactor::alertable_handle_events");
01460 
01461   return this->handle_events (max_wait_time);
01462 }
01463 
01464 int
01465 ACE_Dev_Poll_Reactor::handle_events (ACE_Time_Value &max_wait_time)
01466 {
01467   ACE_TRACE ("ACE_Dev_Poll_Reactor::handle_events");
01468 
01469   return this->handle_events (&max_wait_time);
01470 }
01471 
01472 int
01473 ACE_Dev_Poll_Reactor::alertable_handle_events (ACE_Time_Value &max_wait_time)
01474 {
01475   ACE_TRACE ("ACE_Dev_Poll_Reactor::alertable_handle_events");
01476 
01477   return this->handle_events (max_wait_time);
01478 }
01479 
01480 int
01481 ACE_Dev_Poll_Reactor::deactivated (void)
01482 {
01483   return this->deactivated_;
01484 }
01485 
01486 void
01487 ACE_Dev_Poll_Reactor::deactivate (int do_stop)
01488 {
01489   this->deactivated_ = do_stop;
01490   this->wakeup_all_threads ();
01491 }
01492 
01493 int
01494 ACE_Dev_Poll_Reactor::register_handler (ACE_Event_Handler *handler,
01495                                         ACE_Reactor_Mask mask)
01496 {
01497   ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler");
01498 
01499   ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
01500 
01501   return this->register_handler_i (handler->get_handle (),
01502                                    handler,
01503                                    mask);
01504 }
01505 
01506 int
01507 ACE_Dev_Poll_Reactor::register_handler (ACE_HANDLE handle,
01508                                         ACE_Event_Handler *event_handler,
01509                                         ACE_Reactor_Mask mask)
01510 {
01511   ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler");
01512 
01513   ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
01514 
01515   return this->register_handler_i (handle,
01516                                    event_handler,
01517                                    mask);
01518 }
01519 
01520 int
01521 ACE_Dev_Poll_Reactor::register_handler_i (ACE_HANDLE handle,
01522                                           ACE_Event_Handler *event_handler,
01523                                           ACE_Reactor_Mask mask)
01524 {
01525   ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler_i");
01526 
01527   if (handle == ACE_INVALID_HANDLE
01528       || mask == ACE_Event_Handler::NULL_MASK)
01529     {
01530       errno = EINVAL;
01531       return -1;
01532     }
01533 
01534  if (this->handler_rep_.find (handle) == 0)
01535    {
01536      // Handler not present in the repository.  Bind it.
01537      if (this->handler_rep_.bind (handle, event_handler, mask) != 0)
01538        return -1;
01539 
01540 #if defined (ACE_HAS_EVENT_POLL)
01541 
01542      struct epoll_event epev;
01543      ACE_OS::memset (&epev, 0, sizeof (epev));
01544      static const int op = EPOLL_CTL_ADD;
01545 
01546      epev.events  = this->reactor_mask_to_poll_event (mask);
01547      epev.data.fd = handle;
01548 
01549      if (::epoll_ctl (this->poll_fd_, op, handle, &epev) == -1)
01550        {
01551          ACE_ERROR ((LM_ERROR, "%p\n", "epoll_ctl"));
01552          (void) this->handler_rep_.unbind (handle);
01553          return -1;
01554        }
01555 
01556 #endif /* ACE_HAS_EVENT_POLL */
01557    }
01558  else
01559    {
01560      // Handler is already present in the repository, so register it
01561      // again, possibly for different event.  Add new mask to the
01562      // current one.
01563      if (this->mask_ops_i (handle, mask, ACE_Reactor::ADD_MASK) == -1)
01564        ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "mask_ops_i"), -1);
01565    }
01566 
01567 #ifndef  ACE_HAS_EVENT_POLL
01568 
01569   struct pollfd pfd;
01570 
01571   pfd.fd      = handle;
01572   pfd.events  = this->reactor_mask_to_poll_event (mask);
01573   pfd.revents = 0;
01574 
01575   // Add file descriptor to the "interest set."
01576   if (ACE_OS::write (this->poll_fd_, &pfd, sizeof (pfd)) != sizeof (pfd))
01577     {
01578       (void) this->handler_rep_.unbind (handle);
01579       return -1;
01580     }
01581 #endif /*ACE_HAS_EVENT_POLL*/
01582 
01583   // Note the fact that we've changed the state of the wait_set_,
01584   // which is used by the dispatching loop to determine whether it can
01585   // keep going or if it needs to reconsult select().
01586   // this->state_changed_ = 1;
01587 
01588   return 0;
01589 }
01590 
01591 int
01592 ACE_Dev_Poll_Reactor::register_handler (
01593   ACE_HANDLE /* event_handle */,
01594   ACE_HANDLE /* io_handle */,
01595   ACE_Event_Handler * /* event_handler */,
01596   ACE_Reactor_Mask /* mask */)
01597 {
01598   ACE_NOTSUP_RETURN (-1);
01599 }
01600 
01601 int
01602 ACE_Dev_Poll_Reactor::register_handler (const ACE_Handle_Set &handle_set,
01603                                         ACE_Event_Handler *event_handler,
01604                                         ACE_Reactor_Mask mask)
01605 {
01606   ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler");
01607 
01608   ACE_Handle_Set_Iterator handle_iter (handle_set);
01609 
01610   ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
01611 
01612   // @@ It might be more efficient to construct a pollfd array and
01613   //    pass it to the write() call in register_handler_i() only once,
01614   //    instead of calling write() (a system call) once for each file
01615   //    descriptor.
01616 
01617   for (ACE_HANDLE h = handle_iter ();
01618        h != ACE_INVALID_HANDLE;
01619        h = handle_iter ())
01620     if (this->register_handler_i (h, event_handler, mask) == -1)
01621       return -1;
01622 
01623   return 0;
01624 }
01625 
01626 int
01627 ACE_Dev_Poll_Reactor::register_handler (int signum,
01628                                         ACE_Event_Handler *new_sh,
01629                                         ACE_Sig_Action *new_disp,
01630                                         ACE_Event_Handler **old_sh,
01631                                         ACE_Sig_Action *old_disp)
01632 {
01633   ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler");
01634 
01635   return this->signal_handler_->register_handler (signum,
01636                                                   new_sh,
01637                                                   new_disp,
01638                                                   old_sh,
01639                                                   old_disp);
01640 }
01641 
01642 int
01643 ACE_Dev_Poll_Reactor::register_handler (const ACE_Sig_Set &sigset,
01644                                         ACE_Event_Handler *new_sh,
01645                                         ACE_Sig_Action *new_disp)
01646 {
01647   ACE_TRACE ("ACE_Dev_Poll_Reactor::register_handler");
01648 
01649   int result = 0;
01650 
01651 #if (ACE_NSIG > 0)
01652 
01653   for (int s = 1; s < ACE_NSIG; ++s)
01654     if ((sigset.is_member (s) == 1)
01655         && this->signal_handler_->register_handler (s,
01656                                                     new_sh,
01657                                                     new_disp) == -1)
01658       result = -1;
01659 
01660 #else  /* ACE_NSIG <= 0 */
01661 
01662   ACE_UNUSED_ARG (sigset);
01663   ACE_UNUSED_ARG (new_sh);
01664   ACE_UNUSED_ARG (new_disp);
01665 
01666 #endif /* ACE_NSIG <= 0  */
01667 
01668   return result;
01669 }
01670 
01671 int
01672 ACE_Dev_Poll_Reactor::remove_handler (ACE_Event_Handler *handler,
01673                                       ACE_Reactor_Mask mask)
01674 {
01675   ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler");
01676 
01677   ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
01678 
01679   return this->remove_handler_i (handler->get_handle (), mask);
01680 }
01681 
01682 int
01683 ACE_Dev_Poll_Reactor::remove_handler (ACE_HANDLE handle,
01684                                       ACE_Reactor_Mask mask)
01685 {
01686   ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler");
01687 
01688   ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
01689 
01690   return this->remove_handler_i (handle, mask);
01691 }
01692 
01693 int
01694 ACE_Dev_Poll_Reactor::remove_handler_i (ACE_HANDLE handle,
01695                                         ACE_Reactor_Mask mask)
01696 {
01697   ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler_i");
01698 
01699   ACE_Event_Handler *eh = this->handler_rep_.find (handle);
01700 
01701   if (eh == 0 ||
01702       this->mask_ops_i (handle, mask, ACE_Reactor::CLR_MASK) == -1)
01703     return -1;
01704 
01705   // Check for ref counting now - handle_close() may delete eh.
01706   int requires_reference_counting =
01707     eh->reference_counting_policy ().value () ==
01708     ACE_Event_Handler::Reference_Counting_Policy::ENABLED;
01709 
01710   if (ACE_BIT_DISABLED (mask, ACE_Event_Handler::DONT_CALL))
01711     (void) eh->handle_close (handle, mask);
01712 
01713   // If there are no longer any outstanding events on the given handle
01714   // then remove it from the handler repository.
01715   if (this->handler_rep_.mask (handle) == ACE_Event_Handler::NULL_MASK)
01716     this->handler_rep_.unbind (handle, requires_reference_counting);
01717 
01718   // Note the fact that we've changed the state of the wait_set,
01719   // i.e. the "interest set," which is used by the dispatching loop to
01720   // determine whether it can keep going or if it needs to reconsult
01721   // /dev/poll or /dev/epoll.
01722   // this->state_changed_ = 1;
01723 
01724   return 0;
01725 }
01726 
01727 int
01728 ACE_Dev_Poll_Reactor::remove_handler (const ACE_Handle_Set &handle_set,
01729                                       ACE_Reactor_Mask mask)
01730 {
01731   ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler");
01732 
01733   ACE_Handle_Set_Iterator handle_iter (handle_set);
01734 
01735   ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
01736 
01737   // @@ It might be more efficient to construct a pollfd array and
01738   //    pass it to the write() call in register_handler_i() only once,
01739   //    instead of calling write() (a system call) once for each file
01740   //    descriptor.
01741 
01742   for (ACE_HANDLE h = handle_iter ();
01743        h != ACE_INVALID_HANDLE;
01744        h = handle_iter ())
01745     if (this->remove_handler_i (h, mask) == -1)
01746       return -1;
01747 
01748   return 0;
01749 }
01750 
01751 int
01752 ACE_Dev_Poll_Reactor::remove_handler (int signum,
01753                                       ACE_Sig_Action *new_disp,
01754                                       ACE_Sig_Action *old_disp,
01755                                       int sigkey)
01756 {
01757   ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler");
01758 
01759   return this->signal_handler_->remove_handler (signum,
01760                                                 new_disp,
01761                                                 old_disp,
01762                                                 sigkey);
01763 }
01764 
01765 int
01766 ACE_Dev_Poll_Reactor::remove_handler (const ACE_Sig_Set &sigset)
01767 {
01768   ACE_TRACE ("ACE_Dev_Poll_Reactor::remove_handler");
01769 
01770   int result = 0;
01771 
01772 #if (ACE_NSIG > 0)
01773 
01774   for (int s = 1; s < ACE_NSIG; ++s)
01775     if ((sigset.is_member (s) == 1)
01776         && this->signal_handler_->remove_handler (s) == -1)
01777       result = -1;
01778 
01779 #else  /* ACE_NSIG <= 0 */
01780 
01781   ACE_UNUSED_ARG (sigset);
01782 
01783 #endif /* ACE_NSIG <= 0 */
01784 
01785   return result;
01786 }
01787 
01788 int
01789 ACE_Dev_Poll_Reactor::suspend_handler (ACE_Event_Handler *event_handler)
01790 {
01791   ACE_TRACE ("ACE_Dev_Poll_Reactor::suspend_handler");
01792 
01793   if (event_handler == 0)
01794     {
01795       errno = EINVAL;
01796       return -1;
01797     }
01798 
01799   ACE_HANDLE handle = event_handler->get_handle ();
01800 
01801   ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
01802 
01803   return this->suspend_handler_i (handle);
01804 }
01805 
01806 int
01807 ACE_Dev_Poll_Reactor::suspend_handler (ACE_HANDLE handle)
01808 {
01809   ACE_TRACE ("ACE_Dev_Poll_Reactor::suspend_handler");
01810 
01811   ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
01812 
01813   return this->suspend_handler_i (handle);
01814 }
01815 
01816 int
01817 ACE_Dev_Poll_Reactor::suspend_handler (const ACE_Handle_Set &handles)
01818 {
01819   ACE_TRACE ("ACE_Dev_Poll_Reactor::suspend_handler");
01820 
01821   ACE_Handle_Set_Iterator handle_iter (handles);
01822   ACE_HANDLE h;
01823 
01824   ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
01825 
01826   while ((h = handle_iter ()) != ACE_INVALID_HANDLE)
01827     if (this->suspend_handler_i (h) == -1)
01828       return -1;
01829 
01830   return 0;
01831 }
01832 
01833 int
01834 ACE_Dev_Poll_Reactor::suspend_handlers (void)
01835 {
01836   ACE_TRACE ("ACE_Dev_Poll_Reactor::suspend_handlers");
01837 
01838   ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
01839 
01840   const size_t len = this->handler_rep_.size ();
01841 
01842   for (size_t i = 0; i < len; ++i)
01843     if (this->handler_rep_.suspended (i) == 0
01844         && this->suspend_handler_i (i) != 0)
01845       return -1;
01846 
01847   return 0;
01848 }
01849 
01850 int
01851 ACE_Dev_Poll_Reactor::suspend_handler_i (ACE_HANDLE handle)
01852 {
01853   ACE_TRACE ("ACE_Dev_Poll_Reactor::suspend_handler_i");
01854 
01855   if (this->handler_rep_.find (handle) == 0)
01856     return -1;
01857 
01858   if (this->handler_rep_.suspended (handle))
01859     return 0;  // Already suspended.  @@ Should this be an error?
01860 
01861   // Remove the handle from the "interest set."
01862   //
01863   // Note that the associated event handler is still in the handler
01864   // repository, but no events will be polled on the given handle thus
01865   // no event will be dispatched to the event handler.
01866 
01867 #if defined (ACE_HAS_EVENT_POLL)
01868 
01869   struct epoll_event epev;
01870   ACE_OS::memset (&epev, 0, sizeof (epev));
01871   static const int op = EPOLL_CTL_DEL;
01872 
01873   epev.events  = 0;
01874   epev.data.fd = handle;
01875 
01876   if (::epoll_ctl (this->poll_fd_, op, handle, &epev) == -1)
01877     return -1;
01878 
01879 #else
01880 
01881   struct pollfd pfd[1];
01882 
01883   pfd[0].fd      = handle;
01884   pfd[0].events  = POLLREMOVE;
01885   pfd[0].revents = 0;
01886 
01887   if (ACE_OS::write (this->poll_fd_, pfd, sizeof (pfd)) != sizeof (pfd))
01888     return -1;
01889 
01890 #endif  /* ACE_HAS_EVENT_POLL */
01891 
01892   this->handler_rep_.suspend (handle);
01893 
01894   return 0;
01895 }
01896 
01897 int
01898 ACE_Dev_Poll_Reactor::resume_handler (ACE_Event_Handler *event_handler)
01899 {
01900   ACE_TRACE ("ACE_Dev_Poll_Reactor::resume_handler");
01901 
01902   if (event_handler == 0)
01903     {
01904       errno = EINVAL;
01905       return -1;
01906     }
01907 
01908   ACE_HANDLE handle = event_handler->get_handle ();
01909 
01910   ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
01911 
01912   return this->resume_handler_i (handle);
01913 }
01914 
01915 int
01916 ACE_Dev_Poll_Reactor::resume_handler (ACE_HANDLE handle)
01917 {
01918   ACE_TRACE ("ACE_Dev_Poll_Reactor::resume_handler");
01919 
01920   ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
01921 
01922   return this->resume_handler_i (handle);
01923 }
01924 
01925 int
01926 ACE_Dev_Poll_Reactor::resume_handler (const ACE_Handle_Set &handles)
01927 {
01928   ACE_TRACE ("ACE_Dev_Poll_Reactor::resume_handler");
01929 
01930   ACE_Handle_Set_Iterator handle_iter (handles);
01931   ACE_HANDLE h;
01932 
01933   ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
01934 
01935   while ((h = handle_iter ()) != ACE_INVALID_HANDLE)
01936     if (this->resume_handler_i (h) == -1)
01937       return -1;
01938 
01939   return 0;
01940 }
01941 
01942 int
01943 ACE_Dev_Poll_Reactor::resume_handlers (void)
01944 {
01945   ACE_TRACE ("ACE_Dev_Poll_Reactor::resume_handlers");
01946 
01947   ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
01948 
01949   const size_t len = this->handler_rep_.size ();
01950 
01951   for (size_t i = 0; i < len; ++i)
01952     if (this->handler_rep_.suspended (i)
01953         && this->resume_handler_i (i) != 0)
01954       return -1;
01955 
01956   return 0;
01957 }
01958 
01959 int
01960 ACE_Dev_Poll_Reactor::resume_handler_i (ACE_HANDLE handle)
01961 {
01962   ACE_TRACE ("ACE_Dev_Poll_Reactor::resume_handler_i");
01963 
01964   if (this->handler_rep_.find (handle) == 0
01965       && this->handler_rep_.suspended (handle) == 0)
01966     return -1;
01967 
01968   ACE_Reactor_Mask mask = this->handler_rep_.mask (handle);
01969 
01970   if (mask == ACE_Event_Handler::NULL_MASK)
01971     return -1;
01972 
01973   // Place the handle back in to the "interest set."
01974   //
01975   // Events for the given handle will once again be polled.
01976 
01977 #if defined (ACE_HAS_EVENT_POLL)
01978 
01979   struct epoll_event epev;
01980   ACE_OS::memset (&epev, 0, sizeof (epev));
01981   static const int op = EPOLL_CTL_ADD;
01982 
01983   epev.events  = this->reactor_mask_to_poll_event (mask);
01984   epev.data.fd = handle;
01985 
01986   if (::epoll_ctl (this->poll_fd_, op, handle, &epev) == -1)
01987     return -1;
01988 
01989 #else
01990 
01991   struct pollfd pfd[1];
01992 
01993   pfd[0].fd      = handle;
01994   pfd[0].events  = this->reactor_mask_to_poll_event (mask);
01995   pfd[0].revents = 0;
01996 
01997   if (ACE_OS::write (this->poll_fd_, pfd, sizeof (pfd)) != sizeof (pfd))
01998     return -1;
01999 
02000 #endif  /* ACE_HAS_EVENT_POLL */
02001 
02002   this->handler_rep_.resume (handle);
02003 
02004   return 0;
02005 }
02006 
02007 int
02008 ACE_Dev_Poll_Reactor::resumable_handler (void)
02009 {
02010   // @@ Is this correct?
02011 
02012   return 0;
02013 }
02014 
02015 int
02016 ACE_Dev_Poll_Reactor::uses_event_associations (void)
02017 {
02018   // Since the Dev_Poll_Reactor does not do any event associations,
02019   // this method always return zero.
02020   return 0;
02021 }
02022 
02023 long
02024 ACE_Dev_Poll_Reactor::schedule_timer (ACE_Event_Handler *event_handler,
02025                                       const void *arg,
02026                                       const ACE_Time_Value &delay,
02027                                       const ACE_Time_Value &interval)
02028 {
02029   ACE_TRACE ("ACE_Dev_Poll_Reactor::schedule_timer");
02030 
02031   ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
02032 
02033   if (0 != this->timer_queue_)
02034     return this->timer_queue_->schedule
02035       (event_handler,
02036        arg,
02037        this->timer_queue_->gettimeofday () + delay,
02038        interval);
02039 
02040   errno = ESHUTDOWN;
02041   return -1;
02042 }
02043 
02044 int
02045 ACE_Dev_Poll_Reactor::reset_timer_interval (long timer_id,
02046                                             const ACE_Time_Value &interval)
02047 {
02048   ACE_TRACE ("ACE_Dev_Poll_Reactor::reset_timer_interval");
02049 
02050   ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
02051 
02052   if (0 != this->timer_queue_)
02053     return this->timer_queue_->reset_interval (timer_id, interval);
02054 
02055   errno = ESHUTDOWN;
02056   return -1;
02057 }
02058 
02059 int
02060 ACE_Dev_Poll_Reactor::cancel_timer (ACE_Event_Handler *event_handler,
02061                                     int dont_call_handle_close)
02062 {
02063   ACE_TRACE ("ACE_Dev_Poll_Reactor::cancel_timer");
02064 
02065   ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
02066 
02067   return (this->timer_queue_ == 0
02068           ? 0
02069           : this->timer_queue_->cancel (event_handler,
02070                                         dont_call_handle_close));
02071 }
02072 
02073 int
02074 ACE_Dev_Poll_Reactor::cancel_timer (long timer_id,
02075                                     const void **arg,
02076                                     int dont_call_handle_close)
02077 {
02078   ACE_TRACE ("ACE_Dev_Poll_Reactor::cancel_timer");
02079 
02080   ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
02081 
02082   return (this->timer_queue_ == 0
02083           ? 0
02084           : this->timer_queue_->cancel (timer_id,
02085                                         arg,
02086                                         dont_call_handle_close));
02087 }
02088 
02089 int
02090 ACE_Dev_Poll_Reactor::schedule_wakeup (ACE_Event_Handler *eh,
02091                                        ACE_Reactor_Mask mask)
02092 {
02093   ACE_TRACE ("ACE_Dev_Poll_Reactor::schedule_wakeup");
02094 
02095   return this->mask_ops (eh->get_handle (), mask, ACE_Reactor::ADD_MASK);
02096 }
02097 
02098 int
02099 ACE_Dev_Poll_Reactor::schedule_wakeup (ACE_HANDLE handle,
02100                                        ACE_Reactor_Mask mask)
02101 {
02102   ACE_TRACE ("ACE_Dev_Poll_Reactor::schedule_wakeup");
02103 
02104   return this->mask_ops (handle, mask, ACE_Reactor::ADD_MASK);
02105 }
02106 
02107 int
02108 ACE_Dev_Poll_Reactor::cancel_wakeup (ACE_Event_Handler *eh,
02109                                      ACE_Reactor_Mask mask)
02110 {
02111   ACE_TRACE ("ACE_Dev_Poll_Reactor::cancel_wakeup");
02112 
02113   return this->mask_ops (eh->get_handle (), mask, ACE_Reactor::CLR_MASK);
02114 }
02115 
02116 int
02117 ACE_Dev_Poll_Reactor::cancel_wakeup (ACE_HANDLE handle,
02118                                      ACE_Reactor_Mask mask)
02119 {
02120   ACE_TRACE ("ACE_Dev_Poll_Reactor::cancel_wakeup");
02121 
02122   return this->mask_ops (handle, mask, ACE_Reactor::CLR_MASK);
02123 }
02124 
02125 int
02126 ACE_Dev_Poll_Reactor::notify (ACE_Event_Handler *eh,
02127                               ACE_Reactor_Mask mask,
02128                               ACE_Time_Value *timeout)
02129 {
02130   ACE_TRACE ("ACE_Dev_Poll_Reactor::notify");
02131 
02132   ssize_t n = 0;
02133 
02134   // Pass over both the Event_Handler *and* the mask to allow the
02135   // caller to dictate which Event_Handler method the receiver
02136   // invokes.  Note that this call can timeout.
02137 
02138   n = this->notify_handler_->notify (eh, mask, timeout);
02139 
02140   return n == -1 ? -1 : 0;
02141 }
02142 
02143 void
02144 ACE_Dev_Poll_Reactor::max_notify_iterations (int iterations)
02145 {
02146   ACE_TRACE ("ACE_Dev_Poll_Reactor::max_notify_iterations");
02147 
02148   ACE_MT (ACE_GUARD (ACE_Dev_Poll_Reactor_Token, mon, this->token_));
02149 
02150   this->notify_handler_->max_notify_iterations (iterations);
02151 }
02152 
02153 int
02154 ACE_Dev_Poll_Reactor::max_notify_iterations (void)
02155 {
02156   ACE_TRACE ("ACE_Dev_Poll_Reactor::max_notify_iterations");
02157 
02158   ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
02159 
02160   return this->notify_handler_->max_notify_iterations ();
02161 }
02162 
02163 int
02164 ACE_Dev_Poll_Reactor::purge_pending_notifications (ACE_Event_Handler * eh,
02165                                                    ACE_Reactor_Mask mask)
02166 {
02167   if (this->notify_handler_ == 0)
02168     return 0;
02169 
02170   return this->notify_handler_->purge_pending_notifications (eh, mask);
02171 }
02172 
02173 ACE_Event_Handler *
02174 ACE_Dev_Poll_Reactor::find_handler (ACE_HANDLE handle)
02175 {
02176   ACE_MT (ACE_READ_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, 0));
02177 
02178   ACE_Event_Handler *event_handler = this->handler_rep_.find (handle);
02179   if (event_handler)
02180     event_handler->add_reference ();
02181   return event_handler;
02182 }
02183 
02184 int
02185 ACE_Dev_Poll_Reactor::handler (ACE_HANDLE handle,
02186                                ACE_Reactor_Mask mask,
02187                                ACE_Event_Handler **event_handler)
02188 {
02189   ACE_TRACE ("ACE_Dev_Poll_Reactor::handler");
02190 
02191   ACE_MT (ACE_READ_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
02192 
02193   ACE_Event_Handler *h = this->handler_rep_.find (handle);
02194 
02195   if (h != 0
02196       && ACE_BIT_CMP_MASK (this->handler_rep_.mask (handle),
02197                            mask,  // Compare all bits in the mask
02198                            mask))
02199     {
02200       if (event_handler != 0)
02201         *event_handler = h;
02202 
02203       return 0;
02204     }
02205 
02206   return -1;
02207 }
02208 
02209 int
02210 ACE_Dev_Poll_Reactor::handler (int signum,
02211                                ACE_Event_Handler **eh)
02212 {
02213   ACE_TRACE ("ACE_Dev_Poll_Reactor::handler");
02214 
02215   ACE_Event_Handler *handler = this->signal_handler_->handler (signum);
02216 
02217   if (handler == 0)
02218     return -1;
02219   else if (eh != 0)
02220     *eh = handler;
02221 
02222   return 0;
02223 }
02224 
02225 int
02226 ACE_Dev_Poll_Reactor::initialized (void)
02227 {
02228   ACE_TRACE ("ACE_Dev_Poll_Reactor::initialized");
02229 
02230   ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
02231 
02232   return this->initialized_;
02233 }
02234 
02235 size_t
02236 ACE_Dev_Poll_Reactor::size (void) const
02237 {
02238   return this->size_;
02239 }
02240 
02241 ACE_Lock &
02242 ACE_Dev_Poll_Reactor::lock (void)
02243 {
02244   ACE_TRACE ("ACE_Dev_Poll_Reactor::lock");
02245 
02246   return this->lock_adapter_;
02247 }
02248 
02249 void
02250 ACE_Dev_Poll_Reactor::wakeup_all_threads (void)
02251 {
02252   ACE_TRACE ("ACE_Dev_Poll_Reactor::wakeup_all_threads");
02253 
02254   // Send a notification, but don't block if there's no one to receive
02255   // it.
02256   this->notify (0,
02257                 ACE_Event_Handler::NULL_MASK,
02258                 (ACE_Time_Value *) &ACE_Time_Value::zero);
02259 }
02260 
02261 int
02262 ACE_Dev_Poll_Reactor::owner (ACE_thread_t /* new_owner */,
02263                              ACE_thread_t * /* old_owner */)
02264 {
02265   ACE_TRACE ("ACE_Dev_Poll_Reactor::owner");
02266 
02267   // There is no need to set the owner of the event loop.  Multiple
02268   // threads may invoke the event loop simulataneously.
02269 
02270   return 0;
02271 }
02272 
02273 int
02274 ACE_Dev_Poll_Reactor::owner (ACE_thread_t * /* owner */)
02275 {
02276   ACE_TRACE ("ACE_Dev_Poll_Reactor::owner");
02277 
02278   // There is no need to set the owner of the event loop.  Multiple
02279   // threads may invoke the event loop simulataneously.
02280 
02281   return 0;
02282 }
02283 
02284 int
02285 ACE_Dev_Poll_Reactor::restart (void)
02286 {
02287   ACE_TRACE ("ACE_Dev_Poll_Reactor::restart");
02288 
02289   ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
02290 
02291   return this->restart_;
02292 }
02293 
02294 int
02295 ACE_Dev_Poll_Reactor::restart (int r)
02296 {
02297   ACE_TRACE ("ACE_Dev_Poll_Reactor::restart");
02298 
02299   ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
02300 
02301   int current_value = this->restart_;
02302   this->restart_ = r;
02303   return current_value;
02304 }
02305 
02306 void
02307 ACE_Dev_Poll_Reactor::requeue_position (int)
02308 {
02309   ACE_TRACE ("ACE_Dev_Poll_Reactor::requeue_position");
02310 }
02311 
02312 int
02313 ACE_Dev_Poll_Reactor::requeue_position (void)
02314 {
02315   ACE_TRACE ("ACE_Dev_Poll_Reactor::requeue_position");
02316 
02317   ACE_NOTSUP_RETURN (-1);
02318 }
02319 
02320 int
02321 ACE_Dev_Poll_Reactor::mask_ops (ACE_Event_Handler *event_handler,
02322                                 ACE_Reactor_Mask mask,
02323                                 int ops)
02324 {
02325   ACE_TRACE ("ACE_Dev_Poll_Reactor::mask_ops");
02326 
02327   ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
02328 
02329   return this->mask_ops_i (event_handler->get_handle (), mask, ops);
02330 }
02331 
02332 int
02333 ACE_Dev_Poll_Reactor::mask_ops (ACE_HANDLE handle,
02334                                 ACE_Reactor_Mask mask,
02335                                 int ops)
02336 {
02337   ACE_TRACE ("ACE_Dev_Poll_Reactor::mask_ops");
02338 
02339   ACE_MT (ACE_GUARD_RETURN (ACE_Dev_Poll_Reactor_Token, mon, this->token_, -1));
02340 
02341   return this->mask_ops_i (handle, mask, ops);
02342 }
02343 
02344 int
02345 ACE_Dev_Poll_Reactor::mask_ops_i (ACE_HANDLE handle,
02346                                   ACE_Reactor_Mask mask,
02347                                   int ops)
02348 {
02349   ACE_TRACE ("ACE_Dev_Poll_Reactor::mask_ops_i");
02350 
02351   if (this->handler_rep_.handle_in_range (handle) == 0)
02352     return -1;
02353 
02354   // Block out all signals until method returns.
02355   ACE_Sig_Guard sb;
02356 
02357   const ACE_Reactor_Mask old_mask = this->handler_rep_.mask (handle);
02358   ACE_Reactor_Mask new_mask = old_mask;
02359 
02360   // Perform GET, CLR, SET, and ADD operations on the interest/wait
02361   // set and the suspend set (if necessary).
02362   //
02363   // GET = 1, Retrieve current value
02364   // SET = 2, Set value of bits to new mask (changes the entire mask)
02365   // ADD = 3, Bitwise "or" the value into the mask (only changes
02366   //          enabled bits)
02367   // CLR = 4  Bitwise "and" the negation of the value out of the mask
02368   //          (only changes enabled bits)
02369   //
02370   // Returns the original mask.
02371 
02372   switch (ops)
02373     {
02374     case ACE_Reactor::GET_MASK:
02375       // The work for this operation is done in all cases at the
02376       // begining of the function.
02377       return old_mask;
02378 
02379     case ACE_Reactor::CLR_MASK:
02380       ACE_CLR_BITS (new_mask, mask);
02381       break;
02382 
02383     case ACE_Reactor::SET_MASK:
02384       new_mask = mask;
02385       break;
02386 
02387     case ACE_Reactor::ADD_MASK:
02388       ACE_SET_BITS (new_mask, mask);
02389       break;
02390 
02391     default:
02392       return -1;
02393     }
02394 
02395   /// Reset the mask for the given handle.
02396   this->handler_rep_.mask (handle, new_mask);
02397 
02398   if (this->handler_rep_.suspended (handle) == 0)
02399     {
02400       // Only attempt to alter events for the handle from the
02401       // "interest set" if it hasn't been suspended.
02402 
02403       const short events = this->reactor_mask_to_poll_event (new_mask);
02404 
02405 #if defined (sun)
02406       // Apparently events cannot be updated on-the-fly on Solaris so
02407       // remove the existing events, and then add the new ones.
02408       struct pollfd pfd[2];
02409 
02410       pfd[0].fd      = handle;
02411       pfd[0].events  = POLLREMOVE;
02412       pfd[0].revents = 0;
02413       pfd[1].fd      = (events == POLLREMOVE ? ACE_INVALID_HANDLE : handle);
02414       pfd[1].events  = events;
02415       pfd[1].revents = 0;
02416 
02417       // Change the events associated with the given file descriptor.
02418       if (ACE_OS::write (this->poll_fd_,
02419                          pfd,
02420                          sizeof (pfd)) != sizeof (pfd))
02421         return -1;
02422 #elif defined (ACE_HAS_EVENT_POLL)
02423 
02424       struct epoll_event epev;
02425       ACE_OS::memset (&epev, 0, sizeof (epev));
02426       int op;
02427 
02428       // ACE_Event_Handler::NULL_MASK ???
02429       if (new_mask == 0)
02430         {
02431           op          = EPOLL_CTL_DEL;
02432           epev.events = 0;
02433         }
02434       else
02435         {
02436           op          = EPOLL_CTL_MOD;
02437           epev.events = events;
02438         }
02439 
02440       epev.data.fd = handle;
02441 
02442       if (::epoll_ctl (this->poll_fd_, op, handle, &epev) == -1)
02443         {
02444           // If a handle is closed, epoll removes it from the poll set
02445           // automatically - we may not know about it yet. If that's the
02446           // case, a mod operation will fail with ENOENT. Retry it as
02447           // an add.
02448           if (op == EPOLL_CTL_MOD && errno == ENOENT &&
02449               ::epoll_ctl (this->poll_fd_, EPOLL_CTL_ADD, handle, &epev) == -1)
02450             return -1;
02451         }
02452 
02453 #else
02454       pollfd pfd[1];
02455 
02456       pfd[0].fd      = handle;
02457       pfd[0].events  = events;
02458       pfd[0].revents = 0;
02459 
02460       // Change the events associated with the given file descriptor.
02461       if (ACE_OS::write (this->poll_fd_,
02462                          pfd,
02463                          sizeof (pfd)) != sizeof (pfd))
02464         return -1;
02465 #endif /*ACE_HAS_EVENT_POLL  */
02466     }
02467 
02468   return old_mask;
02469 }
02470 
02471 int
02472 ACE_Dev_Poll_Reactor::ready_ops (ACE_Event_Handler * /* event_handler */,
02473                                  ACE_Reactor_Mask /* mask */,
02474                                  int /* ops */)
02475 {
02476   ACE_TRACE ("ACE_Dev_Poll_Reactor::ready_ops");
02477 
02478   // Since the Dev_Poll_Reactor uses the poll result buffer, the
02479   // ready_set cannot be directly manipulated outside of the event
02480   // loop.
02481   ACE_NOTSUP_RETURN (-1);
02482 }
02483 
02484 int
02485 ACE_Dev_Poll_Reactor::ready_ops (ACE_HANDLE /* handle */,
02486                                  ACE_Reactor_Mask /* mask */,
02487                                  int /* ops */)
02488 {
02489   ACE_TRACE ("ACE_Dev_Poll_Reactor::ready_ops");
02490 
02491   // Since the Dev_Poll_Reactor uses the poll result buffer, the
02492   // ready_set cannot be directly manipulated outside of the event
02493   // loop.
02494   ACE_NOTSUP_RETURN (-1);
02495 }
02496 
02497 void
02498 ACE_Dev_Poll_Reactor::dump (void) const
02499 {
02500 #if defined (ACE_HAS_DUMP)
02501   ACE_TRACE ("ACE_Dev_Poll_Reactor::dump");
02502 
02503   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
02504   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("restart_ = %d\n"), this->restart_));
02505   ACE_DEBUG ((LM_DEBUG,
02506               ACE_LIB_TEXT ("initialized_ = %d"),
02507               this->initialized_));
02508   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("poll_fd_ = %d"), this->poll_fd_));
02509   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("size_ = %u"), this->size_));
02510   ACE_DEBUG ((LM_DEBUG,
02511               ACE_LIB_TEXT ("deactivated_ = %d"),
02512               this->deactivated_));
02513   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
02514 #endif /* ACE_HAS_DUMP */
02515 }
02516 
02517 short
02518 ACE_Dev_Poll_Reactor::reactor_mask_to_poll_event (ACE_Reactor_Mask mask)
02519 {
02520   ACE_TRACE ("ACE_Dev_Poll_Reactor::reactor_mask_to_poll_event");
02521 
02522   if (mask == ACE_Event_Handler::NULL_MASK)
02523     // No event.  Remove from interest set.
02524 #if defined (ACE_HAS_EVENT_POLL)
02525     return EPOLL_CTL_DEL;
02526 #else
02527     return POLLREMOVE;
02528 #endif /* ACE_HAS_EVENT_POLL */
02529 
02530   short events = 0;
02531 
02532   // READ, ACCEPT, and CONNECT flag will place the handle in the
02533   // read set.
02534   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::READ_MASK)
02535       || ACE_BIT_ENABLED (mask, ACE_Event_Handler::ACCEPT_MASK)
02536       || ACE_BIT_ENABLED (mask, ACE_Event_Handler::CONNECT_MASK))
02537     {
02538 #if defined (ACE_HAS_EVENT_POLL)
02539       ACE_SET_BITS (events, EPOLLIN);
02540 #else
02541       ACE_SET_BITS (events, POLLIN);
02542 #endif /*ACE_HAS_EVENT_POLL*/
02543     }
02544 
02545   // WRITE and CONNECT flag will place the handle in the write set.
02546   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::WRITE_MASK)
02547       || ACE_BIT_ENABLED (mask, ACE_Event_Handler::CONNECT_MASK))
02548     {
02549 #if defined (ACE_HAS_EVENT_POLL)
02550       ACE_SET_BITS (events, EPOLLOUT);
02551 #else
02552       ACE_SET_BITS (events, POLLOUT);
02553 #endif /*ACE_HAS_EVENT_POLL*/
02554     }
02555 
02556   // EXCEPT flag will place the handle in the except set.
02557   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::EXCEPT_MASK))
02558     {
02559 #if defined (ACE_HAS_EVENT_POLL)
02560       ACE_SET_BITS (events, EPOLLPRI);
02561 #else
02562       ACE_SET_BITS (events, POLLPRI);
02563 #endif /*ACE_HAS_EVENT_POLL*/
02564     }
02565 
02566   return events;
02567 }
02568 
02569 namespace {
02570   void polite_sleep_hook (void *) { }
02571 }
02572 
02573 int
02574 ACE_Dev_Poll_Reactor::Token_Guard::acquire_quietly (ACE_Time_Value *max_wait)
02575 {
02576   ACE_TRACE ("ACE_Dev_Poll_Reactor::Token_Guard::acquire_quietly");
02577 
02578   // Acquire the token but don't ping any waiters; just queue up politely.
02579   int result = 0;
02580   if (max_wait)
02581     {
02582       ACE_Time_Value tv = ACE_OS::gettimeofday ();
02583       tv += *max_wait;
02584 
02585       ACE_MT (result = this->token_.acquire_read (&polite_sleep_hook,
02586                                                   0,
02587                                                   &tv));
02588     }
02589   else
02590     {
02591       ACE_MT (result = this->token_.acquire_read (&polite_sleep_hook));
02592     }
02593 
02594   // Check for timeouts and errors.
02595   if (result == -1)
02596     {
02597       if (errno == ETIME)
02598         return 0;
02599       else
02600         {
02601           ACE_ERROR ((LM_ERROR, "%t: %p\n", "token acquire_read"));
02602           return -1;
02603         }
02604     }
02605 
02606   // We got the token and so let us mark ourselves as owner
02607   this->owner_ = 1;
02608 
02609   return result;
02610 }
02611 
02612 int
02613 ACE_Dev_Poll_Reactor::Token_Guard::acquire (ACE_Time_Value *max_wait)
02614 {
02615   ACE_TRACE ("ACE_Dev_Poll_Reactor::Token_Guard::acquire");
02616 
02617   // Try to grab the token.  If someone if already there, don't wake
02618   // them up, just queue up in the thread pool.
02619   int result = 0;
02620   if (max_wait)
02621     {
02622       ACE_Time_Value tv = ACE_OS::gettimeofday ();
02623       tv += *max_wait;
02624 
02625       ACE_MT (result = this->token_.acquire (0, 0, &tv));
02626     }
02627   else
02628     {
02629       ACE_MT (result = this->token_.acquire ());
02630     }
02631 
02632   // Check for timeouts and errors.
02633   if (result == -1)
02634     {
02635       if (errno == ETIME)
02636         return 0;
02637       else
02638         return -1;
02639     }
02640 
02641   // We got the token and so let us mark ourseleves as owner
02642   this->owner_ = 1;
02643 
02644   return result;
02645 }
02646 
02647 ACE_END_VERSIONED_NAMESPACE_DECL
02648 
02649 #endif  /* ACE_HAS_EVENT_POLL || ACE_HAS_DEV_POLL */

Generated on Thu Nov 9 09:41:50 2006 for ACE by doxygen 1.3.6