rogue
Loading...
Searching...
No Matches
Slave.cpp
Go to the documentation of this file.
1
19#include "rogue/Directives.h"
20
22
23#include <inttypes.h>
24#include <unistd.h>
25
26#include <cstdio>
27#include <cstring>
28#include <memory>
29#include <string>
30
31#include "rogue/GeneralError.h"
32#include "rogue/GilRelease.h"
33#include "rogue/Logging.h"
34#include "rogue/ScopedGil.h"
40
42
43#ifndef NO_PYTHON
44 #include <boost/python.hpp>
45namespace bp = boost::python;
46#endif
47
49ris::SlavePtr ris::Slave::create() {
50 ris::SlavePtr slv = std::make_shared<ris::Slave>();
51 return (slv);
52}
53
55ris::Slave::Slave() {
56 debug_ = 0;
57 frameCount_ = 0;
58 frameBytes_ = 0;
59}
60
62ris::Slave::~Slave() {}
63
64void ris::Slave::stop() {}
65
67void ris::Slave::setDebug(uint32_t debug, std::string name) {
68 debug_ = debug;
69 log_ = rogue::Logging::create(name.c_str());
70}
71
73void ris::Slave::acceptFrame(ris::FramePtr frame) {
75
76 uint32_t count;
77 uint8_t val;
78
80 ris::FrameLockPtr lock = frame->lock();
81
82 frameCount_++;
83 frameBytes_ += frame->getPayload();
84
85 if (debug_ > 0) {
86 char buffer[1000];
87
88 log_->critical("Got Size=%" PRIu32 ", Error=%" PRIu8 ", Data:", frame->getPayload(), frame->getError());
89 snprintf(buffer, sizeof(buffer), " ");
90
91 count = 0;
92 for (it = frame->begin(); (count < debug_) && (it != frame->end()); ++it) {
93 count++;
94 val = *it;
95
96 snprintf(buffer + strlen(buffer), 1000 - strlen(buffer), " 0x%.2x", val);
97 if (((count + 1) % 8) == 0) {
98 log_->critical(buffer);
99 snprintf(buffer, sizeof(buffer), " ");
100 }
101 }
102
103 if (strlen(buffer) > 5) log_->log(100, buffer);
104 }
105}
106
107#ifndef NO_PYTHON
108
110void ris::SlaveWrap::acceptFrame(ris::FramePtr frame) {
111 {
113
114 if (boost::python::override pb = this->get_override("_acceptFrame")) {
115 try {
116 pb(frame);
117 return;
118 } catch (...) {
119 PyErr_Print();
120 }
121 }
122 }
123 ris::Slave::acceptFrame(frame);
124}
125
127void ris::SlaveWrap::defAcceptFrame(ris::FramePtr frame) {
128 ris::Slave::acceptFrame(frame);
129}
130
131#endif
132
134uint64_t ris::Slave::getFrameCount() {
135 return (frameCount_);
136}
137
139uint64_t ris::Slave::getByteCount() {
140 return (frameBytes_);
141}
142
143// Ensure passed frame is a single buffer
144bool ris::Slave::ensureSingleBuffer(ris::FramePtr& frame, bool reqEn) {
145 // Frame is a single buffer
146 if (frame->bufferCount() == 1) {
147 return true;
148
149 } else if (!reqEn) {
150 return false;
151
152 } else {
153 uint32_t size = frame->getPayload();
154 ris::FramePtr nFrame = reqLocalFrame(size, true);
155
156 if (nFrame->bufferCount() != 1) {
157 return false;
158
159 } else {
160 nFrame->setPayload(size);
161
162 ris::FrameIterator srcIter = frame->begin();
163 ris::FrameIterator dstIter = nFrame->begin();
164
165 ris::copyFrame(srcIter, size, dstIter);
166 frame = nFrame;
167 return true;
168 }
169 }
170}
171
172// Process a local frame request
173ris::FramePtr ris::Slave::reqLocalFrame(uint32_t size, bool zeroCopyEn) {
174 return ris::Pool::acceptReq(size, zeroCopyEn);
175}
176
177void ris::Slave::setup_python() {
178#ifndef NO_PYTHON
179
180 bp::class_<ris::SlaveWrap, ris::SlaveWrapPtr, boost::noncopyable>("Slave", bp::init<>())
181 .def("setDebug", &ris::Slave::setDebug)
182 .def("_acceptFrame", &ris::Slave::acceptFrame, &ris::SlaveWrap::defAcceptFrame)
183 .def("getFrameCount", &ris::Slave::getFrameCount)
184 .def("getByteCount", &ris::Slave::getByteCount)
185 .def("_stop", &ris::Slave::stop)
186 .def("getAllocCount", &ris::Pool::getAllocCount)
187 .def("getAllocBytes", &ris::Pool::getAllocBytes)
188 .def("setFixedSize", &ris::Pool::setFixedSize)
189 .def("getFixedSize", &ris::Pool::getFixedSize)
190 .def("setPoolSize", &ris::Pool::setPoolSize)
191 .def("getPoolSize", &ris::Pool::getPoolSize)
192 .def("__lshift__", &ris::Slave::lshiftPy);
193
194 bp::implicitly_convertible<ris::SlavePtr, ris::PoolPtr>();
195#endif
196}
197
198#ifndef NO_PYTHON
199
200// Support << operator in python
201bp::object ris::Slave::lshiftPy(bp::object p) {
202 ris::MasterPtr mst;
203
204 // First Attempt to access object as a stream master
205 boost::python::extract<ris::MasterPtr> get_master(p);
206
207 // Test extraction
208 if (get_master.check()) {
209 mst = get_master();
210
211 // Otherwise look for indirect call
212 } else if (PyObject_HasAttrString(p.ptr(), "_getStreamMaster")) {
213 // Attempt to convert returned object to master pointer
214 boost::python::extract<ris::MasterPtr> get_master(p.attr("_getStreamMaster")());
215
216 // Test extraction
217 if (get_master.check()) mst = get_master();
218 }
219
220 if (mst != NULL)
222 else
223 throw(rogue::GeneralError::create("stream::Slave::lshiftPy",
224 "Attempt to use << with incompatable stream master"));
225
226 return p;
227}
228
229#endif
230
232ris::MasterPtr& ris::Slave::operator<<(ris::MasterPtr& other) {
234 return other;
235}
Typed shared-from-this helper for Rogue classes.
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
static std::shared_ptr< rogue::Logging > create(const std::string &name, bool quiet=false)
Creates a logger instance.
Definition Logging.cpp:60
RAII helper that acquires the Python GIL for a scope.
Definition ScopedGil.h:35
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
std::shared_ptr< rogue::interfaces::stream::FrameLock > FrameLockPtr
Shared pointer alias for FrameLock.
Definition FrameLock.h:110