2 //=============================================================================
4 * @file FT_TestReplica_i.cpp
6 * Implements CORBA interface TestReplica.
8 * @author Dale Wilson <wilson_d@ociweb.com>
10 //=============================================================================
13 #include "FT_TestReplica_i.h"
14 #include "FT_ReplicaFactory_i.h"
15 #include "tao/ORB_Constants.h"
16 #include "FT_TestReplicaC.h"
17 // FUZZ: disable check_for_streams_include
18 #include "ace/streams.h"
19 #include "ace/OS_NS_stdio.h"
27 * Endian neutral store of long into indexable object.
28 * BUFFER can be sequence of Octet, unsigned char[], etc.
30 * TODO: Find this a good home.
32 * @param state an object that supports char & operator[] (size_t index);
33 * @param offset is the position within state where the first character should be stored.
34 * @param value is the data to be inserted into state.
36 template<typename BUFFER
>
37 void storeLong(BUFFER
& state
, size_t offset
, long value
)
39 state
[offset
] = static_cast<unsigned char> (value
>> 24);
40 state
[offset
+ 1] = static_cast<unsigned char> (value
>> 16);
41 state
[offset
+ 2] = static_cast<unsigned char> (value
>> 8);
42 state
[offset
+ 3] = static_cast<unsigned char> (value
);
46 * Endian neutral load of long from indexable object.
47 * BUFFER can be sequence of Octet, unsigned char[], etc.
49 * TODO: Find this a good home.
51 * @param state an object that supports const char & operator[] (size_t index) const;
52 * @param offset is the position within state where the first character can be found
53 * @returns value is the data loaded from state.
55 template<typename BUFFER
>
56 long loadLong(const BUFFER
& state
, size_t offset
)
59 = ((state
[offset
] & 0xFF) << 24)
60 | ((state
[offset
+ 1] & 0xFF) << 16)
61 | ((state
[offset
+ 2] & 0xFF) << 8)
62 | ((state
[offset
+ 3] & 0xFF) );
67 // NO_RESPONSE ->no reinvocation
69 #define FAULT_CODE CORBA::TRANSIENT
71 // Macros to simplify suicide.
72 #define KEVORKIAN(value, method) \
73 if (this->death_pending_ == (FT_TEST::TestReplica::value)){ \
74 suicide (#value " in method " #method); \
76 CORBA::SystemException::_tao_minor_code ( \
79 CORBA::COMPLETED_NO); \
82 #define KEVORKIAN_DURING(method) \
83 if (this->death_pending_ == FT_TEST::TestReplica::BEFORE_REPLY ){\
84 suicide ("read-only method " #method); \
86 CORBA::SystemException::_tao_minor_code ( \
89 CORBA::COMPLETED_NO); \
92 #define KEVORKIAN_RETURN(value, method, result) \
93 if (this->death_pending_ == (FT_TEST::TestReplica::value)){ \
94 suicide (#value " in method " #method); \
96 CORBA::SystemException::_tao_minor_code ( \
99 CORBA::COMPLETED_NO); \
102 #define KEVORKIAN_DURING_RETURN(method, result) \
103 if (this->death_pending_ == FT_TEST::TestReplica::BEFORE_REPLY ){\
104 suicide ("read-only method " #method); \
106 CORBA::SystemException::_tao_minor_code ( \
109 CORBA::COMPLETED_NO); \
113 //////////////////////////////////////////////////
114 // class FT_TestReplica_i construction/destruction
116 FT_TestReplica_i::FT_TestReplica_i (FT_ReplicaFactory_i
* factory
, const char * name
, unsigned long factory_id
)
117 : death_pending_ (FT_TEST::TestReplica::NOT_YET
)
120 , factory_id_ (factory_id
)
125 , name_persistent_storage (0)
127 // cout << name_.c_str() << '@' << this->factory_->location() << '#' << this->factory_id_ << " Construct" << endl;
130 FT_TestReplica_i::~FT_TestReplica_i ()
132 // cout << name_.c_str() << '@' << this->factory_->location() << '#' << this->factory_id_ << " Destruct" << endl;
136 void FT_TestReplica_i::suicide(const char * note
)
138 ACE_OS::fprintf (stdout
, "%s@%s#%lu Simulate FAULT_CODE fault: %s\n",
139 name_
.c_str(), this->factory_
->location(), this->factory_id_
, note
);
141 // Tell the poa we aren't accepting future calls
142 this->poa_
->deactivate_object (this->object_id_
.in ());
145 /////////////////////////////////////////////////////
146 // class FT_TestReplica_i public, non-CORBA interface
150 const char * FT_TestReplica_i::repository_id()
153 FT_TEST::_tc_TestReplica
->id();
159 FT_TestReplica_i::parse_args (int argc
, ACE_TCHAR
*argv
[])
161 ACE_UNUSED_ARG (argc
);
162 ACE_UNUSED_ARG (argv
);
168 FT_TestReplica_i::usage_options()
173 unsigned long FT_TestReplica_i::factory_id()const
175 return this->factory_id_
;
178 ::PortableServer::POA_ptr
FT_TestReplica_i::_default_POA ()
180 return ::PortableServer::POA::_duplicate(this->poa_
.in ());
183 PortableServer::ObjectId
FT_TestReplica_i::object_id()const
185 return this->object_id_
.in();
190 * Initialize this object.
191 * @param orbManager our ORB -- we keep var to it.
192 * @return zero for success; nonzero is process return code for failure.
194 int FT_TestReplica_i::init (CORBA::ORB_var
& orb
, const ACE_TCHAR
* file_persistent
)
198 this->name_persistent_storage
= file_persistent
;
200 // Use the ROOT POA for now
201 CORBA::Object_var poa_object
=
202 this->orb_
->resolve_initial_references (TAO_OBJID_ROOTPOA
);
204 if (CORBA::is_nil (poa_object
.in ()))
205 ACE_ERROR_RETURN ((LM_ERROR
,
206 ACE_TEXT (" (%P|%t) Unable to initialize the POA.\n")),
209 // Get the POA object.
211 PortableServer::POA::_narrow (poa_object
.in ());
214 if (CORBA::is_nil(this->poa_
.in ()))
216 ACE_ERROR_RETURN ((LM_ERROR
,
217 ACE_TEXT (" (%P|%t) Unable to narrow the POA.\n")),
221 PortableServer::POAManager_var poa_manager
=
222 this->poa_
->the_POAManager ();
224 poa_manager
->activate ();
227 // Register with the POA.
229 this->object_id_
= this->poa_
->activate_object (this);
234 void FT_TestReplica_i::_remove_ref ()
236 //////////////////////////////////////////////////
237 // WARNING: The following call invokes fini then deletes this object
238 this->factory_
->remove_replica(this->factory_id_
, this);
241 int FT_TestReplica_i::fini ()
247 /////////////////////////////////////////////////////
248 // class FT_TestReplica_i: PullMonitorable interface
249 CORBA::Boolean
FT_TestReplica_i::is_alive ()
251 KEVORKIAN_RETURN(DURING_IS_ALIVE
, is_alive
, 0)
252 ACE_ERROR ((LM_ERROR
,
253 "%s@%s#%d: is_alive: %d\n",
255 this->factory_
->location(),
257 (this->death_pending_
!= FT_TEST::TestReplica::DENY_IS_ALIVE
)
260 return this->death_pending_
!= FT_TEST::TestReplica::DENY_IS_ALIVE
;
263 /////////////////////////////////////////////////////
264 // class FT_TestReplica_i: Updateable interface
265 FT::State
* FT_TestReplica_i::get_update ()
267 KEVORKIAN_RETURN(DURING_GET_UPDATE
, get_update
, 0)
268 long counter
= load();
269 ::FT::State_var vState
= new ::FT::State
;
270 vState
->length(sizeof(counter
));
271 storeLong(vState
, 0, counter
);
272 return vState
._retn();
275 void FT_TestReplica_i::set_update (const FT::State
& s
)
277 #if defined(FT_TEST_LACKS_UPDATE)
278 throw FT::InvalidUpdate ();
279 #else // FT_TEST_LACKS_UPDATE
280 KEVORKIAN(BEFORE_SET_UPDATE
, set_update
)
281 long counter
= loadLong
<FT::State
>(s
, 0);
283 KEVORKIAN(AFTER_SET_UPDATE
, set_update
)
284 #endif // FT_TEST_LACKS_UPDATE
287 /////////////////////////////////////////////////////
288 // class FT_TestReplica_i: Checkpointable interface
289 ::FT::State
* FT_TestReplica_i::get_state ()
291 #if defined(FT_TEST_LACKS_STATE)
292 throw FT::NoStateAvailable ();
293 #else // FT_TEST_LACKS_STATE
294 KEVORKIAN_RETURN(DURING_GET_STATE
, get_state
, 0)
295 long counter
= load();
296 ::FT::State_var vState
= new ::FT::State
;
297 vState
->length(sizeof(counter
));
298 storeLong(vState
, 0, counter
);
299 return vState
._retn();
300 #endif // FT_TEST_LACKS_STATE
303 void FT_TestReplica_i::set_state (const FT::State
& s
)
305 #if defined(FT_TEST_LACKS_STATE)
306 throw FT::InvalidState ();
307 #else // FT_TEST_LACKS_STATE
308 KEVORKIAN(BEFORE_SET_STATE
, set_state
)
309 long counter
= loadLong
<FT::State
>(s
, 0);
311 KEVORKIAN(AFTER_SET_STATE
, set_state
)
312 #endif // FT_TEST_LACKS_STATE
315 void FT_TestReplica_i::tao_update_object_group (
317 PortableGroup::ObjectGroupRefVersion version
,
318 CORBA::Boolean is_primary
321 ACE_UNUSED_ARG (iogr
);
322 ACE_UNUSED_ARG (version
);
323 ACE_UNUSED_ARG (is_primary
);
325 throw CORBA::NO_IMPLEMENT();
328 //////////////////////////////
329 // implement FT_TEST::Replica
331 void FT_TestReplica_i::set (CORBA::Long value
)
333 KEVORKIAN(BEFORE_STATE_CHANGE
, set
)
334 long counter
= value
;
336 KEVORKIAN(BEFORE_REPLY
, set
)
339 CORBA::Long
FT_TestReplica_i::increment (CORBA::Long delta
)
341 KEVORKIAN_RETURN(BEFORE_STATE_CHANGE
, increment
, 0)
342 long counter
= load ();
345 KEVORKIAN_RETURN(BEFORE_REPLY
, increment
, 0)
349 CORBA::Long
FT_TestReplica_i::get ()
351 KEVORKIAN_DURING_RETURN(get
, 0)
352 long counter
= load ();
356 CORBA::Long
FT_TestReplica_i::counter ()
358 KEVORKIAN_DURING_RETURN([get
]counter
, 0)
359 long counter
= load ();
363 void FT_TestReplica_i::counter (CORBA::Long counter
)
365 KEVORKIAN(BEFORE_STATE_CHANGE
, [set
]counter
)
367 KEVORKIAN(BEFORE_REPLY
, [set
]counter
)
370 void FT_TestReplica_i::die (FT_TEST::TestReplica::Bane when
)
372 ACE_OS::fprintf (stdout
, "%s@%s#%lu Received death threat: %d\n",
373 name_
.c_str(), this->factory_
->location(), this->factory_id_
, when
);
375 this->death_pending_
= when
;
376 KEVORKIAN(RIGHT_NOW
, die
)
379 void FT_TestReplica_i::shutdown ()
381 ACE_OS::fprintf (stdout
, "%s@%s#%lu Shut down requested\n",
382 name_
.c_str(), this->factory_
->location(), this->factory_id_
);
383 this->death_pending_
= FT_TEST::TestReplica::CLEAN_EXIT
;
386 //////////////////////////////////////////////
387 // FT_TestReplica_i public non-CORBA interface
388 int FT_TestReplica_i::idle (int & result
)
391 if (this->death_pending_
== FT_TEST::TestReplica::WHILE_IDLE
)
393 ACE_ERROR ((LM_ERROR
,
394 "%s@%s#%d: Simulated fault WHILE_IDLE",
396 this->factory_
->location(),
397 static_cast<int> (this->factory_id_
)
399 this->poa_
->deactivate_object (this->object_id_
.in ());
403 else if (this->death_pending_
== FT_TEST::TestReplica::CLEAN_EXIT
)
405 this->poa_
->deactivate_object (this->object_id_
.in ());
412 void FT_TestReplica_i::request_quit()
414 this->death_pending_
= FT_TEST::TestReplica::WHILE_IDLE
;
418 void FT_TestReplica_i::store(long counter
)
420 FILE * f
= ACE_OS::fopen(this->name_persistent_storage
, "w");
423 unsigned char* buffer
= 0;
424 ACE_NEW (buffer
, unsigned char [sizeof(long)]);
425 storeLong(buffer
, 0, counter
);
426 ACE_OS::fwrite(buffer
, 1, sizeof(long), f
);
430 ACE_OS::fprintf (stdout
, "%s@%s#%lu :%ld\n",
431 name_
.c_str(), this->factory_
->location(), this->factory_id_
, counter
);
438 long FT_TestReplica_i::load ()
441 FILE * f
= ACE_OS::fopen(this->name_persistent_storage
,"r");
444 unsigned char buffer
[sizeof(long)];
445 ACE_OS::fread(buffer
, 1, sizeof(long), f
);
447 counter
= loadLong
<unsigned char *>(buffer
, 0);