1 //=============================================================================
3 * @file Storable_File_Guard.cpp
5 * @author Rich Seibel (seibelr@ociweb.com)
6 * @author Byron Harris (harrisb@ociweb.com)
8 //=============================================================================
10 #include "tao/Storable_File_Guard.h"
11 #include "tao/Storable_Base.h"
13 #include "tao/SystemException.h"
14 #include "tao/debug.h"
16 TAO::Storable_File_Guard::
17 Storable_File_Guard (bool redundant
, bool use_backup
)
19 , redundant_(redundant
)
22 , use_backup_(use_backup
)
26 TAO::Storable_File_Guard::
27 ~Storable_File_Guard () noexcept(false)
33 TAO::Storable_File_Guard::init_no_load(Method_Type method_type
)
40 case CREATE_WITH_FILE
:
42 this->rwflags_
= mode_read
;
44 case CREATE_WITHOUT_FILE
:
46 this->rwflags_
= mode_write
| mode_create
;
50 this->rwflags_
= mode_read
| mode_write
;
57 if (TAO_debug_level
> 0)
59 TAOLIB_DEBUG ((LM_DEBUG
,
60 ACE_TEXT ("(%P|%t) Storable_File_Guard:Invalid ")
61 ACE_TEXT ("flags\n")));
63 throw CORBA::PERSIST_STORE();
67 fl_
= this->create_stream(mode
.c_str ());
71 TAO::Storable_File_Guard::reload ()
75 if (fl_
->open () != 0)
77 if (TAO_debug_level
> 0)
79 TAOLIB_DEBUG ((LM_DEBUG
,
80 ACE_TEXT ("(%P|%t) Storable_File_Guard::Open ")
81 ACE_TEXT ("failed in redundant\n")));
83 throw CORBA::PERSIST_STORE();
86 // acquire a lock on it
87 if (fl_
->flock (0, 0, 0) != 0)
90 if (TAO_debug_level
> 0)
92 TAOLIB_DEBUG ((LM_DEBUG
,
93 ACE_TEXT ("(%P|%t) Storable_File_Guard:flock ")
94 ACE_TEXT ("failed in redundant\n")));
96 throw CORBA::INTERNAL();
99 // now that the file is successfully opened and locked it must be
100 // unlocked/closed before we leave this class
103 if ( ! (rwflags_
& mode_create
) )
105 // Check if our copy is up to date
106 if (this->object_obsolete ())
108 this->mark_object_current ();
113 else if ( ! this->is_loaded_from_stream () || (rwflags_
& mode_write
) )
115 bool file_has_data
= fl_
->exists ();
117 if (fl_
->open () != 0)
119 if (TAO_debug_level
> 0)
121 TAOLIB_DEBUG ((LM_DEBUG
,
122 ACE_TEXT ("(%P|%t) Storable_File_Guard:Open ")
123 ACE_TEXT ("failed in non-redundant\n")));
125 throw CORBA::PERSIST_STORE ();
128 // now that the file is successfully opened
129 // unlocked/closed before we leave this class
132 if (file_has_data
&& ! this->is_loaded_from_stream ())
140 TAO::Storable_File_Guard::init(Method_Type method_type
)
142 this->init_no_load (method_type
);
147 TAO::Storable_File_Guard::object_obsolete ()
148 { // Default implementation uses time to determine
150 return (fl_
->last_changed () > this->get_object_last_changed ());
154 TAO::Storable_File_Guard::mark_object_current ()
155 { // Default implementation is to set the last changed
156 // time to that of the file lock.
157 this->set_object_last_changed (fl_
->last_changed ());
161 TAO::Storable_File_Guard::release ()
165 if (this->use_backup_
&&
166 (rwflags_
& mode_write
) != 0)
168 fl_
->create_backup ();
171 // If we updated the disk, save the time stamp
174 if( rwflags_
& mode_write
)
176 // This is a costly call, but necessary if
177 // we are running redundant. It ensures that
178 // the data is written to disk.
181 this->mark_object_current ();
185 fl_
->funlock (0, 0, 0);
194 TAO::Storable_File_Guard::peer ()
200 TAO::Storable_File_Guard::load ()
203 if (!this->use_backup_
)
204 { // Not using a backup file. Just attempt to
205 // load from the stream and return.
206 return this->load_from_stream ();
209 // We are using a backup.
212 // Attempt to load from the stream from the primary.
213 result
= this->load_from_stream ();
215 catch (const Storable_Read_Exception
&ex
)
216 { // Failed to load from primary.
217 ACE_CString state_str
= Storable_Base::state_as_string (ex
.get_state());
219 TAOLIB_ERROR ((LM_ERROR
,
220 ACE_TEXT ("TAO: (%P|%t) ERROR: State %s ")
221 ACE_TEXT ("encountered reading persistent ")
222 ACE_TEXT ("state from file\n%s\n"),
223 state_str
.c_str (), ex
.get_file_name().c_str ()));
225 // The following opens the backup file, and copies it
226 // to the primary file location.
227 result
= this->fl_
->restore_backup ();
229 // result of 0 means OK. We should now have a good primary file.
232 TAOLIB_ERROR ((LM_INFO
,
233 ACE_TEXT ("TAO: (%P|%t) Attempting to restore ")
234 ACE_TEXT ("from backup\n")));
237 { // Load the data from the newly restored primary.
238 result
= this->load_from_stream ();
240 catch (const Storable_Read_Exception
&)
241 { // Still having trouble reading from the file. Time to bail.
242 TAOLIB_ERROR ((LM_ERROR
,
243 ACE_TEXT ("TAO: (%P|%t) ERROR: Unable to restore ")
244 ACE_TEXT ("the state from backup.\n")));
247 TAOLIB_ERROR ((LM_INFO
,
248 ACE_TEXT ("TAO: (%P|%t) The state was restored ")
249 ACE_TEXT ("from backup.\n")));
253 TAOLIB_ERROR ((LM_ERROR
,
254 ACE_TEXT ("TAO: (%P|%t) ERROR: Could not read ")
255 ACE_TEXT ("backup file\n")));
261 // Return a result value for the load operation.