summaryrefslogtreecommitdiff
path: root/TAO/tao/PortableServer/Non_Servant_Upcall.cpp
blob: e00befdbd1d18e326893db18efc04ca05d2065db (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
#include "tao/PortableServer/Non_Servant_Upcall.h"
#include "tao/PortableServer/Object_Adapter.h"
#include "tao/PortableServer/Root_POA.h"

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

TAO_BEGIN_VERSIONED_NAMESPACE_DECL

namespace TAO
{
  namespace Portable_Server
  {
    Non_Servant_Upcall::Non_Servant_Upcall (::TAO_Root_POA &poa)
      : object_adapter_ (poa.object_adapter ()),
        poa_ (poa),
        previous_ (0)
    {
      // Check if this is a nested non_servant_upcall.
      if (this->object_adapter_.non_servant_upcall_nesting_level_ != 0)
        {
          // Remember previous instance of non_servant_upcall.
          this->previous_ =
            this->object_adapter_.non_servant_upcall_in_progress_;

          // Assert that the thread is the same as the one before.
          ACE_ASSERT (ACE_OS::thr_equal (
                      this->object_adapter_.non_servant_upcall_thread_,
                      ACE_OS::thr_self ()));
        }

      // Remember which thread is calling the adapter activators.
      this->object_adapter_.non_servant_upcall_thread_ = ACE_OS::thr_self ();

      // Mark the fact that a non-servant upcall is in progress.
      this->object_adapter_.non_servant_upcall_in_progress_ = this;

      // Adjust the nesting level.
      this->object_adapter_.non_servant_upcall_nesting_level_++;

      // We always release
      this->object_adapter_.lock ().release ();
    }

    Non_Servant_Upcall::~Non_Servant_Upcall (void)
    {
      // Reacquire the Object Adapter lock.
      this->object_adapter_.lock ().acquire ();

      // Adjust the nesting level.
      this->object_adapter_.non_servant_upcall_nesting_level_--;

      // We are done with this nested upcall.
      this->object_adapter_.non_servant_upcall_in_progress_ = this->previous_;

      // If we are at the outer nested upcall.
      if (this->object_adapter_.non_servant_upcall_nesting_level_ == 0)
        {
          // Reset thread id.
          this->object_adapter_.non_servant_upcall_thread_ =
            ACE_OS::NULL_thread;

          // Check if all pending requests are over.
          if (this->poa_.waiting_destruction () &&
            this->poa_.outstanding_requests () == 0)
            {
              try
                {
                  this->poa_.complete_destruction_i ();
                }
              catch (const::CORBA::Exception&ex)
                {
                  // Ignore exceptions
                  ex._tao_print_exception ("TAO_POA::complete_destruction_i");
                }
            }

          // Wakeup all waiting threads.
          this->object_adapter_.non_servant_upcall_condition_.broadcast ();
        }
    }
  }
}

TAO_END_VERSIONED_NAMESPACE_DECL