Back to index

lightning-sunbird  0.9+nobinonly
GUSIDescriptor.h
Go to the documentation of this file.
00001 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
00002 // % Project  :      GUSI                        -      Grand Unified Socket Interface                    
00003 // % File            :      GUSIDescriptor.nw    -      Descriptor Table                          
00004 // % Author   :      Matthias Neeracher                                           
00005 // % Language :      C++                                                        
00006 // %                                                                       
00007 // % $Log: GUSIDescriptor.h,v $
00008 // % Revision 1.1  2001/03/11 22:33:48  sgehani%netscape.com
00009 // % First Checked In.
00010 // %                                           
00011 // % Revision 1.15  2001/01/22 04:31:11  neeri                             
00012 // % Last minute changes for 2.1.5                                         
00013 // %                                                                       
00014 // % Revision 1.14  2001/01/17 08:40:17  neeri                             
00015 // % Prevent inlining of overridable functions                             
00016 // %                                                                       
00017 // % Revision 1.13  2000/06/12 04:23:43  neeri                             
00018 // % Return values, not references; Introduce support for multiple descriptor tables
00019 // %                                                                       
00020 // % Revision 1.12  2000/05/23 06:58:03  neeri                             
00021 // % Improve formatting                                                    
00022 // %                                                                       
00023 // % Revision 1.11  2000/03/15 07:14:26  neeri                             
00024 // % Prevent double destruction of descriptor table                        
00025 // %                                                                       
00026 // % Revision 1.10  2000/03/06 06:26:57  neeri                             
00027 // % Introduce (and call) CloseAllDescriptors()                            
00028 // %                                                                       
00029 // % Revision 1.9  1999/08/26 05:45:01  neeri                              
00030 // % Fixes for literate edition of source code                             
00031 // %                                                                       
00032 // % Revision 1.8  1999/08/02 07:02:43  neeri                              
00033 // % Support for asynchronous errors and other socket options              
00034 // %                                                                       
00035 // % Revision 1.7  1999/06/30 07:42:05  neeri                              
00036 // % Getting ready to release 2.0b3                                        
00037 // %                                                                       
00038 // % Revision 1.6  1999/05/29 06:26:42  neeri                              
00039 // % Fixed header guards                                                   
00040 // %                                                                       
00041 // % Revision 1.5  1999/04/29 05:00:48  neeri                              
00042 // % Fix bug with bizarre uses of dup2                                     
00043 // %                                                                       
00044 // % Revision 1.4  1999/03/17 09:05:06  neeri                              
00045 // % Added GUSITimer, expanded docs                                        
00046 // %                                                                       
00047 // % Revision 1.3  1998/10/11 16:45:12  neeri                              
00048 // % Ready to release 2.0a2                                                
00049 // %                                                                       
00050 // % Revision 1.2  1998/08/01 21:32:03  neeri                              
00051 // % About ready for 2.0a1                                                 
00052 // %                                                                       
00053 // % Revision 1.1  1998/01/25 21:02:44  neeri                              
00054 // % Engine implemented, except for signals & scheduling                   
00055 // %                                                                       
00056 // % Revision 1.1  1996/12/16 02:12:40  neeri                              
00057 // % TCP Sockets sort of work                                              
00058 // %                                                                       
00059 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
00060 //                                                                         
00061 // \chapter{Mapping descriptors to sockets}                                
00062 //                                                                         
00063 // POSIX routines do not, of course, operate on [[GUSISockets]] but on     
00064 // numerical descriptors. The [[GUSIDescriptorTable]] singleton maps between
00065 // descriptors and their [[GUSISockets]].                                  
00066 //                                                                         
00067 // <GUSIDescriptor.h>=                                                     
00068 #ifndef _GUSIDescriptor_
00069 #define _GUSIDescriptor_
00070 
00071 #ifdef GUSI_SOURCE
00072 
00073 #include "GUSISocket.h"
00074 
00075 #include <ConditionalMacros.h>
00076 
00077 #if PRAGMA_STRUCT_ALIGN
00078 #pragma options align=native
00079 #endif
00080 
00081 // \section{Definition of [[GUSIDescriptorTable]]}                         
00082 //                                                                         
00083 // A [[GUSIDescriptorTable]] is another singleton class, behaving in many aspects
00084 // like an array of [[GUSISocket]] pointers. [[InstallSocket]] installs a new socket 
00085 // into the table, picking the first available slot with a descriptor greater than
00086 // or equal to [[start]]. [[RemoveSocket]] empties one slot.               
00087 // [[GUSIDescriptorTable::LookupSocket]] is a shorthand for                
00088 // [[ (*GUSIDescriptorTable::Instance())[fd] ]].                           
00089 //                                                                         
00090 // To allow for light-weight processes, we provide a copy constructor and  
00091 // the [[SetInstance]] member.                                             
00092 //                                                                         
00093 // <Definition of class [[GUSIDescriptorTable]]>=                          
00094 class GUSIDescriptorTable {
00095 public:
00096        enum { SIZE = 64 };
00097        
00098        static GUSIDescriptorTable *       Instance();
00099        
00100        int                                InstallSocket(GUSISocket * sock, int start = 0);
00101        int                                RemoveSocket(int fd);
00102        GUSISocket *         operator[](int fd);
00103        static GUSISocket *  LookupSocket(int fd);
00104        
00105        class iterator;
00106        friend class iterator;
00107        
00108        iterator                    begin();
00109        iterator                    end();
00110        
00111        ~GUSIDescriptorTable();
00112        
00113        static void                 CloseAllDescriptors();
00114 
00115        static void SetInstance(GUSIDescriptorTable * table);
00116        
00117        GUSIDescriptorTable(const GUSIDescriptorTable & parent);
00118 private:
00119        // \section{Implementation of [[GUSIDescriptorTable]]}                     
00120  //                                                                         
00121  // On creation, a [[GUSIDescriptorTable]] clears all descriptors.          
00122  //                                                                         
00123  // <Privatissima of [[GUSIDescriptorTable]]>=                              
00124  GUSISocket * fSocket[SIZE];
00125  int                        fInvalidDescriptor;
00126  GUSIDescriptorTable();
00127  // <Privatissima of [[GUSIDescriptorTable]]>=                              
00128  static       GUSIDescriptorTable  * sGUSIDescriptorTable;
00129 };
00130 
00131 #if PRAGMA_STRUCT_ALIGN
00132 #pragma options align=reset
00133 #endif
00134 
00135 // If no instance exists yet, [[GUSIDescriptorTable::Instance]] creates one and
00136 // calls [[GUSISetupConsole]] if the [[setupConsole]] parameter is true.   
00137 // [[GUSISetupConsole]] calls [[GUSIDefaultSetupConsole]], which first calls
00138 // [[GUSISetupConsoleDescriptors]] to set up file descriptors 0, 1, and 2, and
00139 // then calls [[GUSISetupConsoleStdio]] to deal with the necessary initializations
00140 // on the stdio level.                                                     
00141 //                                                                         
00142 // <Hooks for ANSI library interfaces>=                                    
00143 extern "C" {
00144 void GUSISetupConsole();
00145 void GUSIDefaultSetupConsole();
00146 void GUSISetupConsoleDescriptors();
00147 void GUSISetupConsoleStdio();
00148 }
00149 // Destructing a [[GUSIDescriptorTable]] may be a bit problematic, as this 
00150 // may have effects reaching up into the stdio layer. We therefore factor  
00151 // out the stdio aspects into the procedures [[StdioClose]] and [[StdioFlush]]
00152 // which we then can redefine in other, stdio library specific, libraries. 
00153 //                                                                         
00154 // <Hooks for ANSI library interfaces>=                                    
00155 extern "C" {
00156 void GUSIStdioClose();      
00157 void GUSIStdioFlush();
00158 }
00159 
00160 // <Inline member functions for class [[GUSIDescriptorTable]]>=            
00161 class GUSIDescriptorTable::iterator {
00162 public:
00163        iterator(GUSIDescriptorTable * table, int fd = 0) : fTable(table), fFd(fd) {}       
00164        GUSIDescriptorTable::iterator & operator++();
00165        GUSIDescriptorTable::iterator operator++(int);
00166        int    operator*()                        { return fFd;                                           }
00167        bool operator==(const GUSIDescriptorTable::iterator & other) const;
00168 private:
00169        GUSIDescriptorTable *              fTable;
00170        int                                              fFd;
00171 };
00172 
00173 inline GUSIDescriptorTable::iterator & GUSIDescriptorTable::iterator::operator++()
00174 {
00175        while (++fFd < fTable->fInvalidDescriptor && !fTable->fSocket[fFd])
00176               ;
00177        
00178        return *this;
00179 }
00180 
00181 inline GUSIDescriptorTable::iterator GUSIDescriptorTable::iterator::operator++(int)
00182 {
00183        int oldFD = fFd;
00184        
00185        while (++fFd < fTable->fInvalidDescriptor && !fTable->fSocket[fFd])
00186               ;
00187        
00188        return GUSIDescriptorTable::iterator(fTable, oldFD);
00189 }
00190 
00191 inline bool GUSIDescriptorTable::iterator::operator==(
00192                             const GUSIDescriptorTable::iterator & other) const
00193 {
00194        return fFd == other.fFd;
00195 }
00196 
00197 inline GUSIDescriptorTable::iterator GUSIDescriptorTable::begin()
00198 {
00199        return iterator(this);
00200 }
00201 
00202 inline GUSIDescriptorTable::iterator GUSIDescriptorTable::end()
00203 {
00204        return iterator(this, fInvalidDescriptor);
00205 }
00206 
00207 #endif /* GUSI_SOURCE */
00208 
00209 #endif /* _GUSIDescriptor_ */