PageRenderTime 45ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/ATF2/control-software/epics-3.14.10/base/src/libCom/fdmgr/fdmgr.cpp

http://atf2flightsim.googlecode.com/
C++ | 337 lines | 250 code | 49 blank | 38 comment | 20 complexity | 5496fd60deae650832c11b1a6faac6ff MD5 | raw file
Possible License(s): BSD-2-Clause, LGPL-2.0, IPL-1.0, BSD-3-Clause
  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. //
  12. // File descriptor management C++ class library
  13. // (for multiplexing IO in a single threaded environment)
  14. //
  15. // Author Jeffrey O. Hill
  16. // johill@lanl.gov
  17. // 505 665 1831
  18. //
  19. // NOTES:
  20. // 1) the routines in this file provide backward compatibility with the original
  21. // "C" based file descriptor manager API
  22. // 2) This library is _not_ thread safe
  23. //
  24. #include <stddef.h>
  25. #define epicsExportSharedSymbols
  26. #include "locationException.h"
  27. #include "epicsAssert.h"
  28. #include "fdManager.h"
  29. #include "fdmgr.h"
  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. class fdRegForOldFdmgr : public fdReg {
  35. public:
  36. //
  37. // exceptions
  38. //
  39. class noFunctionSpecified {};
  40. class doubleDelete {};
  41. epicsShareFunc fdRegForOldFdmgr (const SOCKET fdIn, const fdRegType type,
  42. const bool onceOnly, fdManager &manager, pCallBackFDMgr pFunc, void *pParam);
  43. epicsShareFunc ~fdRegForOldFdmgr ();
  44. private:
  45. pCallBackFDMgr pFunc;
  46. void *pParam;
  47. epicsShareFunc virtual void callBack ();
  48. fdRegForOldFdmgr ( const fdRegForOldFdmgr & );
  49. fdRegForOldFdmgr & operator = ( const fdRegForOldFdmgr & );
  50. };
  51. class oldFdmgr;
  52. //
  53. // timerForOldFdmgr
  54. //
  55. class timerForOldFdmgr : public epicsTimerNotify, public chronIntIdRes<timerForOldFdmgr> {
  56. public:
  57. epicsShareFunc timerForOldFdmgr (oldFdmgr &fdmgr, double delay, pCallBackFDMgr pFunc, void *pParam);
  58. epicsShareFunc virtual ~timerForOldFdmgr ();
  59. //
  60. // exceptions
  61. //
  62. class noFunctionSpecified {};
  63. class doubleDelete {};
  64. private:
  65. epicsTimer &timer;
  66. oldFdmgr &fdmgr;
  67. pCallBackFDMgr pFunc;
  68. void *pParam;
  69. unsigned id;
  70. epicsShareFunc expireStatus expire ( const epicsTime & currentTime );
  71. timerForOldFdmgr ( const timerForOldFdmgr & );
  72. timerForOldFdmgr & operator = ( const timerForOldFdmgr & );
  73. };
  74. class oldFdmgr : public fdManager {
  75. friend class timerForOldFdmgr;
  76. friend epicsShareFunc int epicsShareAPI fdmgr_clear_timeout (fdctx *pfdctx, fdmgrAlarmId id);
  77. public:
  78. oldFdmgr ();
  79. private:
  80. chronIntIdResTable <timerForOldFdmgr> resTbl;
  81. oldFdmgr ( const oldFdmgr & );
  82. oldFdmgr & operator = ( const oldFdmgr & );
  83. };
  84. #ifdef _MSC_VER
  85. # pragma warning ( push )
  86. # pragma warning ( disable:4660 )
  87. #endif
  88. template class chronIntIdResTable <timerForOldFdmgr>;
  89. template class resTable<timerForOldFdmgr, chronIntId>;
  90. #ifdef _MSC_VER
  91. # pragma warning ( pop )
  92. #endif
  93. epicsShareFunc fdRegForOldFdmgr::fdRegForOldFdmgr
  94. (const SOCKET fdIn, const fdRegType typeIn,
  95. const bool onceOnlyIn, fdManager &managerIn,
  96. pCallBackFDMgr pFuncIn, void *pParamIn) :
  97. fdReg (fdIn, typeIn, onceOnlyIn, managerIn),
  98. pFunc (pFuncIn), pParam (pParamIn)
  99. {
  100. if (pFuncIn==NULL) {
  101. throwWithLocation ( noFunctionSpecified () );
  102. }
  103. }
  104. epicsShareFunc fdRegForOldFdmgr::~fdRegForOldFdmgr ()
  105. {
  106. if (this->pFunc==NULL) {
  107. throwWithLocation ( doubleDelete () );
  108. }
  109. }
  110. epicsShareFunc void fdRegForOldFdmgr::callBack ()
  111. {
  112. (*this->pFunc) (this->pParam);
  113. }
  114. timerForOldFdmgr::timerForOldFdmgr ( oldFdmgr &fdmgrIn,
  115. double delayIn, pCallBackFDMgr pFuncIn, void * pParamIn ) :
  116. timer ( fdmgrIn.createTimer() ),
  117. fdmgr ( fdmgrIn ), pFunc ( pFuncIn ), pParam( pParamIn )
  118. {
  119. if ( pFuncIn == NULL ) {
  120. throwWithLocation ( noFunctionSpecified () );
  121. }
  122. this->fdmgr.resTbl.idAssignAdd (*this);
  123. this->timer.start ( *this, delayIn );
  124. }
  125. timerForOldFdmgr::~timerForOldFdmgr ()
  126. {
  127. this->fdmgr.resTbl.remove ( this->getId() );
  128. this->timer.destroy ();
  129. }
  130. epicsTimerNotify::expireStatus timerForOldFdmgr::expire ( const epicsTime & )
  131. {
  132. (*this->pFunc) (this->pParam);
  133. return noRestart;
  134. }
  135. oldFdmgr::oldFdmgr () {}
  136. extern "C" epicsShareFunc fdctx * epicsShareAPI fdmgr_init (void)
  137. {
  138. oldFdmgr *pfdm;
  139. try {
  140. pfdm = new oldFdmgr();
  141. }
  142. catch (...)
  143. {
  144. pfdm = NULL;
  145. }
  146. return (fdctx *) pfdm;
  147. }
  148. extern "C" epicsShareFunc fdmgrAlarmId epicsShareAPI fdmgr_add_timeout (
  149. fdctx *pfdctx, struct timeval *ptimeout, pCallBackFDMgr pFunc, void *pParam)
  150. {
  151. double delay = ptimeout->tv_sec + ptimeout->tv_usec / static_cast <const double> (uSecPerSec);
  152. oldFdmgr *pfdm = static_cast <oldFdmgr *> (pfdctx);
  153. timerForOldFdmgr *pTimer;
  154. unsigned id = fdmgrNoAlarm;
  155. if (!pfdm) {
  156. return fdmgrNoAlarm;
  157. }
  158. while (true) {
  159. try {
  160. pTimer = new timerForOldFdmgr
  161. (*pfdm, delay, pFunc, pParam);
  162. }
  163. catch (...)
  164. {
  165. pTimer = NULL;
  166. }
  167. if (pTimer) {
  168. id = pTimer->getId ();
  169. if (id!=fdmgrNoAlarm) {
  170. break;
  171. }
  172. else {
  173. delete pTimer;
  174. }
  175. }
  176. else {
  177. break;
  178. }
  179. }
  180. return id;
  181. }
  182. extern "C" epicsShareFunc int epicsShareAPI fdmgr_clear_timeout (fdctx *pfdctx, fdmgrAlarmId id)
  183. {
  184. oldFdmgr *pfdm = static_cast <oldFdmgr *> (pfdctx);
  185. timerForOldFdmgr *pTimer;
  186. try {
  187. pTimer = pfdm->resTbl.remove (id);
  188. }
  189. catch (...)
  190. {
  191. pTimer = NULL;
  192. }
  193. if (pTimer==NULL) {
  194. return -1;
  195. }
  196. delete pTimer;
  197. return 0;
  198. }
  199. extern "C" epicsShareFunc int epicsShareAPI fdmgr_add_callback ( // X aCC 361
  200. fdctx *pfdctx, SOCKET fd, enum fdi_type fdi, pCallBackFDMgr pFunc, void *pParam)
  201. {
  202. oldFdmgr *pfdm = static_cast <oldFdmgr *> (pfdctx);
  203. fdRegForOldFdmgr *pfdrbc;
  204. bool onceOnly = (fdi==fdi_write);
  205. unsigned fdiType;
  206. if (pfdm==NULL) {
  207. return -1;
  208. }
  209. if (pFunc==NULL) {
  210. return -1;
  211. }
  212. if (fdi<0) {
  213. return -1;
  214. }
  215. fdiType = (unsigned) fdi;
  216. if (fdiType>=fdiToFdRegTypeNElements) {
  217. return -1;
  218. }
  219. try {
  220. pfdrbc = new fdRegForOldFdmgr (fd, fdiToFdRegType[fdiType], onceOnly, *pfdm, pFunc, pParam);
  221. }
  222. catch (...)
  223. {
  224. pfdrbc = NULL;
  225. }
  226. if (pfdrbc==NULL) {
  227. return -1;
  228. }
  229. else {
  230. return 0;
  231. }
  232. }
  233. extern "C" epicsShareFunc int epicsShareAPI fdmgr_clear_callback ( // X aCC 361
  234. fdctx *pfdctx, SOCKET fd, enum fdi_type fdi)
  235. {
  236. oldFdmgr *pfdm = static_cast <oldFdmgr *> (pfdctx);
  237. fdReg *pFDR;
  238. if (pfdm==NULL) {
  239. return -1;
  240. }
  241. try {
  242. pFDR = pfdm->lookUpFD (fd, fdiToFdRegType[fdi]);
  243. }
  244. catch (...)
  245. {
  246. pFDR = NULL;
  247. }
  248. if (pFDR==NULL) {
  249. return -1;
  250. }
  251. else {
  252. delete pFDR;
  253. return 0;
  254. }
  255. }
  256. extern "C" epicsShareFunc int epicsShareAPI fdmgr_pend_event (fdctx *pfdctx, struct timeval *ptimeout)
  257. {
  258. oldFdmgr *pfdm = static_cast <oldFdmgr *> (pfdctx);
  259. double delay = ptimeout->tv_sec + ptimeout->tv_usec / static_cast <const double> (uSecPerSec);
  260. try {
  261. pfdm->process (delay);
  262. }
  263. catch (...) {
  264. return -1;
  265. }
  266. return 0;
  267. }
  268. extern "C" epicsShareFunc int epicsShareAPI fdmgr_delete (fdctx *pfdctx)
  269. {
  270. oldFdmgr *pfdm = static_cast <oldFdmgr *> (pfdctx);
  271. delete pfdm;
  272. return 0;
  273. }
  274. /*
  275. * depricated interface
  276. */
  277. extern "C" epicsShareFunc int epicsShareAPI fdmgr_clear_fd (fdctx *pfdctx, SOCKET fd)
  278. {
  279. return fdmgr_clear_callback(pfdctx, fd, fdi_read);
  280. }
  281. /*
  282. * depricated interface
  283. */
  284. extern "C" epicsShareFunc int epicsShareAPI fdmgr_add_fd (
  285. fdctx *pfdctx, SOCKET fd, void (*pfunc)(void *pParam), void *param)
  286. {
  287. return fdmgr_add_callback (pfdctx, fd, fdi_read, pfunc, param);
  288. }