Merge pull request #2301 from sonndinh/remove-dup-reactor-functions
[ACE_TAO.git] / TAO / tao / Storable_File_Guard.cpp
blob583dbbb34e99e08f135288874875b03aacaaff80
1 //=============================================================================
2 /**
3 * @file Storable_File_Guard.cpp
5 * @author Rich Seibel (seibelr@ociweb.com)
6 * @author Byron Harris (harrisb@ociweb.com)
7 */
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)
18 : fl_(nullptr)
19 , redundant_(redundant)
20 , closed_(1)
21 , rwflags_(0)
22 , use_backup_(use_backup)
26 TAO::Storable_File_Guard::
27 ~Storable_File_Guard () noexcept(false)
29 delete fl_;
32 void
33 TAO::Storable_File_Guard::init_no_load(Method_Type method_type)
35 ACE_CString mode;
36 this->rwflags_ = 0;
37 switch (method_type)
39 case ACCESSOR:
40 case CREATE_WITH_FILE:
41 mode = "r";
42 this->rwflags_ = mode_read;
43 break;
44 case CREATE_WITHOUT_FILE:
45 mode = "rwc";
46 this->rwflags_ = mode_write | mode_create;
47 break;
48 case MUTATOR:
49 mode = "rw";
50 this->rwflags_ = mode_read | mode_write;
51 break;
54 if( rwflags_ <= 0 )
56 errno = EINVAL;
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();
66 // Create the stream
67 fl_ = this->create_stream(mode.c_str ());
70 void
71 TAO::Storable_File_Guard::reload ()
73 if (redundant_)
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)
89 fl_->close ();
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
101 closed_ = 0;
103 if ( ! (rwflags_ & mode_create) )
105 // Check if our copy is up to date
106 if (this->object_obsolete ())
108 this->mark_object_current ();
109 this->load ();
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
130 closed_ = 0;
132 if (file_has_data && ! this->is_loaded_from_stream ())
134 this->load ();
139 void
140 TAO::Storable_File_Guard::init(Method_Type method_type)
142 this->init_no_load (method_type);
143 this->reload ();
146 bool
147 TAO::Storable_File_Guard::object_obsolete ()
148 { // Default implementation uses time to determine
149 // if obsolete.
150 return (fl_->last_changed () > this->get_object_last_changed ());
153 void
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 ());
160 void
161 TAO::Storable_File_Guard::release ()
163 if ( ! closed_ )
165 if (this->use_backup_ &&
166 (rwflags_ & mode_write) != 0)
168 fl_->create_backup ();
171 // If we updated the disk, save the time stamp
172 if(redundant_)
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.
179 fl_->sync ();
181 this->mark_object_current ();
184 // Release the lock
185 fl_->funlock (0, 0, 0);
187 fl_->close ();
188 closed_ = 1;
193 TAO::Storable_Base &
194 TAO::Storable_File_Guard::peer ()
196 return *fl_;
200 TAO::Storable_File_Guard::load ()
202 int result = 0;
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.
230 if (!result)
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")));
245 throw;
247 TAOLIB_ERROR ((LM_INFO,
248 ACE_TEXT ("TAO: (%P|%t) The state was restored ")
249 ACE_TEXT ("from backup.\n")));
251 else
253 TAOLIB_ERROR ((LM_ERROR,
254 ACE_TEXT ("TAO: (%P|%t) ERROR: Could not read ")
255 ACE_TEXT ("backup file\n")));
256 throw;
261 // Return a result value for the load operation.
262 return result;