summaryrefslogtreecommitdiff
path: root/TAO/tests/CollocationLockup/CollocationLockup.cpp
blob: ad25d7cb7bdd0e86456c4c9c6d24e4bdbf0ac003 (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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/**
 * CollocationLockup.cpp
 * This is regression test against bug #2130.
 * It tests a deadlock between a thread making a collocated invocation
 * (which holds a lock on the ORB core and attempts to lock the POA) and a
 * thread activating a servant (which locks the POA and attempts to lock the
 * ORB core).
 *
 * This test was developed from a test submitted by Rick Marlborough for bug
 * #2297 and refined by Paul Calabrese.
 */

#include "ABS.h"
#include "SimpleNamingServiceC.h"

#include "ace/Thread_Manager.h"
#include "ace/SString.h"

namespace
{
  const size_t N_THREADS = 20;
  const size_t N_ITERATIONS = 100;
}

class A_i : public virtual POA_A
{
};

class B_i : public virtual POA_C
{
public:
  B_i (PortableServer::POA_ptr poa)
    : poa_ (PortableServer::POA::_duplicate (poa))
  {}

  virtual A_ptr
  makeA ()
  {
    PortableServer::ServantBase_var servant = new A_i;
    PortableServer::ObjectId_var tmp = this->poa_->activate_object (servant.in());
    CORBA::Object_var obj = this->poa_->servant_to_reference (servant.in());
    return A::_narrow (obj.in ());
  }

private:
  PortableServer::POA_var poa_;
};

// Thread for ORB->run()
ACE_THR_FUNC_RETURN OrbRunThread (void*);

// Thread to run the test
ACE_THR_FUNC_RETURN TestThread (void*);

int
ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{
  try
    {
      // Normal corba init
      CORBA::ORB_var Orb = CORBA::ORB_init (argc, argv);

      CORBA::Object_var pPoaObj =
        Orb->resolve_initial_references ("RootPOA");
      PortableServer::POA_var Poa = PortableServer::POA::_narrow (pPoaObj.in ());
      PortableServer::POAManager_var pMgr = Poa->the_POAManager ();
      pMgr->activate ();

      CORBA::Object_var pNSObj =
        Orb->resolve_initial_references ("SimpleNamingService");
      SimpleNamingService_var NameService =
        SimpleNamingService::_narrow (pNSObj.in ());

      if (CORBA::is_nil (NameService.in ()))
        {
          ACE_DEBUG ((LM_ERROR,
                      "ERROR: Could not locate the Simple Naming Service\n"));
          return 1;
        }

      ACE_Thread_Manager orb_thread;
      orb_thread.spawn (OrbRunThread, Orb.in (), THR_NEW_LWP | THR_DETACHED);

      // Setup
      PortableServer::ServantBase_var servant = new B_i (Poa.in ());
      PortableServer::ObjectId_var tmp = Poa->activate_object (servant.in());
      CORBA::Object_var b = Poa->servant_to_reference (servant.in());

      NameService->bind (b.in ());

      //Start threads
      ACE_Thread_Manager threads;
      threads.spawn_n (N_THREADS, TestThread, NameService.in ());
      ACE_DEBUG ((LM_INFO, "All threads spawned.\n"));

      threads.wait ();

      Orb->shutdown (0);
      orb_thread.wait();
      Orb->destroy ();
    } //destructor of ACE_Thread_Manager = implicit join
  catch (const CORBA::Exception& ex)
    {
      ACE_DEBUG ((LM_ERROR, "Corba Exception: %s\n", ex._info ().c_str ()));
      return 1;
    }

  return 0;
}

ACE_THR_FUNC_RETURN
OrbRunThread (void *arg)
{
  CORBA::ORB_var Orb =
    CORBA::ORB::_duplicate (reinterpret_cast<CORBA::ORB_ptr> (arg));

  try
    {
      Orb->run ();
    }
  catch (const CORBA::Exception& ex)
    {
      ACE_DEBUG ((LM_ERROR,
                  "In OrbRunThread: Corba Exception: %s\n",
                  ex._info ().c_str ()));
    }
  return 0;
}

ACE_THR_FUNC_RETURN
TestThread (void *arg)
{
  SimpleNamingService_var NameService =
    SimpleNamingService::_duplicate (reinterpret_cast<SimpleNamingService_ptr> (arg));

  try
    {
      for (size_t i (0); i < N_ITERATIONS; ++i)
        {
          CORBA::Object_var obj = NameService->resolve ();
          C_var b = C::_narrow (obj.in ());
          A_var tmp = b->makeA ();
          if (i % 50 == 0)
            ACE_DEBUG ((LM_INFO, "(%t) collocated call returned\n"));
        }
    }
  catch (const CORBA::Exception& ex)
    {
      ACE_DEBUG ((LM_ERROR,
                  "In TestThread: Corba Exception: %s\n",
                  ex._info ().c_str ()));
    }
  return 0;
}