pva2pva  1.4.1
 All Classes Functions Variables Pages
chancache.h
1 #ifndef CHANCACHE_H
2 #define CHANCACHE_H
3 
4 #include <string>
5 #include <map>
6 #include <set>
7 #include <deque>
8 
9 #include <epicsMutex.h>
10 #include <epicsTimer.h>
11 
12 #include <pv/pvAccess.h>
13 
14 #include "weakmap.h"
15 #include "weakset.h"
16 
17 struct ChannelCache;
18 struct ChannelCacheEntry;
19 struct MonitorUser;
20 struct GWChannel;
21 
22 struct MonitorCacheEntry : public epics::pvData::MonitorRequester
23 {
24  POINTER_DEFINITIONS(MonitorCacheEntry);
25  static size_t num_instances;
26  weak_pointer weakref;
27 
28  ChannelCacheEntry * const chan;
29 
30  const size_t bufferSize; // DS requested buffer size
31 
32  // to avoid yet another mutex borrow interested.mutex() for our members
33  inline epicsMutex& mutex() const { return interested.mutex(); }
34 
35  typedef std::vector<epicsUInt8> pvrequest_t;
36 
37  bool havedata; // set when initial update is received
38  bool done; // set when unlisten() is received
39  size_t nwakeups; // # of upstream monitorEvent() calls
40  size_t nevents; // # of upstream events poll()'d
41 
42  epics::pvData::StructureConstPtr typedesc;
46  epics::pvData::MonitorElement::shared_pointer lastelem;
47  epics::pvData::MonitorPtr mon;
48  epics::pvData::Status startresult;
49 
51  interested_t interested;
52 
53  MonitorCacheEntry(ChannelCacheEntry *ent, const epics::pvData::PVStructure::shared_pointer& pvr);
54  virtual ~MonitorCacheEntry();
55 
56  virtual void monitorConnect(epics::pvData::Status const & status,
57  epics::pvData::MonitorPtr const & monitor,
58  epics::pvData::StructureConstPtr const & structure);
59  virtual void monitorEvent(epics::pvData::MonitorPtr const & monitor);
60  virtual void unlisten(epics::pvData::MonitorPtr const & monitor);
61 
62  virtual std::string getRequesterName();
63 };
64 
65 struct MonitorUser : public epics::pvData::Monitor
66 {
67  POINTER_DEFINITIONS(MonitorUser);
68  static size_t num_instances;
69  weak_pointer weakref;
70 
71  inline epicsMutex& mutex() const { return entry->mutex(); }
72 
73  MonitorCacheEntry::shared_pointer entry;
74  epics::pvData::MonitorRequester::weak_pointer req;
75  std::tr1::weak_ptr<GWChannel> srvchan;
76 
77  // guards queues and member variables
78  bool initial;
79  bool running;
80  bool inoverflow;
81  size_t nwakeups; // # of monitorEvent() calls to req
82  size_t nevents; // total # events queued
83  size_t ndropped; // # of events drop because our queue was full
84 
85  std::deque<epics::pvData::MonitorElementPtr> filled, empty;
86  std::set<epics::pvData::MonitorElementPtr> inuse;
87 
88  epics::pvData::MonitorElementPtr overflowElement;
89 
90  MonitorUser(const MonitorCacheEntry::shared_pointer&);
91  virtual ~MonitorUser();
92 
93  virtual void destroy();
94 
95  virtual epics::pvData::Status start();
96  virtual epics::pvData::Status stop();
97  virtual epics::pvData::MonitorElementPtr poll();
98  virtual void release(epics::pvData::MonitorElementPtr const & monitorElement);
99 
100  virtual std::string getRequesterName();
101 };
102 
104 {
105  POINTER_DEFINITIONS(ChannelCacheEntry);
106  static size_t num_instances;
107 
108  const std::string channelName;
109  ChannelCache * const cache;
110 
111  // to avoid yet another mutex borrow interested.mutex() for our members
112  inline epicsMutex& mutex() const { return interested.mutex(); }
113 
114  // clientChannel
115  epics::pvAccess::Channel::shared_pointer channel;
116  epics::pvAccess::ChannelRequester::shared_pointer requester;
117 
118  bool dropPoke;
119 
121  interested_t interested;
122 
123  typedef MonitorCacheEntry::pvrequest_t pvrequest_t;
125  mon_entries_t mon_entries;
126 
127  ChannelCacheEntry(ChannelCache*, const std::string& n);
128  virtual ~ChannelCacheEntry();
129 
130  // this exists as a seperate object to prevent a reference loop
131  // ChannelCacheEntry -> pva::Channel -> CRequester
132  struct CRequester : public epics::pvAccess::ChannelRequester
133  {
134  static size_t num_instances;
135 
136  CRequester(const ChannelCacheEntry::shared_pointer& p);
137  virtual ~CRequester();
138  ChannelCacheEntry::weak_pointer chan;
139  // for Requester
140  virtual std::string getRequesterName();
141  // for ChannelRequester
142  virtual void channelCreated(const epics::pvData::Status& status,
143  epics::pvAccess::Channel::shared_pointer const & channel);
144  virtual void channelStateChange(epics::pvAccess::Channel::shared_pointer const & channel,
145  epics::pvAccess::Channel::ConnectionState connectionState);
146  };
147 };
148 
152 {
153  typedef std::map<std::string, ChannelCacheEntry::shared_pointer > entries_t;
154 
155  // cacheLock should not be held while calling *Requester methods
156  epicsMutex cacheLock;
157 
158  entries_t entries;
159 
160  epics::pvAccess::ChannelProvider::shared_pointer provider; // client Provider
161 
162  epicsTimerQueueActive *timerQueue;
163  epicsTimer *cleanTimer;
164  struct cacheClean;
165  cacheClean *cleaner;
166  size_t cleanerRuns;
167  size_t cleanerDust;
168 
169  ChannelCache(const epics::pvAccess::ChannelProvider::shared_pointer& prov);
170  ~ChannelCache();
171 
172  ChannelCacheEntry::shared_pointer lookup(const std::string& name);
173 };
174 
175 #endif // CHANCACHE_H
176 
epics::pvData::MonitorElement::shared_pointer lastelem
Definition: chancache.h:46
Definition: chancache.h:132
Definition: chancache.h:103
epicsMutex & mutex() const
Definition: weakset.h:199
Definition: chancache.h:22