summaryrefslogtreecommitdiff
path: root/TAO/tao/PI/PICurrent.cpp
blob: 8d66096a7072f0a65e039bc5f851778ed76cfbd1 (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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include "tao/PI/PICurrent.h"

#if TAO_HAS_INTERCEPTORS == 1

ACE_RCSID (tao,
           PICurrent,
           "$Id$")

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

#include "tao/PI/PICurrent_Impl.h"

#include "tao/ORB_Core.h"
#include "tao/ORB_Core_TSS_Resources.h"
#include "tao/TAO_Server_Request.h"
#include "ace/CORBA_macros.h"

TAO_BEGIN_VERSIONED_NAMESPACE_DECL

TAO::PICurrent::PICurrent (TAO_ORB_Core &orb_core)
  : orb_core_ (orb_core),
    tss_slot_ (0), // Call initialize() before use.
    slot_count_ (0) // Call initialize() before use.
{
}

TAO::PICurrent::~PICurrent (void)
{
}

CORBA::Any *
TAO::PICurrent::get_slot (PortableInterceptor::SlotId identifier)
{
  this->check_validity (identifier);

  return this->tsc ()->get_slot (identifier);
}

void
TAO::PICurrent::set_slot (PortableInterceptor::SlotId identifier,
                         const CORBA::Any &data)
{
  this->check_validity (identifier);

  this->tsc ()->set_slot (identifier, data);
}

namespace
{
  extern "C" void CleanUpPICurrent(void *object, void *)
  {
    delete static_cast<TAO::PICurrent_Impl *> (object);
  }
}

TAO::PICurrent_Impl *
TAO::PICurrent::tsc (void)
{
  TAO::PICurrent_Impl *impl =
    static_cast<TAO::PICurrent_Impl *> (
      this->orb_core_.get_tss_resource (this->tss_slot_));

  // If this TSS has not yet been set-up, give it it's own PICurrent_Impl.
  if (0 == impl)
  {
    ACE_NEW_THROW_EX (impl,
                      TAO::PICurrent_Impl,
                      CORBA::NO_MEMORY (
                        CORBA::SystemException::_tao_minor_code (
                          TAO::VMCID,
                          ENOMEM),
                        CORBA::COMPLETED_NO));

    this->orb_core_.set_tss_resource (this->tss_slot_, impl);
  }

  return impl;
}

void
TAO::PICurrent::check_validity (const PortableInterceptor::SlotId &identifier
                                )
{
  // If the slot_count is zero, no initialization has been done (if there are
  // no slots, then the PICurrent_impl object is not created as there is no
  // data to copy).
  if (0 == this->slot_count_)
    throw ::CORBA::BAD_INV_ORDER (CORBA::OMGVMCID | 14, CORBA::COMPLETED_NO);

  // No need to acquire a lock for this check.  At this point, these
  // attributes are read only.
  if (identifier >= this->slot_count_)
    throw PortableInterceptor::InvalidSlot ();
}

CORBA::ORB_ptr
TAO::PICurrent::_get_orb (void)
{
  return CORBA::ORB::_duplicate (this->orb_core_.orb ());
}

void
TAO::PICurrent::initialize (PortableInterceptor::SlotId sc
                            )
{
  // Only allow a single initialization; sc is the number of
  // allocated PICurrent data slots the end user wants. If 0
  // PICurrent is not used, as no data is to be stored.
  if ((0 == this->slot_count_) && (0 != sc))
  {
    // NOTE: This function not only adds the cleanup function
    // but ALSO allocates the TSS slot PICurrent is to use.
    // It MUST be called BEFORE we attempt to get/set any
    // PICurrent slot data.
    if (0 != orb_core_.add_tss_cleanup_func (CleanUpPICurrent, this->tss_slot_))
      throw ::CORBA::NO_MEMORY (
                   CORBA::SystemException::_tao_minor_code (
                     TAO::VMCID,
                     ENOMEM),
                   CORBA::COMPLETED_NO);

    this->slot_count_ = sc;
  }
}

TAO_END_VERSIONED_NAMESPACE_DECL

#endif  /* TAO_HAS_INTERCEPTORS == 1 */