Updated logging to include the class/method so that it is more obvious where these...
[ACE_TAO.git] / TAO / tao / Storable_File_Guard.cpp
blob8f595d7de08ffdb58600b690db973e04289bb6d9
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)
36 ACE_CString mode;
37 this->rwflags_ = 0;
38 switch (method_type)
40 case ACCESSOR:
41 case CREATE_WITH_FILE:
42 mode = "r";
43 this->rwflags_ = mode_read;
44 break;
45 case CREATE_WITHOUT_FILE:
46 mode = "rwc";
47 this->rwflags_ = mode_write | mode_create;
48 break;
49 case MUTATOR:
50 mode = "rw";
51 this->rwflags_ = mode_read | mode_write;
52 break;
55 if( rwflags_ <= 0 )
57 errno = EINVAL;
58 if (TAO_debug_level > 0)
60 TAOLIB_DEBUG ((LM_DEBUG,
61 ACE_TEXT ("(%P|%t) Storable_File_Guard:Invalid ")
62 ACE_TEXT ("flags\n")));
64 throw CORBA::PERSIST_STORE();
67 // Create the stream
68 fl_ = this->create_stream(mode.c_str ());
71 void
72 TAO::Storable_File_Guard::reload ()
74 if (redundant_)
76 if (fl_->open () != 0)
78 if (TAO_debug_level > 0)
80 TAOLIB_DEBUG ((LM_DEBUG,
81 ACE_TEXT ("(%P|%t) Storable_File_Guard::Open ")
82 ACE_TEXT ("failed in redundant\n")));
84 throw CORBA::PERSIST_STORE();
87 // acquire a lock on it
88 if (fl_->flock (0, 0, 0) != 0)
90 fl_->close ();
91 if (TAO_debug_level > 0)
93 TAOLIB_DEBUG ((LM_DEBUG,
94 ACE_TEXT ("(%P|%t) Storable_File_Guard:flock ")
95 ACE_TEXT ("failed in redundant\n")));
97 throw CORBA::INTERNAL();
100 // now that the file is successfully opened and locked it must be
101 // unlocked/closed before we leave this class
102 closed_ = 0;
104 if ( ! (rwflags_ & mode_create) )
106 // Check if our copy is up to date
107 if (this->object_obsolete ())
109 this->mark_object_current ();
110 this->load ();
114 else if ( ! this->is_loaded_from_stream () || (rwflags_ & mode_write) )
116 bool file_has_data = fl_->exists ();
118 if (fl_->open () != 0)
120 if (TAO_debug_level > 0)
122 TAOLIB_DEBUG ((LM_DEBUG,
123 ACE_TEXT ("(%P|%t) Storable_File_Guard:Open ")
124 ACE_TEXT ("failed in non-redundant\n")));
126 throw CORBA::PERSIST_STORE ();
129 // now that the file is successfully opened
130 // unlocked/closed before we leave this class
131 closed_ = 0;
133 if (file_has_data && ! this->is_loaded_from_stream ())
135 this->load ();
140 void
141 TAO::Storable_File_Guard::init(Method_Type method_type)
143 this->init_no_load (method_type);
144 this->reload ();
147 bool
148 TAO::Storable_File_Guard::object_obsolete ()
149 { // Default implementation uses time to determine
150 // if obsolete.
151 return (fl_->last_changed () > this->get_object_last_changed ());
154 void
155 TAO::Storable_File_Guard::mark_object_current ()
156 { // Default implementation is to set the last changed
157 // time to that of the file lock.
158 this->set_object_last_changed (fl_->last_changed ());
161 void
162 TAO::Storable_File_Guard::release ()
164 if ( ! closed_ )
166 if (this->use_backup_ &&
167 (rwflags_ & mode_write) != 0)
169 fl_->create_backup ();
172 // If we updated the disk, save the time stamp
173 if(redundant_)
175 if( rwflags_ & mode_write )
177 // This is a costly call, but necessary if
178 // we are running redundant. It ensures that
179 // the data is written to disk.
180 fl_->sync ();
182 this->mark_object_current ();
185 // Release the lock
186 fl_->funlock (0, 0, 0);
188 fl_->close ();
189 closed_ = 1;
194 TAO::Storable_Base &
195 TAO::Storable_File_Guard::peer ()
197 return *fl_;
201 TAO::Storable_File_Guard::load ()
203 int result = 0;
204 if (!this->use_backup_)
205 { // Not using a backup file. Just attempt to
206 // load from the stream and return.
207 return this->load_from_stream ();
210 // We are using a backup.
213 // Attempt to load from the stream from the primary.
214 result = this->load_from_stream ();
216 catch (const Storable_Read_Exception &ex)
217 { // Failed to load from primary.
218 ACE_CString state_str = Storable_Base::state_as_string (ex.get_state());
220 TAOLIB_ERROR ((LM_ERROR,
221 ACE_TEXT ("TAO: (%P|%t) ERROR: State %s ")
222 ACE_TEXT ("encountered reading persistent ")
223 ACE_TEXT ("state from file\n%s\n"),
224 state_str.c_str (), ex.get_file_name().c_str ()));
226 // The following opens the backup file, and copies it
227 // to the primary file location.
228 result = this->fl_->restore_backup ();
230 // result of 0 means OK. We should now have a good primary file.
231 if (!result)
234 TAOLIB_ERROR ((LM_INFO,
235 ACE_TEXT ("TAO: (%P|%t) Attempting to restore ")
236 ACE_TEXT ("from backup\n")));
239 { // Load the data from the newly restored primary.
240 result = this->load_from_stream ();
242 catch (const Storable_Read_Exception&)
243 { // Still having trouble reading from the file. Time to bail.
244 TAOLIB_ERROR ((LM_ERROR,
245 ACE_TEXT ("TAO: (%P|%t) ERROR: Unable to restore ")
246 ACE_TEXT ("the state from backup.\n")));
247 throw;
249 TAOLIB_ERROR ((LM_INFO,
250 ACE_TEXT ("TAO: (%P|%t) The state was restored ")
251 ACE_TEXT ("from backup.\n")));
253 else
255 TAOLIB_ERROR ((LM_ERROR,
256 ACE_TEXT ("TAO: (%P|%t) ERROR: Could not read ")
257 ACE_TEXT ("backup file\n")));
258 throw;
263 // Return a result value for the load operation.
264 return result;