EPICS Base  7.0.8.1
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
fdManager.h
1 /*************************************************************************\
2 * Copyright (c) 2002 The University of Chicago, as Operator of Argonne
3 * National Laboratory.
4 * Copyright (c) 2002 The Regents of the University of California, as
5 * Operator of Los Alamos National Laboratory.
6 * SPDX-License-Identifier: EPICS
7 * EPICS Base is distributed subject to a Software License Agreement found
8 * in file LICENSE that is included with this distribution.
9 \*************************************************************************/
10 /*
11  * File descriptor management C++ class library
12  * (for multiplexing IO in a single threaded environment)
13  *
14  * Author Jeffrey O. Hill
16  * 505 665 1831
17  */
18 
19 #ifndef fdManagerH_included
20 #define fdManagerH_included
21 
22 #include "libComAPI.h" // reset share lib defines
23 #include "tsDLList.h"
24 #include "resourceLib.h"
25 #include "epicsTime.h"
26 #include "osiSock.h"
27 #include "epicsTimer.h"
28 
29 enum fdRegType {fdrRead, fdrWrite, fdrException, fdrNEnums};
30 
31 //
32 // fdRegId
33 //
34 // file descriptor interest id
35 //
36 class LIBCOM_API fdRegId
37 {
38 public:
39 
40  fdRegId (const SOCKET fdIn, const fdRegType typeIn) :
41  fd(fdIn), type(typeIn) {}
42 
43  SOCKET getFD () const
44  {
45  return this->fd;
46  }
47 
48  fdRegType getType () const
49  {
50  return this->type;
51  }
52 
53  bool operator == (const fdRegId &idIn) const
54  {
55  return this->fd == idIn.fd && this->type==idIn.type;
56  }
57 
58  resTableIndex hash () const;
59 
60  virtual void show (unsigned level) const;
61 
62  virtual ~fdRegId() {}
63 private:
64  SOCKET fd;
65  fdRegType type;
66 };
67 
68 //
69 // fdManager
70 //
71 // file descriptor manager
72 //
74 public:
75  //
76  // exceptions
77  //
79 
80  LIBCOM_API fdManager ();
81  LIBCOM_API virtual ~fdManager ();
82  LIBCOM_API void process ( double delay ); // delay parameter is in seconds
83 
84  // returns NULL if the fd is unknown
85  LIBCOM_API class fdReg *lookUpFD (const SOCKET fd, const fdRegType type);
86 
87  epicsTimer & createTimer ();
88 
89 private:
90  tsDLList < fdReg > regList;
91  tsDLList < fdReg > activeList;
93  const double sleepQuantum;
94  fd_set * fdSetsPtr;
95  epicsTimerQueuePassive * pTimerQueue;
96  SOCKET maxFD;
97  bool processInProg;
98  //
99  // Set to fdreg when in call back
100  // and nill otherwise
101  //
102  fdReg * pCBReg;
103  void reschedule ();
104  double quantum ();
105  void installReg (fdReg &reg);
106  void removeReg (fdReg &reg);
107  void lazyInitTimerQueue ();
108  fdManager ( const fdManager & );
109  fdManager & operator = ( const fdManager & );
110  friend class fdReg;
111 };
112 
113 //
114 // default file descriptor manager
115 //
116 LIBCOM_API extern fdManager fileDescriptorManager;
117 
118 //
119 // fdReg
120 //
121 // file descriptor registration
122 //
123 class LIBCOM_API fdReg :
124  public fdRegId, public tsDLNode<fdReg>, public tsSLNode<fdReg> {
125  friend class fdManager;
126 
127 public:
128 
129  fdReg (const SOCKET fdIn, const fdRegType type,
130  const bool onceOnly=false, fdManager &manager = fileDescriptorManager);
131  virtual ~fdReg ();
132 
133  virtual void show (unsigned level) const;
134 
135  //
136  // Called by the file descriptor manager:
137  // 1) If the fdManager is deleted and there are still
138  // fdReg objects attached
139  // 2) Immediately after calling "callBack()" if
140  // the constructor specified "onceOnly"
141  //
142  // fdReg::destroy() does a "delete this"
143  //
144  virtual void destroy ();
145 
146 private:
147  enum state {active, pending, limbo};
148 
149  //
150  // called when there is activity on the fd
151  // NOTES
152  // 1) the fdManager will call this only once during the
153  // lifetime of a fdReg object if the constructor
154  // specified "onceOnly"
155  //
156  virtual void callBack ()=0;
157 
158  unsigned char state; // state enums go here
159  unsigned char onceOnly;
160  fdManager &manager;
161 
162  fdReg ( const fdReg & );
163  fdReg & operator = ( const fdReg & );
164 };
165 
166 //
167 // fdRegId::hash()
168 //
169 inline resTableIndex fdRegId::hash () const
170 {
171  const unsigned fdManagerHashTableMinIndexBits = 8;
172  const unsigned fdManagerHashTableMaxIndexBits = sizeof(SOCKET)*CHAR_BIT;
173  resTableIndex hashid;
174 
175  hashid = integerHash ( fdManagerHashTableMinIndexBits,
176  fdManagerHashTableMaxIndexBits, this->fd );
177 
178  //
179  // also evenly distribute based on the type of fdRegType
180  //
181  hashid ^= this->type;
182 
183  //
184  // the result here is always masked to the
185  // proper size after it is returned to the resource class
186  //
187  return hashid;
188 }
189 
190 inline void fdManager::lazyInitTimerQueue ()
191 {
192  if ( ! this->pTimerQueue ) {
193  this->pTimerQueue = & epicsTimerQueuePassive::create ( *this );
194  }
195 }
196 
197 inline epicsTimer & fdManager::createTimer ()
198 {
199  this->lazyInitTimerQueue ();
200  return this->pTimerQueue->createTimer ();
201 }
202 
203 #endif // fdManagerH_included
204 
Platform independent socket support library API.
EPICS time-stamps (epicsTimeStamp), epicsTime C++ class and C functions for handling wall-clock times...