summaryrefslogtreecommitdiff
path: root/TAO/tao/Transport_Acceptor.cpp
blob: bdf634c708b55ac6c596e3ec69714fa7665f5c7f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// -*- C++ -*-
#include "tao/Transport_Acceptor.h"
#include "ace/Reactor.h"
#include "tao/debug.h"

#if !defined (__ACE_INLINE__)
# include "tao/Transport_Acceptor.inl"
#endif /* __ACE_INLINE__ */

TAO_BEGIN_VERSIONED_NAMESPACE_DECL

TAO_Acceptor::TAO_Acceptor (CORBA::ULong tag)
  : tag_ (tag),
    error_retry_delay_ (5)
{
}

TAO_Acceptor::~TAO_Acceptor ()
{
}

int
TAO_Acceptor::handle_accept_error (ACE_Event_Handler* base_acceptor)
{
  if (errno == EMFILE || errno == ENFILE)
    {
      if (TAO_debug_level > 0)
        TAOLIB_DEBUG ((LM_DEBUG, "TAO (%P|%t) - "
                              "TAO_Acceptor::handle_accept_error - "
                              "Too many files open\n"));

      // If the user has decided to stop accepting when the file handles
      // run out, just return -1;
      if (this->error_retry_delay_ == 0)
        return -1;

      // Get the reactor.  If there isn't one, which isn't very likely,
      // then just return -1.
      ACE_Reactor* reactor = base_acceptor->reactor ();
      if (reactor == nullptr)
        return -1;

      // So that the reactor doesn't completely remove this handler from
      // the reactor, register it with the except mask.  It should be
      // removed in the timer handler.
      reactor->register_handler (base_acceptor,
                                 ACE_Event_Handler::EXCEPT_MASK);

      // Remove the handler so that the reactor doesn't attempt to
      // process this handle again (and tightly spin).
      reactor->remove_handler (base_acceptor,
                               ACE_Event_Handler::ACCEPT_MASK |
                               ACE_Event_Handler::DONT_CALL);

      // Schedule a timer so that we can resume the handler in hopes
      // that some file handles have freed up.
      ACE_Time_Value timeout (this->error_retry_delay_);
      reactor->schedule_timer (base_acceptor, nullptr, timeout);
    }

  // We want to keep accepting in all other situations.
  return 0;
}

int
TAO_Acceptor::handle_expiration (ACE_Event_Handler* base_acceptor)
{
  // Get the reactor.  If there isn't one, which isn't very likely, then
  // just return -1;
  ACE_Reactor* reactor = base_acceptor->reactor ();
  if (reactor == nullptr)
    return -1;

  if (TAO_debug_level > 0)
    TAOLIB_DEBUG ((LM_DEBUG, "TAO (%P|%t) - "
                          "TAO_Acceptor::handle_expiration - "
                          "Re-registering the acceptor\n"));

  // Try again to allow incoming connections
  reactor->register_handler (base_acceptor, ACE_Event_Handler::ACCEPT_MASK);

  // Remove the except mask that was added during the handling of the
  // accept() error.  That is the only reason that we're in this method
  // in the first place.
  reactor->remove_handler (base_acceptor, ACE_Event_Handler::EXCEPT_MASK |
                                          ACE_Event_Handler::DONT_CALL);
  return 0;
}

TAO_END_VERSIONED_NAMESPACE_DECL