rogue
Loading...
Searching...
No Matches
Master.cpp
Go to the documentation of this file.
1
17#include "rogue/Directives.h"
18
20
21#include <unistd.h>
22
23#include <memory>
24#include <vector>
25
26#include "rogue/GeneralError.h"
27#include "rogue/GilRelease.h"
31
33
34#ifndef NO_PYTHON
35 #include <boost/python.hpp>
36namespace bp = boost::python;
37#endif
38
40ris::MasterPtr ris::Master::create() {
41 ris::MasterPtr msg = std::make_shared<ris::Master>();
42 return (msg);
43}
44
46ris::Master::Master() {
47 defSlave_ = ris::Slave::create();
48}
49
51ris::Master::~Master() {}
52
53// Get Slave Count
54uint32_t ris::Master::slaveCount() {
55 return slaves_.size();
56}
57
59void ris::Master::addSlave(ris::SlavePtr slave) {
61 std::lock_guard<std::mutex> lock(slaveMtx_);
62 slaves_.push_back(slave);
63}
64
66ris::FramePtr ris::Master::reqFrame(uint32_t size, bool zeroCopyEn) {
68 std::lock_guard<std::mutex> lock(slaveMtx_);
69
70 if (slaves_.size() == 0)
71 return (defSlave_->acceptReq(size, zeroCopyEn));
72 else
73 return (slaves_[0]->acceptReq(size, zeroCopyEn));
74}
75
77void ris::Master::sendFrame(FramePtr frame) {
78 std::vector<ris::SlavePtr> slaves;
79 std::vector<ris::SlavePtr>::reverse_iterator rit;
80
81 {
83 std::lock_guard<std::mutex> lock(slaveMtx_);
84 slaves = slaves_;
85 }
86
87 for (rit = slaves.rbegin(); rit != slaves.rend(); ++rit) (*rit)->acceptFrame(frame);
88}
89
90// Ensure passed frame is a single buffer
91bool ris::Master::ensureSingleBuffer(ris::FramePtr& frame, bool reqEn) {
92 // Frame is a single buffer
93 if (frame->bufferCount() == 1) {
94 return true;
95
96 } else if (!reqEn) {
97 return false;
98
99 } else {
100 uint32_t size = frame->getPayload();
101 ris::FramePtr nFrame = reqFrame(size, true);
102
103 if (nFrame->bufferCount() != 1) {
104 return false;
105
106 } else {
107 nFrame->setPayload(size);
108
109 ris::FrameIterator srcIter = frame->begin();
110 ris::FrameIterator dstIter = nFrame->begin();
111
112 ris::copyFrame(srcIter, size, dstIter);
113 frame = nFrame;
114 return true;
115 }
116 }
117}
118
119void ris::Master::stop() {}
120
121void ris::Master::setup_python() {
122#ifndef NO_PYTHON
123
124 bp::class_<ris::Master, ris::MasterPtr, boost::noncopyable>("Master", bp::init<>())
125 .def("_addSlave", &ris::Master::addSlave)
126 .def("_slaveCount", &ris::Master::slaveCount)
127 .def("_reqFrame", &ris::Master::reqFrame)
128 .def("_sendFrame", &ris::Master::sendFrame)
129 .def("_stop", &ris::Master::stop)
130 .def("__eq__", &ris::Master::equalsPy)
131 .def("__rshift__", &ris::Master::rshiftPy);
132
133#endif
134}
135
136#ifndef NO_PYTHON
137
138void ris::Master::equalsPy(boost::python::object p) {
139 ris::MasterPtr rMst;
140 ris::SlavePtr rSlv;
141 ris::SlavePtr lSlv;
142
143 // Attempt to cast local pointer to slave
144 lSlv = std::dynamic_pointer_cast<ris::Slave>(shared_from_this());
145
146 // Attempt to access object as a stream master
147 boost::python::extract<ris::MasterPtr> get_master(p);
148
149 // Test extraction
150 if (get_master.check()) {
151 rMst = get_master();
152
153 // Otherwise look for indirect call
154 } else if (PyObject_HasAttrString(p.ptr(), "_getStreamMaster")) {
155 // Attempt to convert returned object to master pointer
156 boost::python::extract<ris::MasterPtr> get_master(p.attr("_getStreamMaster")());
157
158 // Test extraction
159 if (get_master.check()) {
160 rMst = get_master();
161 }
162 }
163
164 // Attempt to access object as a stream slave
165 boost::python::extract<ris::SlavePtr> get_slave(p);
166
167 // Test extraction
168 if (get_slave.check()) {
169 rSlv = get_slave();
170
171 // Otherwise look for indirect call
172 } else if (PyObject_HasAttrString(p.ptr(), "_getStreamSlave")) {
173 // Attempt to convert returned object to slave pointer
174 boost::python::extract<ris::SlavePtr> get_slave(p.attr("_getStreamSlave")());
175
176 // Test extraction
177 if (get_slave.check()) {
178 rSlv = get_slave();
179 }
180 }
181
182 if (rMst == NULL || rSlv == NULL || lSlv == NULL)
183 throw(rogue::GeneralError::create("stream::Master::equalsPy",
184 "Attempt to use == with an incompatible stream slave"));
185
186 // Make connections
187 addSlave(rSlv);
188 rMst->addSlave(lSlv);
189}
190
191bp::object ris::Master::rshiftPy(bp::object p) {
192 ris::SlavePtr slv;
193
194 // First Attempt to access object as a stream slave
195 boost::python::extract<ris::SlavePtr> get_slave(p);
196
197 // Test extraction
198 if (get_slave.check()) {
199 slv = get_slave();
200
201 // Otherwise look for indirect call
202 } else if (PyObject_HasAttrString(p.ptr(), "_getStreamSlave")) {
203 // Attempt to convert returned object to slave pointer
204 boost::python::extract<ris::SlavePtr> get_slave(p.attr("_getStreamSlave")());
205
206 // Test extraction
207 if (get_slave.check()) {
208 slv = get_slave();
209 }
210 }
211
212 if (slv != NULL)
213 addSlave(slv);
214 else
215 throw(rogue::GeneralError::create("stream::Master::rshiftPy",
216 "Attempt to use >> with incompatible stream slave"));
217
218 return p;
219}
220
221#endif
222
224void ris::Master::operator==(ris::SlavePtr& other) {
225 ris::SlavePtr lSlv;
226 ris::MasterPtr rMst;
227
228 // Attempt to cast local pointer to slave
229 lSlv = std::dynamic_pointer_cast<ris::Slave>(shared_from_this());
230
231 // Attempt to cast other pointer to master
232 rMst = std::dynamic_pointer_cast<ris::Master>(other);
233
234 if (rMst == NULL || lSlv == NULL)
235 throw(rogue::GeneralError::create("stream::Master::equalsPy",
236 "Attempt to use == with an incompatible stream slave"));
237
238 rMst->addSlave(lSlv);
239 addSlave(other);
240}
241
243ris::SlavePtr& ris::Master::operator>>(ris::SlavePtr& other) {
244 addSlave(other);
245 return other;
246}
static GeneralError create(std::string src, const char *fmt,...)
Creates a formatted error instance.
RAII helper that releases the Python GIL for a scope.
Definition GilRelease.h:36
Random-access byte iterator across a Frame payload.
std::shared_ptr< rogue::interfaces::stream::Master > MasterPtr
Shared pointer alias for Master.
Definition Master.h:221
std::shared_ptr< rogue::interfaces::stream::Slave > SlavePtr
Shared pointer alias for Slave.
Definition Slave.h:234
static void copyFrame(rogue::interfaces::stream::FrameIterator &srcIter, uint32_t size, rogue::interfaces::stream::FrameIterator &dstIter)
Copies bytes between frame iterators.
std::shared_ptr< rogue::interfaces::stream::Frame > FramePtr
Shared pointer alias for Frame.
Definition Frame.h:549