=default for generated implementation copy ctor
[ACE_TAO.git] / TAO / tests / HandleExhaustion / server.cpp
blob2334bbcdfc2a19f0beb94466b7d08bdf7e555d76
1 #include "TestS.h"
2 #include "ace/Get_Opt.h"
3 #include "ace/Handle_Set.h"
4 #include "ace/OS_NS_stdio.h"
5 #include "ace/OS_NS_fcntl.h"
6 #include "ace/OS_NS_unistd.h"
7 #include "ace/OS_NS_sys_resource.h"
8 #include "ace/streams.h"
10 const ACE_TCHAR *ior_output_file = ACE_TEXT ("server.ior");
12 class Test_i: public virtual POA_Test
14 public:
15 Test_i (CORBA::ORB_ptr orb)
16 : orb_ (CORBA::ORB::_duplicate (orb))
20 void simple ()
24 void shutdown ()
26 this->orb_->shutdown ();
29 private:
30 CORBA::ORB_var orb_;
33 class Descriptors
35 public:
36 Descriptors ()
37 : min_close_ (0),
38 max_close_ (0),
39 ok_ (false)
41 for (size_t i = 0; i < 0xffff; i++)
43 this->openfds_[i] = ACE_INVALID_HANDLE;
47 int allow_accepts ()
49 cout << "Server: closing " << (this->max_close_ - this->min_close_) + 1
50 << " fds" << endl;
51 for (size_t i = this->min_close_; i <= this->max_close_; i++)
53 ACE_OS::close (this->openfds_[i]);
55 return 0;
58 void leak (const ACE_TCHAR* file)
60 for (size_t i = 0; i < 0xffff; i++)
62 this->openfds_[i] = ACE_OS::open (file, O_RDONLY);
63 if (i == 0)
65 #if defined (ACE_WIN32)
66 // the test is not valid on windows so just wing this value
67 this->min_close_ = 1000;
68 #else
69 this->min_close_ = (ACE_DEFAULT_SELECT_REACTOR_SIZE - 2)
70 - (this->openfds_[i] - 1);
71 #endif /* ACE_WIN32 */
72 cout << "Server: first leaked handle is "
73 << this->openfds_[i] << " min_close is "
74 << this->min_close_ << endl;
76 this->max_close_ = i;
77 if (this->openfds_[i] == ACE_INVALID_HANDLE)
79 cout << "Server: last handle encounterd at i = " << i << endl;
80 this->ok_ = true;
81 return;
84 cout << "Server: Descriptors::leak did not saturate fdset" << endl;
87 bool ok () const
89 return this->ok_;
92 private:
93 ACE_HANDLE openfds_[0xffff];
94 size_t min_close_;
95 size_t max_close_;
96 bool ok_;
99 int
100 parse_args (int argc, ACE_TCHAR *argv[])
102 ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("o:"));
103 int c;
105 while ((c = get_opts ()) != -1)
106 switch (c)
108 case 'o':
109 ior_output_file = get_opts.opt_arg ();
110 break;
112 case '?':
113 default:
114 ACE_ERROR_RETURN ((LM_ERROR,
115 "usage: %s "
116 "-o <iorfile>"
117 "\n",
118 argv [0]),
119 -1);
121 // Indicates successful parsing of the command line
122 return 0;
126 ACE_TMAIN (int argc, ACE_TCHAR *argv[])
128 #if defined (ACE_WIN32)
129 ACE_UNUSED_ARG (argc);
130 ACE_UNUSED_ARG (argv);
131 cout << "HandleExhaustion test not available on Windows" << endl;
132 #else
135 #if !defined (ACE_LACKS_RLIMIT) && defined (RLIMIT_NOFILE)
136 // We must make sure that our file descriptor limit does not exceed
137 // the size allowed (in the fd set) by the reactor. If it does, this
138 // test will fail (in a different way than expected) which is a
139 // completely different bug than this test is designed to address
140 // (see Bug #3326).
142 // We must also make sure that this happens before creating the first
143 // ORB. Otherwise, the reactor will be created with a maximum size of
144 // the current rlimit for file desriptors (which will later on be
145 // increased).
146 rlimit rlim;
147 if (ACE_OS::getrlimit(RLIMIT_NOFILE, &rlim) == 0)
149 cout << "server evaluating rlimit, cur = "
150 << rlim.rlim_cur << " max = " << rlim.rlim_max
151 << " reactor max = "
152 << ACE_DEFAULT_SELECT_REACTOR_SIZE << endl;
153 if (rlim.rlim_cur < static_cast<rlim_t> (ACE_DEFAULT_SELECT_REACTOR_SIZE) &&
154 rlim.rlim_max > static_cast<rlim_t> (ACE_DEFAULT_SELECT_REACTOR_SIZE))
156 rlim.rlim_cur = ACE_DEFAULT_SELECT_REACTOR_SIZE;
157 rlim.rlim_max = ACE_DEFAULT_SELECT_REACTOR_SIZE;
158 ACE_OS::setrlimit(RLIMIT_NOFILE, &rlim);
159 cout << "server set rlimit_nofile" << endl;
162 #else
163 cout << "server does not support setting rlimit, reactor max = "
164 << ACE_DEFAULT_SELECT_REACTOR_SIZE << endl;
165 #endif /* !ACE_LACKS_RLIMIT && RLIMIT_NOFILE */
167 CORBA::ORB_var orb =
168 CORBA::ORB_init (argc, argv);
170 CORBA::Object_var poa_object =
171 orb->resolve_initial_references("RootPOA");
173 PortableServer::POA_var root_poa =
174 PortableServer::POA::_narrow (poa_object.in ());
176 if (CORBA::is_nil (root_poa.in ()))
177 ACE_ERROR_RETURN ((LM_ERROR,
178 " (%P|%t) Panic: nil RootPOA\n"),
181 if (parse_args (argc, argv) != 0)
182 return 1;
184 Test_i* test_i;
185 ACE_NEW_RETURN (test_i,
186 Test_i (orb.in ()),
188 PortableServer::ServantBase_var owner_transfer(test_i);
190 PortableServer::ObjectId_var id = root_poa->activate_object (test_i);
192 CORBA::Object_var object = root_poa->id_to_reference (id.in ());
194 Test_var test = Test::_narrow (object.in ());
196 CORBA::String_var ior = orb->object_to_string (test.in ());
198 // Output the IOR to the <ior_output_file>
199 FILE *output_file= ACE_OS::fopen (ior_output_file, "w");
200 if (output_file == 0)
201 ACE_ERROR_RETURN ((LM_ERROR,
202 "Cannot open output file %s for writing IOR: %C\n",
203 ior_output_file,
204 ior.in ()),
206 ACE_OS::fprintf (output_file, "%s", ior.in ());
207 ACE_OS::fclose (output_file);
209 PortableServer::POAManager_var poa_manager =
210 root_poa->the_POAManager ();
211 poa_manager->activate ();
213 Descriptors descriptors;
214 descriptors.leak (
215 #ifdef _WRS_KERNEL
216 "server.out");
217 #else
218 argv[0]);
219 #endif
221 ACE_Time_Value tv (10);
222 orb->run (tv);
224 cout << "Server: closing some fds" << endl;
226 descriptors.allow_accepts ();
227 orb->run ();
228 orb->destroy ();
230 if (!descriptors.ok ())
232 cout << "Server: the accept error never occurred" << endl;
233 ACE_ERROR_RETURN ((LM_ERROR, "The accept error never occurred\n"), 1);
236 catch (const CORBA::Exception& ex)
238 ex._tao_print_exception ("Exception caught:");
239 return 1;
241 #endif /* ACE_WIN32 */
242 return 0;