Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

omniEventsLog.cc

Go to the documentation of this file.
00001 // -*- Mode: C++; -*-
00002 //                            Package   : omniEvents
00003 //  omniEventsLog.cc          Created   : 1/10/99
00004 //                            Author    : Paul Nader (pwn)
00005 //
00006 //    Copyright (C) 1998 Paul Nader, 2003-2005 Alex Tingle.
00007 //
00008 //    This file is part of the omniEvents application.
00009 //
00010 //    omniEvents is free software; you can redistribute it and/or
00011 //    modify it under the terms of the GNU Lesser General Public
00012 //    License as published by the Free Software Foundation; either
00013 //    version 2.1 of the License, or (at your option) any later version.
00014 //
00015 //    omniEvents is distributed in the hope that it will be useful,
00016 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 //    Lesser General Public License for more details.
00019 //
00020 //    You should have received a copy of the GNU Lesser General Public
00021 //    License along with this library; if not, write to the Free Software
00022 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023 //
00024 // Description:
00025 //      
00026 
00027 /*
00028   $Log: omniEventsLog.cc,v $
00029   Revision 1.20.2.3  2005/05/10 14:28:11  alextingle
00030   Updated copyrights to 2005.
00031 
00032   Revision 1.20.2.2  2005/05/04 23:06:02  alextingle
00033   Fixed reference leak. Releases ref to factory servant.
00034 
00035   Revision 1.20.2.1  2004/11/16 21:46:11  alextingle
00036   Made several methods virtual to allow users of libomniEvents to override
00037   the default persistency behaviour. (Dirk O. Siebnich)
00038 
00039   Revision 1.20  2004/09/25 23:12:28  alextingle
00040   New method: Orb::reportObjectFailure() - flags unexpected failures at a higher
00041   priority than normal non-fatal exceptions.
00042 
00043   New macro: NP_MINORSTRING() - a safe interface to
00044   CORBA::SystemException::NP_minorString() that returns "??" when there is no
00045   mapping for the exception's minor code.
00046 
00047   Revision 1.19  2004/07/26 16:27:08  alextingle
00048   Support for NT service on windows: main() moved into daemon.cc.
00049   New (laxer) start up syntax. Port is now set with -p (not -s). There is no
00050   special cold start mode.
00051   More flexible naming service name option -N. (No more -K option).
00052 
00053   Revision 1.18  2004/07/16 08:45:46  alextingle
00054   New macro: IF_OMNIORB4(). Fixes warnings on AIX xlC_r.
00055 
00056   Revision 1.17  2004/07/15 16:18:45  alextingle
00057   Fixed casting warnings on Tru64.
00058 
00059   Revision 1.16  2004/07/06 12:46:34  alextingle
00060   Moved default macros into defaults.h
00061 
00062   Revision 1.15  2004/07/06 10:59:39  alextingle
00063   Tightened privileges on created files.
00064 
00065   Revision 1.14  2004/07/05 13:52:37  alextingle
00066   Improved iostream portability (again).
00067 
00068   Revision 1.13  2004/07/02 15:20:39  alextingle
00069   Added daemonization, syslog & pidfile support on Unix.
00070   Corrected trace levels for consistency with omniORB.
00071 
00072   Revision 1.12  2004/05/14 14:44:48  alextingle
00073   Explicitly cast 'flags' to type ios::openmode for platforms where this type is an enum.
00074 
00075   Revision 1.11  2004/04/20 20:23:03  alextingle
00076   Cross-platform friendly use of std:ifstream.
00077 
00078   Revision 1.10  2004/04/20 17:16:16  alextingle
00079   Corrected openOfstream() arg name/comments.
00080 
00081   Revision 1.9  2004/03/30 17:31:00  alextingle
00082   Added exception handlers to thread methods.
00083 
00084   Revision 1.8  2004/03/28 01:03:58  alextingle
00085   Refactored class omniEventsLog to allow for more EventChannelFactory parameters.\nNew omniEvents params: -v, -a (alternate endPoint).
00086 
00087   Revision 1.7  2004/03/23 13:29:34  alextingle
00088   Fixed bizarre compilation errors on Sun's CC.
00089 
00090   Revision 1.6  2004/01/11 16:57:26  alextingle
00091   New persistancy log file format, implemented by PersistNode.h/cc. The new format enables new nodes to be added and old ones erased by appending a single line to the file, rather than by re-persisting the whole application. This is much more efficient when lots of proxies are being created all at once. It's also a much simpler solution, with far fewer lines of code.
00092 
00093   Revision 1.5  2003/12/21 16:17:19  alextingle
00094   Added OmniEvents namespace. Now uses POA implementations.
00095 
00096   Revision 1.4  2003/11/14 14:05:21  alextingle
00097   New output() members functions. Eliminates the need for friend ostream
00098   functions that are problematic on earlier versions of Microsoft
00099   VisualC++. Improved helpfulness of usage and error messages.
00100 
00101   Revision 1.3  2003/11/03 22:41:00  alextingle
00102   Oops! Removed excess log comments.
00103 
00104   Revision 1.2  2003/11/03 22:38:39  alextingle
00105   Removed many platform specific switches, alas many remain. Now uses
00106     autoconf,config.h wherever possible.
00107   Removed local definition of strdup() - omniEvents.cc manages to get
00108     along without it, so it can't be needed here.
00109   Moved convoluted code to obtain hostname into its own header file:
00110     gethostname.h
00111   Moved code that constructs logfile names into its own private method,
00112     omniEventsLog::initializeFileNames()
00113   Added explicit initialisation for all `class omniEventsLog' members.
00114   Moved code that opens file stream into its own private method,
00115     omniEventsLog::openOfstream()
00116 
00117   Revision 1.1.1.1  2002/09/25 19:00:35  shamus13
00118   Import of OmniEvents source tree from release 2.1.1
00119 
00120   Revision 1.8  2000/09/26 09:20:26  naderp
00121   STL Default parameters rework.
00122   Configurable checkpoint period.
00123 
00124   Revision 1.7  2000/09/04 05:05:22  naderp
00125   Fixed problem with triggering multiple checkpoints.
00126 
00127   Revision 1.6  2000/08/30 04:38:24  naderp
00128   Fix to prevent recorder thread from terminating.
00129 
00130   Revision 1.5  2000/08/30 00:57:29  naderp
00131   Fixed broken persist method exiting after first checkpoint.
00132 
00133   Revision 1.4  2000/03/06 13:19:58  naderp
00134   Moved port from global to factory persistency data.
00135 
00136   Revision 1.3  2000/03/06 04:15:09  naderp
00137   Removed internal dependency between factory and Naming Service.
00138 
00139   Revision 1.2  2000/03/02 04:20:09  naderp
00140   Initialising factory refernce in init().
00141 
00142   Revision 1.1  2000/03/02 02:00:25  naderp
00143   Re-open active logfile during re-start.
00144 
00145   Revision 1.0  1999/11/01 17:04:08  naderp
00146   Initial revision
00147 
00148 */
00149 
00150 #include "omniEventsLog.h"
00151 
00152 #ifdef HAVE_CONFIG_H
00153 #  include "config.h"
00154 #endif
00155 
00156 #include <stdio.h>
00157 
00158 #ifdef HAVE_STDLIB_H
00159 #  include <stdlib.h>
00160 #endif
00161 
00162 #ifdef HAVE_SYS_TYPES_H
00163 #  include <sys/types.h>
00164 #endif
00165 
00166 #ifdef HAVE_SYS_STAT_H
00167 #  include <sys/stat.h>
00168 #endif
00169 
00170 #ifdef HAVE_FCNTL_H
00171 #  include <fcntl.h>
00172 #endif
00173 
00174 #if defined(__VMS) && __CRTL_VER < 70000000
00175 #  include <omniVMS/unlink.hxx>
00176 #endif
00177 
00178 #ifdef __WIN32__
00179 #  include <io.h>
00180 #  include <winbase.h>
00181 #  define stat(x,y) _stat(x,y)
00182 #  define unlink(x) _unlink(x)
00183 #  define STRUCT_STAT struct _stat
00184 #else
00185 #  define STRUCT_STAT struct stat
00186 #endif // __WIN32__
00187 
00188 #ifdef HAVE_UNISTD_H
00189 #  include <unistd.h>
00190 #endif
00191 
00192 #ifdef HAVE_LIBC_H
00193 #  include <libc.h>
00194 #endif
00195 
00196 #ifdef HAVE_SYS_PARAM_H
00197 #  include <sys/param.h>
00198 #endif
00199 
00200 #include <errno.h>
00201 #include <time.h>
00202 #include <assert.h>
00203 #include "gethostname.h"
00204 
00205 #include "EventChannelFactory.h"
00206 #include "Orb.h"
00207 #include "defaults.h"
00208 
00209 //
00210 // Set flags for use in calls to omniEventsLog::openOfstream()
00211 //
00212 
00213 #if defined(HAVE_FSTREAM_OPEN)
00214 #  define FLAG_TRUNCATE ios::trunc
00215 #  define FLAG_APPEND   ios::app
00216 #  define FLAG_SYNC     0
00217 #elif defined(HAVE_FSTREAM_ATTACH)
00218 #  if defined(__WIN32__)
00219 #    define FLAG_SYNC 0
00220 #  elif defined(O_SYNC)
00221 #    define FLAG_SYNC O_SYNC
00222 #  else
00223 #    define FLAG_SYNC O_FSYNC // FreeBSD 3.2 does not have O_SYNC???
00224 #  endif
00225 #  define FLAG_TRUNCATE O_CREAT|O_TRUNC
00226 #  define FLAG_APPEND   O_APPEND
00227 #else
00228 #  error "Can't open a file without ofstream::open() or ofstream::attach()"
00229 #endif
00230 
00231 //
00232 // Append ';' to VMS filenames to force the latest version.
00233 //
00234 
00235 #ifdef __VMS
00236 #  define VMS_SEMICOLON ";"
00237 #else
00238 #  define VMS_SEMICOLON
00239 #endif
00240 
00241 extern int yyparse();
00242 extern int yydebug;
00243 extern FILE *yyin;
00244 
00245 namespace OmniEvents {
00246 
00252 class timestamp
00253 {
00254   char str[29];
00255 public:
00256   timestamp(void)
00257   {
00258     str[0] = '[';
00259     str[1] = str[28] = '\0';
00260   }
00261   const char* t(void)
00262   {
00263     time_t t =time(NULL);
00264     char*  p =ctime(&t);
00265     if(strncmp(p, &str[1], 24) == 0)
00266         return "";
00267     strncpy(&str[1], p, 24);
00268     str[25] = ']';
00269     str[26] = ' ';
00270     str[27] = ' ';
00271     return str;
00272   }
00273 };
00274 
00275 timestamp ts;
00276 
00277 //------------------------------------------------------------------------
00278 //           omniEvents Log Implementation
00279 //------------------------------------------------------------------------
00280 
00281 omniEventsLog *omniEventsLog::theLog = NULL;
00282 
00283 omniEventsLog::omniEventsLog(const char* logdir) :
00284   _logstream(),
00285   _activeFilename(NULL),
00286   _backupFilename(NULL),
00287   _checkpointFilename(NULL),
00288   _workerThread(NULL),
00289   _factory(NULL),
00290   _checkpointNeeded(true),
00291   _lock()
00292 {
00293   omniEventsLog::theLog = this;
00294   initializeFileNames(logdir);
00295 }
00296 
00297 
00298 omniEventsLog::~omniEventsLog()
00299 {
00300   DB(20, "omniEventsLog::~omniEventsLog()");
00301 /*
00302   if(NULL != _workerThread)
00303   {
00304     _workerThread->join(0);
00305     _workerThread = NULL;
00306   }
00307 */
00308   if(NULL != _factory)
00309   {
00310     _factory->_remove_ref();
00311     _factory = NULL;
00312   }
00313   omniEventsLog::theLog = NULL;
00314 }
00315 
00316 
00317 bool omniEventsLog::fileExists(const char* filename) const
00318 {
00319   STRUCT_STAT sb;
00320   return(::stat(filename,&sb) == 0);
00321 }
00322 
00323 
00324 PersistNode* omniEventsLog::bootstrap(int port, const char* endPointNoListen)
00325 {
00326   //
00327   // Construct a new initialState, from the arguments.
00328   PersistNode* initialState=new PersistNode();
00329   PersistNode* ecf =initialState->addnode("ecf");
00330   ecf->addattr("port",port);
00331   if(endPointNoListen && endPointNoListen[0])
00332       ecf->addattr(string("endPointNoListen=")+endPointNoListen);
00333   return initialState;
00334 } // bootstrap()
00335 
00336 
00337 PersistNode* omniEventsLog::parse()
00338 {
00339   //
00340   // Restart - parse log file.
00341   ifstream persiststream(_activeFilename);
00342   if(!persiststream)
00343   {
00344     cerr << "Error: cannot read database file '"
00345          << _activeFilename << "'." << endl;
00346     if( fileExists(_backupFilename) ) 
00347     {
00348       cerr <<
00349         " Backup file '" << _backupFilename << "' exists.\n"
00350         " Either rename it to '" << _activeFilename << "' to\n"
00351         " to recover the server's state, or delete it to create a new\n"
00352         " database file." << endl;
00353     }
00354     exit(1);
00355   }
00356   PersistNode* initialState=new PersistNode(persiststream);
00357   persiststream.close();
00358   
00359   //
00360   // Check that the file contains a valid EventChannelFactory.
00361   const char* errorStr =NULL;
00362   PersistNode* ecf=initialState->child("ecf");
00363   if(!ecf)
00364       errorStr="Can't find EventChannelFactory.";
00365   else if(ecf->attrLong("port",-1)<=0)
00366       errorStr="EventChannelFactory is not assigned a valid port.";
00367 
00368   if(errorStr)
00369   {
00370     cerr<<"Error parsing database '"<<_activeFilename<<"'.\n"
00371         <<errorStr<<" Try deleting the file (and any backup)."<<endl;
00372     exit(1);
00373   }
00374 
00375   return initialState;
00376 } // parse()
00377 
00378 
00379 void omniEventsLog::incarnateFactory(PersistNode* initialState)
00380 {
00381   assert(initialState!=NULL);
00382 
00383   //
00384   // Open the logstream (The EventChannelFactory might want to write to it).
00385   try
00386   {
00387     openOfstream(_logstream,_activeFilename,FLAG_APPEND);
00388   }
00389   catch (IOError& ex)
00390   {
00391     cerr << "Error: cannot "
00392          << (fileExists(_activeFilename)?"write to":"create new")
00393          << " database file '" << _activeFilename
00394          << "': " << strerror(errno) << endl;
00395     cerr << "\nUse option '-l' or set the environment variable "
00396          << OMNIEVENTS_LOGDIR_ENV_VAR
00397          << "\nto specify the directory where the files are kept.\n"
00398          << endl;
00399     _logstream.close();
00400     unlink(_activeFilename);
00401     exit(1);
00402   }
00403 
00404   //
00405   // Recreate the persisted factory.
00406   PersistNode* ecf=initialState->child("ecf");
00407   assert(ecf!=NULL);
00408   _factory =new EventChannelFactory_i(*ecf);
00409   CORBA::Object_var obj;
00410   assert(!CORBA::is_nil(obj = _factory->_this()));
00411 } // incarnateFactory
00412 
00413 
00414 void omniEventsLog::runWorker()
00415 {
00416   assert(_factory!=NULL);
00417 
00418   _workerThread=new omniEventsLogWorker(
00419       this,
00420       &omniEventsLog::checkpoint, // member function pointer
00421       omni_thread::PRIORITY_NORMAL
00422     );
00423 }
00424 
00425 
00426 void omniEventsLog::output(ostream& os)
00427 {
00428   _factory->output(os);
00429   os<<endl;
00430 }
00431 
00432 
00433 void omniEventsLog::checkpoint(void)
00434 {
00435   int idle_time_btw_chkpt;
00436   static int firstCheckPoint = 1;
00437   char *itbc = getenv("OMNIEVENTS_ITBC");
00438   if (itbc == NULL || sscanf(itbc,"%d",&idle_time_btw_chkpt) != 1)
00439   {
00440     idle_time_btw_chkpt=OMNIEVENTS_LOG_CHECKPOINT_PERIOD;
00441   }
00442 
00443   omni_mutex mutex;
00444   omni_condition cond(&mutex);
00445 
00446   mutex.lock();
00447   while (1) {
00448 
00449     // Take an initial checkpoint the first time. All subsequent
00450     // checkpoints are conditionally tested on whether they are
00451     // needed or not.
00452 
00453     if (! firstCheckPoint)
00454     {
00455        unsigned long s, n;
00456        omni_thread::get_time(&s, &n, idle_time_btw_chkpt);
00457        cond.timedwait(s,n);
00458 
00459        _lock.lock();
00460        if(!_checkpointNeeded)
00461        {
00462           _lock.unlock();
00463           continue;
00464        }
00465     }
00466     else
00467     {
00468        _lock.lock();
00469        firstCheckPoint = 0;
00470     }
00471   
00472     DB(1,ts.t() << "Checkpointing Phase 1: Prepare.")
00473   
00474     ofstream ckpf;
00475     int fd = -1;
00476   
00477     try
00478     {
00479       try
00480       {
00481         openOfstream(ckpf,_checkpointFilename,FLAG_TRUNCATE|FLAG_SYNC,&fd);
00482       }
00483       catch(IOError& ex)
00484       {
00485         DB(0,ts.t() << "Error: cannot open checkpoint file '"
00486              << _checkpointFilename << "' for writing.")
00487         throw;
00488       }
00489   
00490       output(ckpf);
00491   
00492       ckpf.close();
00493       if(!ckpf)
00494           throw IOError();
00495   
00496   // a bug in sparcworks C++ means that the fd doesn't get closed.
00497 #if defined(__sunos__) && defined(__SUNPRO_CC) && __SUNPRO_CC < 0x500
00498       if(close(fd) < 0)
00499           throw IOError();
00500 #endif
00501   
00502     }
00503     catch(IOError& ex)
00504     {
00505       DB(0,ts.t()<<"I/O error writing checkpoint file: "<<strerror(errno)
00506            <<"\nAbandoning checkpoint")
00507       ckpf.close();
00508   // a bug in sparcworks C++ means that the fd doesn't get closed.
00509 #if defined(__sunos__) && defined(__SUNPRO_CC) && __SUNPRO_CC < 0x500
00510       close(fd);
00511 #endif
00512       unlink(_checkpointFilename);
00513       _lock.unlock();
00514       continue;
00515     }
00516   
00517     //
00518     // Now commit the checkpoint to become the active log.
00519     //
00520   
00521     DB(1,ts.t() << "Checkpointing Phase 2: Commit.")
00522 
00523   // a bug in sparcworks C++ means that the fd doesn't get closed.
00524 #if defined(__sunos__) && defined(__SUNPRO_CC) && __SUNPRO_CC < 0x500
00525     close(_logstream.rdbuf()->fd());
00526 #endif
00527   
00528     _logstream.close();
00529   
00530     unlink(_backupFilename);
00531   
00532 #if defined(__WIN32__)
00533     if(rename(_activeFilename, _backupFilename) != 0)
00534 #elif defined(__VMS)
00535     if(rename(_activeFilename, _backupFilename) < 0)
00536 #else
00537     if(link(_activeFilename,_backupFilename) < 0)
00538 #endif
00539     {
00540       // Failure here leaves old active and checkpoint file.
00541       DB(0,ts.t() << "Error: failed to link backup file '"
00542            << _backupFilename << "' to old log file '"
00543            << _activeFilename << "'.")
00544       exit(1);
00545     }
00546   
00547 #if !defined( __VMS) && !defined(__WIN32__)
00548     if(unlink(_activeFilename) < 0)
00549     {
00550       // Failure here leaves active and backup pointing to the same (old) file.
00551       DB(0,ts.t() << "Error: failed to unlink old log file '"
00552            << _activeFilename << "': " << strerror(errno))
00553       exit(1);
00554     }
00555 #endif
00556   
00557 #if defined(__WIN32__)
00558     if(rename(_checkpointFilename,_activeFilename) != 0)
00559 #elif defined(__VMS)
00560     if(rename(_checkpointFilename,_activeFilename) < 0)
00561 #else
00562     if(link(_checkpointFilename,_activeFilename) < 0)
00563 #endif
00564     {
00565       // Failure here leaves no active but backup points to the old file.
00566       DB(0,ts.t() << "Error: failed to link log file '" << _activeFilename
00567            << "' to checkpoint file '" << _checkpointFilename << "'.")
00568       exit(1);
00569     }
00570   
00571 #if !defined( __VMS) && !defined(__WIN32__)
00572     if (unlink(_checkpointFilename) < 0)
00573     {
00574       // Failure here leaves active and checkpoint pointing to the same file.
00575       DB(0,ts.t() << "Error: failed to unlink checkpoint file '"
00576            << _checkpointFilename << "'.")
00577       exit(1);
00578     }
00579 #endif
00580   
00581     try
00582     {
00583       openOfstream(_logstream,_activeFilename,FLAG_APPEND|FLAG_SYNC,&fd);
00584     }
00585     catch (IOError& ex)
00586     {
00587       DB(0,ts.t() << "Error: cannot open new log file '" << _activeFilename
00588            << "' for writing.")
00589       exit(1);
00590     }
00591   
00592     DB(1,ts.t() << "Checkpointing completed.")
00593   
00594     _checkpointNeeded=false;
00595     _lock.unlock();
00596   }
00597   mutex.unlock();
00598 } // checkpoint
00599 
00600 
00611 void omniEventsLog::initializeFileNames(const char* logdir)
00612 {
00613   if(!logdir)
00614       logdir=getenv(OMNIEVENTS_LOGDIR_ENV_VAR);
00615   if(!logdir)
00616       logdir=OMNIEVENTS_LOG_DEFAULT_LOCATION;
00617 
00618   const char* logname ="omnievents-";
00619   char hostname[MAXHOSTNAMELEN];
00620   if (0!=gethostname(hostname,MAXHOSTNAMELEN))
00621   {
00622     cerr << "Error: cannot get the name of this host." << endl;
00623     exit(1);
00624   }
00625   const char* sep ="";
00626 
00627 #if defined(__WIN32__)
00628   sep="\\";
00629 #elif defined(__VMS)
00630   char last( logdir[strlen(logdir)-1] );
00631   if (last != ':' && last != ']')
00632   {
00633     cerr << "Error: " << OMNIEVENTS_LOGDIR_ENV_VAR << " (" << logdir
00634          << ") is not a directory name." << endl;
00635     exit(1);
00636   }
00637 #else // Unix
00638   if (logdir[0] != '/')
00639   {
00640     cerr << "Error: " << OMNIEVENTS_LOGDIR_ENV_VAR << " (" << logdir
00641          << ") is not an absolute path name." << endl;
00642     exit(1);
00643   }
00644   if (logdir[strlen(logdir)-1] != '/')
00645       sep="/";
00646 #endif
00647 
00648   // VMS_SEMICOLON specifies latest version of the file on VMS
00649   // (essentially, we're saying we don't want to use VMS file versioning).
00650 
00651   setFilename(_activeFilename,logdir,sep,logname,hostname,".log" VMS_SEMICOLON);
00652   setFilename(_backupFilename,logdir,sep,logname,hostname,".bak" VMS_SEMICOLON);
00653   setFilename(
00654           _checkpointFilename,logdir,sep,logname,hostname,".ckp" VMS_SEMICOLON);
00655 }
00656 
00657 
00661 void omniEventsLog::setFilename(
00662   char*& filename,     const char* logdir,   const char* sep,
00663   const char* logname, const char* hostname, const char* ext)
00664 {
00665   size_t len=1+
00666     strlen(logdir)+strlen(sep)+strlen(logname)+strlen(hostname)+strlen(ext);
00667   filename=new char[len];
00668   sprintf(filename,"%s%s%s%s%s",logdir,sep,logname,hostname,ext);
00669 }
00670 
00671 
00685 void omniEventsLog::openOfstream(
00686   ofstream& s, const char* filename, int flags, int* fd)
00687 {
00688 #if defined(HAVE_FSTREAM_OPEN)
00689 #  ifdef HAVE_STD_IOSTREAM
00690       ios::openmode openmodeflags =ios::out|ios::openmode(flags);
00691 #  else
00692       int           openmodeflags =ios::out|flags;
00693 #  endif
00694 
00695 #  ifdef FSTREAM_OPEN_PROT
00696       s.open(filename,openmodeflags,0644);
00697 #  else
00698       s.open(filename,openmodeflags);
00699 #  endif
00700       if (!s)
00701           throw IOError();
00702 
00703 #elif defined(HAVE_FSTREAM_ATTACH)
00704 #  ifdef __WIN32__
00705       int localFd = _open(filename, O_WRONLY | flags, _S_IWRITE);
00706 #  else
00707       int localFd = open(filename, O_WRONLY | flags, 0644);
00708 #  endif /* __WIN32__ */
00709       if (localFd < 0)
00710           throw IOError();
00711       if(fd)
00712           (*fd)=localFd;
00713       s.attach(localFd);
00714 #endif
00715 }
00716 
00717 
00718 //------------------------------------------------------------------------
00719 //           OmniEvents Log Worker Implementation
00720 //------------------------------------------------------------------------
00721 omniEventsLogWorker::omniEventsLogWorker(
00722   omniEventsLog* object,
00723   Method         method,
00724   priority_t     priority
00725 ):omni_thread(NULL,priority)
00726 {
00727   DB(15, "omniEventsLogWorker::omniEventsLogWorker()");
00728 
00729   _method=method;
00730   _object=object;
00731 
00732   start_undetached();
00733 }
00734 
00735 
00736 void* omniEventsLogWorker::run_undetached(void *)
00737 {
00738   try {
00739     DB(15, "omniEventsLogWorker : run_undetached Start");
00740     (_object->*_method)();
00741     DB(15, "omniEventsLogWorker : run_undetached End");
00742   }
00743   catch (CORBA::SystemException& ex) {
00744     DB(0,"omniEventsLogWorker killed by CORBA system exception"
00745        IF_OMNIORB4(": "<<ex._name()<<" ("<<NP_MINORSTRING(ex)<<")") ".")
00746   }
00747   catch (CORBA::Exception& ex) {
00748     DB(0,"omniEventsLogWorker killed by CORBA exception"
00749        IF_OMNIORB4(": "<<ex._name()<<) ".")
00750   }
00751   catch(...) {
00752     DB(0,"omniEventsLogWorker killed by unknown exception.")
00753   }
00754   return NULL;
00755 }
00756 
00757 omniEventsLogWorker::~omniEventsLogWorker()
00758 {
00759   DB(20, "omniEventsLogWorker::~omniEventsLogWorker()");
00760 }
00761 
00762 
00763 }; // end namespace OmniEvents

Generated on Fri Aug 26 20:56:14 2005 for OmniEvents by  doxygen 1.4.3-20050530