Back to index

lightning-sunbird  0.9+nobinonly
GUSIContextQueue.h
Go to the documentation of this file.
00001 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
00002 // % Project  :      GUSI                        -      Grand Unified Socket Interface                    
00003 // % File            :      GUSIContext.nw              -      Thread and Process structures               
00004 // % Author   :      Matthias Neeracher                                           
00005 // % Language :      C++                                                        
00006 // %                                                                       
00007 // % $Log: GUSIContextQueue.h,v $
00008 // % Revision 1.1  2001/03/11 22:33:41  sgehani%netscape.com
00009 // % First Checked In.
00010 // %                                         
00011 // % Revision 1.9  2001/01/17 08:45:13  neeri                              
00012 // % Improve memory allocation safety somewhat                             
00013 // %                                                                       
00014 // % Revision 1.8  2000/05/23 06:58:03  neeri                              
00015 // % Improve formatting                                                    
00016 // %                                                                       
00017 // % Revision 1.7  2000/03/15 07:22:06  neeri                              
00018 // % Enforce alignment choices                                             
00019 // %                                                                       
00020 // % Revision 1.6  1999/08/26 05:45:00  neeri                              
00021 // % Fixes for literate edition of source code                             
00022 // %                                                                       
00023 // % Revision 1.5  1999/05/30 03:09:29  neeri                              
00024 // % Added support for MPW compilers                                       
00025 // %                                                                       
00026 // % Revision 1.4  1999/03/17 09:05:06  neeri                              
00027 // % Added GUSITimer, expanded docs                                        
00028 // %                                                                       
00029 // % Revision 1.3  1998/08/02 11:20:07  neeri                              
00030 // % Fixed some typos                                                      
00031 // %                                                                       
00032 // % Revision 1.2  1998/08/01 21:32:02  neeri                              
00033 // % About ready for 2.0a1                                                 
00034 // %                                                                       
00035 // % Revision 1.1  1998/01/25 21:02:43  neeri                              
00036 // % Engine implemented, except for signals & scheduling                   
00037 // %                                                                       
00038 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
00039 //                                                                         
00040 // \chapter{Context Queues}                                                
00041 //                                                                         
00042 // At all times through its existence, a [[GUSIContext]] will exist in various
00043 // queues: A queue of all contexts, queues of contexts waiting on a socket 
00044 // event, a mutex, or a condition variable, and so on. Since a context is often
00045 // in several queues simultaneously, it's better to define queues non-intrusively.
00046 //                                                                         
00047 // <GUSIContextQueue.h>=                                                   
00048 #ifndef _GUSIContextQueue_
00049 #define _GUSIContextQueue_
00050 
00051 #ifndef GUSI_SOURCE
00052 
00053 typedef struct GUSIContextQueue GUSIContextQueue;
00054 #else
00055 
00056 #include <stdlib.h>
00057 
00058 // \section{Definition of context queues}                                  
00059 //                                                                         
00060 // We'd like to avoid having to include \texttt{GUSIContext} here, for reasons that
00061 // should be rather obvious.                                               
00062 //                                                                         
00063 // <Name dropping for file GUSIContextQueue>=                              
00064 class GUSIContext;
00065 
00066 #include <ConditionalMacros.h>
00067 
00068 #if PRAGMA_STRUCT_ALIGN
00069 #pragma options align=native
00070 #endif
00071 
00072 // The class [[GUSIContextQueue]] tries to present an interface that is a subset of
00073 // what C++ standard library list template classes offer.                  
00074 //                                                                         
00075 // <Definition of class [[GUSIContextQueue]]>=                             
00076 class GUSIContextQueue {
00077 public:
00078        GUSIContextQueue();
00079        ~GUSIContextQueue();
00080        
00081        bool                 empty();
00082        GUSIContext * front() const;
00083        GUSIContext * back() const;
00084        void                 push_front(GUSIContext * context);
00085        void                 push_back(GUSIContext * context);
00086        void                 push(GUSIContext * context)               { push_back(context); }
00087        void                 pop_front();
00088        void                 pop()                                                   { pop_front(); }
00089        void                 remove(GUSIContext * context);
00090        
00091        void                 Wakeup();
00092 
00093        // We define a forward iterator, but no reverse iterator.                  
00094  //                                                                         
00095  // <Define [[iterator]] for [[GUSIContextQueue]]>=                         
00096  struct element;
00097  class iterator {
00098        friend class GUSIContextQueue;
00099  public:
00100        iterator & operator++();
00101        iterator operator++(int);
00102        bool operator==(const iterator other) const;
00103        GUSIContext * operator*();
00104        GUSIContext * operator->();
00105  private:
00106        // A [[GUSIContextQueue::iterator]] is just a wrapper for a                
00107   // [[GUSIContextQueue::element]].                                          
00108   //                                                                         
00109   // <Privatissima of [[GUSIContextQueue::iterator]]>=                       
00110   element *   fCurrent;
00111 
00112   iterator(element * elt) : fCurrent(elt) {}
00113   iterator()                       : fCurrent(0)   {}
00114  };
00115 
00116  iterator            begin();
00117  iterator            end();
00118 private:
00119        // \section{Implementation of context queues}                              
00120  //                                                                         
00121  // Efficiency of context queues is quite important, so we provide a custom 
00122  // allocator for queue elements.                                           
00123  //                                                                         
00124  // <Privatissima of [[GUSIContextQueue]]>=                                 
00125  struct element {
00126        GUSIContext * fContext;
00127        element *            fNext;
00128        
00129        element(GUSIContext * context, element * next = 0) 
00130               : fContext(context), fNext(next) {}
00131        void * operator new(size_t);
00132        void   operator delete(void *, size_t);
00133  private:
00134        // Elements are allocated in blocks of increasing size.                    
00135   //                                                                         
00136   // <Privatissima of [[GUSIContextQueue::element]]>=                        
00137   struct header {
00138        short  fFree;
00139        short  fMax;
00140        header *fNext;
00141   };
00142   static header *    sBlocks;
00143  };
00144  // A [[GUSIContextQueue]] is a single linked list with a separate back pointer.
00145  //                                                                         
00146  // <Privatissima of [[GUSIContextQueue]]>=                                 
00147  element *    fFirst;
00148  element *    fLast;
00149 };
00150 
00151 #if PRAGMA_STRUCT_ALIGN
00152 #pragma options align=reset
00153 #endif
00154 
00155 // <Inline member functions for class [[GUSIContextQueue]]>=               
00156 inline GUSIContextQueue::GUSIContextQueue() 
00157        : fFirst(0), fLast(0)
00158 {
00159 }
00160 // None of the member functions are very large, so we'll inline them.      
00161 //                                                                         
00162 // <Inline member functions for class [[GUSIContextQueue]]>=               
00163 inline bool GUSIContextQueue::empty()
00164 {
00165        return !fFirst;
00166 }
00167 
00168 inline GUSIContext * GUSIContextQueue::front() const
00169 {
00170        return fFirst ? fFirst->fContext : reinterpret_cast<GUSIContext *>(0);
00171 }
00172 
00173 inline GUSIContext * GUSIContextQueue::back() const
00174 {
00175        return fLast ? fLast->fContext : reinterpret_cast<GUSIContext *>(0);
00176 }
00177 
00178 inline void GUSIContextQueue::push_front(GUSIContext * context)
00179 {
00180        fFirst = new element(context, fFirst);
00181        if (!fLast)
00182               fLast = fFirst;
00183 }
00184 
00185 inline void GUSIContextQueue::pop_front()
00186 {
00187        if (element * e = fFirst) {
00188               if (!(fFirst = fFirst->fNext))
00189                      fLast = 0;
00190               delete e;
00191        }
00192 }
00193 // The constructors are not public, so only [[begin]] and [[end]] call them.
00194 //                                                                         
00195 // <Inline member functions for class [[GUSIContextQueue]]>=               
00196 inline GUSIContextQueue::iterator GUSIContextQueue::begin()
00197 {
00198        return iterator(fFirst);
00199 }
00200 
00201 inline GUSIContextQueue::iterator GUSIContextQueue::end()
00202 {
00203        return iterator();
00204 }
00205 // <Inline member functions for class [[GUSIContextQueue]]>=               
00206 inline GUSIContextQueue::iterator & GUSIContextQueue::iterator::operator++()
00207 {
00208        fCurrent = fCurrent->fNext;
00209        
00210        return *this;
00211 }
00212 
00213 inline GUSIContextQueue::iterator GUSIContextQueue::iterator::operator++(int)
00214 {
00215        GUSIContextQueue::iterator it(*this);
00216        fCurrent = fCurrent->fNext;
00217        
00218        return it;
00219 }
00220 
00221 inline bool GUSIContextQueue::iterator::operator==(const iterator other) const
00222 {
00223        return fCurrent == other.fCurrent;
00224 }
00225 
00226 inline GUSIContext * GUSIContextQueue::iterator::operator*()
00227 {
00228        return fCurrent->fContext;
00229 }
00230 
00231 inline GUSIContext * GUSIContextQueue::iterator::operator->()
00232 {
00233        return fCurrent->fContext;
00234 }
00235 #endif /* GUSI_SOURCE */
00236 
00237 #endif /* _GUSIContextQueue_ */