This is Unofficial EPICS BASE Doxygen Site
serverChannelImpl.cpp
Go to the documentation of this file.
1 
7 #include <pv/reftrack.h>
8 
9 #define epicsExportSharedSymbols
10 #include <pv/serverChannelImpl.h>
11 
12 using namespace epics::pvData;
13 
14 namespace epics {
15 namespace pvAccess {
16 
17 size_t ServerChannel::num_instances;
18 
19 ServerChannel::ServerChannel(Channel::shared_pointer const & channel,
20  const ChannelRequester::shared_pointer &requester,
21  pvAccessID cid, pvAccessID sid):
22  _channel(channel),
23  _requester(requester),
24  _cid(cid),
25  _sid(sid),
26  _destroyed(false)
27 {
28  REFTRACE_INCREMENT(num_instances);
29  if (!channel.get())
30  {
31  THROW_BASE_EXCEPTION("non-null channel required");
32  }
33 }
34 
35 void ServerChannel::registerRequest(const pvAccessID id, const std::tr1::shared_ptr<BaseChannelRequester> & request)
36 {
37  Lock guard(_mutex);
38  if(_destroyed) throw std::logic_error("Can't registerRequest() for destory'd server channel");
39  _requests[id] = request;
40 }
41 
43 {
44  Lock guard(_mutex);
45  _requests_t::iterator iter = _requests.find(id);
46  if(iter != _requests.end())
47  {
48  _requests.erase(iter);
49  }
50 }
51 
52 std::tr1::shared_ptr<BaseChannelRequester> ServerChannel::getRequest(const pvAccessID id)
53 {
54  Lock guard(_mutex);
55  _requests_t::iterator iter = _requests.find(id);
56  if(iter != _requests.end())
57  {
58  return iter->second;
59  }
60  return BaseChannelRequester::shared_pointer();
61 }
62 
64 {
65  _requests_t reqs;
66  {
67  Lock guard(_mutex);
68 
69  if (_destroyed) return;
70  _destroyed = true;
71 
72  // destroy all requests
73  // take ownership of _requests locally to prevent
74  // removal via unregisterRequest() during iteration
75  _requests.swap(reqs);
76 
77  // ... and the channel
78  // TODO try catch
79  _channel->destroy();
80  }
81  // unlock our before destroy.
82  // our mutex is subordinate to operation mutex
83 
84  for(_requests_t::const_iterator it=reqs.begin(), end=reqs.end(); it!=end; ++it)
85  {
86  const _requests_t::mapped_type& req = it->second;
87  // will call unregisterRequest() which is now a no-op
88  req->destroy();
89  // May still be in the send queue
90  }
91 }
92 
94 {
95  destroy();
96  REFTRACE_DECREMENT(num_instances);
97 }
98 
100 {
101  printInfo(stdout);
102 }
103 
104 void ServerChannel::printInfo(FILE *fd) const
105 {
106  fprintf(fd,"CLASS : %s\n", typeid(*this).name());
107  fprintf(fd,"CHANNEL : %s\n", typeid(*_channel).name());
108 }
109 
110 void ServerChannel::installGetField(const GetFieldRequester::shared_pointer& gf)
111 {
112  GetFieldRequester::shared_pointer prev;
113  {
114  epicsGuard<epicsMutex> G(_mutex);
115  prev.swap(_active_requester);
116  _active_requester = gf;
117  }
118  if(prev) {
119  prev->getDone(Status::error("Aborted"), FieldConstPtr());
120  }
121 }
122 
124 {
125  GetFieldRequester::shared_pointer prev;
126  {
127  epicsGuard<epicsMutex> G(_mutex);
128  if(_active_requester.get()==req)
129  prev.swap(_active_requester);
130  }
131 }
132 
133 }
134 }
std::string request
void installGetField(const GetFieldRequester::shared_pointer &gf)
epicsInt32 pvAccessID
Definition: pvaDefs.h:18
static Status error(const std::string &m)
Definition: status.h:50
TODO only here because of the Lockable.
Definition: ntaggregate.cpp:16
A lock for multithreading.
Definition: lock.h:36
void completeGetField(GetFieldRequester *req)
pvData
Definition: monitor.h:428
const ChannelProcessRequester::weak_pointer requester
Definition: pvAccess.cpp:68
std::tr1::shared_ptr< const Field > FieldConstPtr
Definition: pvIntrospect.h:137
#define stdout
Definition: epicsStdio.h:30
#define THROW_BASE_EXCEPTION(msg)
void registerRequest(pvAccessID id, const std::tr1::shared_ptr< BaseChannelRequester > &request)
std::tr1::shared_ptr< BaseChannelRequester > getRequest(pvAccessID id)
may return NULL
void unregisterRequest(pvAccessID id)
#define false
Definition: flexdef.h:85