This is Unofficial EPICS BASE Doxygen Site
fdmgr.cpp
Go to the documentation of this file.
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 * EPICS BASE Versions 3.13.7
7 * and higher are 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
15 // johill@lanl.gov
16 // 505 665 1831
17 //
18 // NOTES:
19 // 1) the routines in this file provide backward compatibility with the original
20 // "C" based file descriptor manager API
21 // 2) This library is _not_ thread safe
22 //
23 
24 #include <stddef.h>
25 #include "locationException.h"
26 #include "epicsAssert.h"
27 #include "fdManager.h"
28 #include "fdmgr.h"
29 
30 static const fdRegType fdiToFdRegType[] = {fdrRead, fdrWrite, fdrException};
31 static const unsigned fdiToFdRegTypeNElements = sizeof (fdiToFdRegType) / sizeof (fdiToFdRegType[0]);
32 const unsigned mSecPerSec = 1000u;
33 const unsigned uSecPerSec = 1000u * mSecPerSec;
34 
35 class fdRegForOldFdmgr : public fdReg {
36 public:
37  //
38  // exceptions
39  //
41  class doubleDelete {};
42 
43  LIBCOM_API fdRegForOldFdmgr (const SOCKET fdIn, const fdRegType type,
44  const bool onceOnly, fdManager &manager, pCallBackFDMgr pFunc, void *pParam);
45  LIBCOM_API ~fdRegForOldFdmgr ();
46 
47 private:
48  pCallBackFDMgr pFunc;
49  void *pParam;
50  LIBCOM_API virtual void callBack ();
51  fdRegForOldFdmgr ( const fdRegForOldFdmgr & );
52  fdRegForOldFdmgr & operator = ( const fdRegForOldFdmgr & );
53 };
54 
55 class oldFdmgr;
56 
57 //
58 // timerForOldFdmgr
59 //
60 class timerForOldFdmgr : public epicsTimerNotify, public chronIntIdRes<timerForOldFdmgr> {
61 public:
62  LIBCOM_API timerForOldFdmgr (oldFdmgr &fdmgr, double delay, pCallBackFDMgr pFunc, void *pParam);
63  LIBCOM_API virtual ~timerForOldFdmgr ();
64 
65  //
66  // exceptions
67  //
69  class doubleDelete {};
70 private:
71  epicsTimer &timer;
72  oldFdmgr &fdmgr;
73  pCallBackFDMgr pFunc;
74  void *pParam;
75  unsigned id;
76  LIBCOM_API expireStatus expire ( const epicsTime & currentTime );
77  timerForOldFdmgr ( const timerForOldFdmgr & );
78  timerForOldFdmgr & operator = ( const timerForOldFdmgr & );
79 };
80 
81 class oldFdmgr : public fdManager {
82  friend class timerForOldFdmgr;
83  friend LIBCOM_API int epicsStdCall fdmgr_clear_timeout (fdctx *pfdctx, fdmgrAlarmId id);
84 
85 public:
86  oldFdmgr ();
87 
88 private:
90  oldFdmgr ( const oldFdmgr & );
91  oldFdmgr & operator = ( const oldFdmgr & );
92 };
93 
94 #ifdef _MSC_VER
95 # pragma warning ( push )
96 # pragma warning ( disable:4660 )
97 #endif
98 
101 
102 #ifdef _MSC_VER
103 # pragma warning ( pop )
104 #endif
105 
107  (const SOCKET fdIn, const fdRegType typeIn,
108  const bool onceOnlyIn, fdManager &managerIn,
109  pCallBackFDMgr pFuncIn, void *pParamIn) :
110  fdReg (fdIn, typeIn, onceOnlyIn, managerIn),
111  pFunc (pFuncIn), pParam (pParamIn)
112 {
113  if (pFuncIn==NULL) {
115  }
116 }
117 
119 {
120  if (this->pFunc==NULL) {
122  }
123 }
124 
125 LIBCOM_API void fdRegForOldFdmgr::callBack ()
126 {
127  (*this->pFunc) (this->pParam);
128 }
129 
131  double delayIn, pCallBackFDMgr pFuncIn, void * pParamIn ) :
132  timer ( fdmgrIn.createTimer() ),
133  fdmgr ( fdmgrIn ), pFunc ( pFuncIn ), pParam( pParamIn )
134 {
135  if ( pFuncIn == NULL ) {
137  }
138  this->fdmgr.resTbl.idAssignAdd (*this);
139  this->timer.start ( *this, delayIn );
140 }
141 
143 {
144  this->fdmgr.resTbl.remove ( this->getId() );
145  this->timer.destroy ();
146 }
147 
148 epicsTimerNotify::expireStatus timerForOldFdmgr::expire ( const epicsTime & )
149 {
150  (*this->pFunc) (this->pParam);
151  return noRestart;
152 }
153 
155 
156 extern "C" LIBCOM_API fdctx * epicsStdCall fdmgr_init (void)
157 {
158  oldFdmgr *pfdm;
159 
160  try {
161  pfdm = new oldFdmgr();
162  }
163  catch (...)
164  {
165  pfdm = NULL;
166  }
167 
168  return (fdctx *) pfdm;
169 }
170 
171 extern "C" LIBCOM_API fdmgrAlarmId epicsStdCall fdmgr_add_timeout (
172  fdctx *pfdctx, struct timeval *ptimeout, pCallBackFDMgr pFunc, void *pParam)
173 {
174  double delay = ptimeout->tv_sec + ptimeout->tv_usec / static_cast <const double> (uSecPerSec);
175  oldFdmgr *pfdm = static_cast <oldFdmgr *> (pfdctx);
176  timerForOldFdmgr *pTimer;
177  unsigned id = fdmgrNoAlarm;
178 
179  if (!pfdm) {
180  return fdmgrNoAlarm;
181  }
182 
183  while (true) {
184  try {
185  pTimer = new timerForOldFdmgr
186  (*pfdm, delay, pFunc, pParam);
187  }
188  catch (...)
189  {
190  pTimer = NULL;
191  }
192  if (pTimer) {
193  id = pTimer->getId ();
194  if (id!=fdmgrNoAlarm) {
195  break;
196  }
197  else {
198  delete pTimer;
199  }
200  }
201  else {
202  break;
203  }
204  }
205 
206  return id;
207 }
208 
209 extern "C" LIBCOM_API int epicsStdCall fdmgr_clear_timeout (fdctx *pfdctx, fdmgrAlarmId id)
210 {
211  oldFdmgr *pfdm = static_cast <oldFdmgr *> (pfdctx);
212  timerForOldFdmgr *pTimer;
213 
214  try {
215  pTimer = pfdm->resTbl.remove (id);
216  }
217  catch (...)
218  {
219  pTimer = NULL;
220  }
221 
222  if (pTimer==NULL) {
223  return -1;
224  }
225  delete pTimer;
226  return 0;
227 }
228 
229 extern "C" LIBCOM_API int epicsStdCall fdmgr_add_callback (
230  fdctx *pfdctx, SOCKET fd, enum fdi_type fdi, pCallBackFDMgr pFunc, void *pParam)
231 {
232  oldFdmgr *pfdm = static_cast <oldFdmgr *> (pfdctx);
233  fdRegForOldFdmgr *pfdrbc;
234  bool onceOnly = (fdi==fdi_write);
235  unsigned fdiType;
236 
237  if (pfdm==NULL) {
238  return -1;
239  }
240 
241  if (pFunc==NULL) {
242  return -1;
243  }
244 
245  if (fdi<0) {
246  return -1;
247  }
248 
249  fdiType = (unsigned) fdi;
250 
251  if (fdiType>=fdiToFdRegTypeNElements) {
252  return -1;
253  }
254 
255  try {
256  pfdrbc = new fdRegForOldFdmgr (fd, fdiToFdRegType[fdiType], onceOnly, *pfdm, pFunc, pParam);
257  }
258  catch (...)
259  {
260  pfdrbc = NULL;
261  }
262 
263  if (pfdrbc==NULL) {
264  return -1;
265  }
266  else {
267  return 0;
268  }
269 }
270 
271 extern "C" LIBCOM_API int epicsStdCall fdmgr_clear_callback (
272  fdctx *pfdctx, SOCKET fd, enum fdi_type fdi)
273 {
274  oldFdmgr *pfdm = static_cast <oldFdmgr *> (pfdctx);
275  fdReg *pFDR;
276 
277  if (pfdm==NULL) {
278  return -1;
279  }
280 
281  try {
282  pFDR = pfdm->lookUpFD (fd, fdiToFdRegType[fdi]);
283  }
284  catch (...)
285  {
286  pFDR = NULL;
287  }
288 
289  if (pFDR==NULL) {
290  return -1;
291  }
292  else {
293  delete pFDR;
294  return 0;
295  }
296 }
297 
298 extern "C" LIBCOM_API int epicsStdCall fdmgr_pend_event (fdctx *pfdctx, struct timeval *ptimeout)
299 {
300  oldFdmgr *pfdm = static_cast <oldFdmgr *> (pfdctx);
301  double delay = ptimeout->tv_sec + ptimeout->tv_usec / static_cast <const double> (uSecPerSec);
302 
303  try {
304  pfdm->process (delay);
305  }
306  catch (...) {
307  return -1;
308  }
309 
310  return 0;
311 }
312 
313 extern "C" LIBCOM_API int epicsStdCall fdmgr_delete (fdctx *pfdctx)
314 {
315  oldFdmgr *pfdm = static_cast <oldFdmgr *> (pfdctx);
316  delete pfdm;
317  return 0;
318 }
319 
320 /*
321  * depricated interface
322  */
323 extern "C" LIBCOM_API int epicsStdCall fdmgr_clear_fd (fdctx *pfdctx, SOCKET fd)
324 {
325  return fdmgr_clear_callback(pfdctx, fd, fdi_read);
326 }
327 
328 /*
329  * depricated interface
330  */
331 extern "C" LIBCOM_API int epicsStdCall fdmgr_add_fd (
332  fdctx *pfdctx, SOCKET fd, void (*pfunc)(void *pParam), void *param)
333 {
334  return fdmgr_add_callback (pfdctx, fd, fdi_read, pfunc, param);
335 }
virtual LIBCOM_API ~timerForOldFdmgr()
Definition: fdmgr.cpp:142
LIBCOM_API int epicsStdCall fdmgr_clear_fd(fdctx *pfdctx, SOCKET fd)
Definition: fdmgr.cpp:323
LIBCOM_API int epicsStdCall fdmgr_pend_event(fdctx *pfdctx, struct timeval *ptimeout)
Definition: fdmgr.cpp:298
void(* pCallBackFDMgr)(void *)
Definition: fdmgr.h:37
LIBCOM_API fdRegForOldFdmgr(const SOCKET fdIn, const fdRegType type, const bool onceOnly, fdManager &manager, pCallBackFDMgr pFunc, void *pParam)
Definition: fdmgr.cpp:107
An EPICS-specific replacement for ANSI C&#39;s assert.
void fdctx
Definition: fdmgr.h:36
void destroy()
Definition: timer.cpp:47
fdi_type
Definition: fdmgr.h:33
pvd::StructureConstPtr type
fdRegType
Definition: fdManager.h:29
#define NULL
Definition: catime.c:38
Definition: fdmgr.h:33
LIBCOM_API fdmgrAlarmId epicsStdCall fdmgr_add_timeout(fdctx *pfdctx, struct timeval *ptimeout, pCallBackFDMgr pFunc, void *pParam)
Definition: fdmgr.cpp:171
LIBCOM_API int epicsStdCall fdmgr_delete(fdctx *pfdctx)
Definition: fdmgr.cpp:313
LIBCOM_API int epicsStdCall fdmgr_clear_timeout(fdctx *pfdctx, fdmgrAlarmId id)
Definition: fdmgr.cpp:209
LIBCOM_API class fdReg * lookUpFD(const SOCKET fd, const fdRegType type)
Definition: fdManager.cpp:333
void idAssignAdd(ITEM &item)
Definition: resourceLib.h:964
LIBCOM_API timerForOldFdmgr(oldFdmgr &fdmgr, double delay, pCallBackFDMgr pFunc, void *pParam)
Definition: fdmgr.cpp:130
BSD and SRV5 Unix timestamp.
Definition: epicsTime.h:52
int SOCKET
Definition: osdSock.h:31
LIBCOM_API int epicsStdCall fdmgr_clear_callback(fdctx *pfdctx, SOCKET fd, enum fdi_type fdi)
Definition: fdmgr.cpp:271
LIBCOM_API void process(double delay)
Definition: fdManager.cpp:80
T * remove(const ID &idIn)
Definition: resourceLib.h:297
fdReg(const SOCKET fdIn, const fdRegType type, const bool onceOnly=false, fdManager &manager=fileDescriptorManager)
Definition: fdManager.cpp:345
LIBCOM_API int epicsStdCall fdmgr_add_callback(fdctx *pfdctx, SOCKET fd, enum fdi_type fdi, pCallBackFDMgr pFunc, void *pParam)
Definition: fdmgr.cpp:229
LIBCOM_API int epicsStdCall fdmgr_add_fd(fdctx *pfdctx, SOCKET fd, void(*pfunc)(void *pParam), void *param)
Definition: fdmgr.cpp:331
LIBCOM_API fdctx *epicsStdCall fdmgr_init(void)
Definition: fdmgr.cpp:156
const unsigned uSecPerSec
Definition: fdmgr.cpp:33
unsigned fdmgrAlarmId
Definition: fdmgr.h:60
oldFdmgr()
Definition: fdmgr.cpp:154
#define throwWithLocation(parm)
#define fdmgrNoAlarm
Definition: fdmgr.h:76
LIBCOM_API ~fdRegForOldFdmgr()
Definition: fdmgr.cpp:118
const unsigned mSecPerSec
Definition: fdmgr.cpp:32
void start(class epicsTimerNotify &, const epicsTime &)
Definition: timer.cpp:59