19 #include <epicsTypes.h> 20 #include <cantProceed.h> 25 #include <epicsExport.h> 31 # define CONTAINER(ptr, structure, member) ({ \ 32 const __typeof(((structure*)0)->member) *_ptr = (ptr); \ 33 (structure*)((char*)_ptr - offsetof(structure, member)); \ 36 # define CONTAINER(ptr, structure, member) \ 37 ((structure*)((char*)(ptr) - offsetof(structure, member))) 41 #define CBINIT(ptr, prio, fn, valptr) \ 43 callbackSetPriority(prio, ptr); \ 44 callbackSetCallback(fn, ptr); \ 45 callbackSetUser(valptr, ptr); \ 52 void defaulterr(
void *, epicsStatus err,
53 epicsUInt32 ,
const epicsUInt8* )
57 case 1: errlogPrintf(
"Data buffer Rx rate too high, dropped buffers\n");
break;
58 case 2: errlogPrintf(
"Data buffer Rx checksum error\n");
break;
59 default: errlogPrintf(
"Data buffer Rx error %d\n",err);
68 ,m_bsize(bsize ? bsize : 2048)
74 CBINIT(&received_cb, priorityMedium, &bufRxManager::received,
this);
76 for(
unsigned int i=0; i<qdepth; i++) {
77 buffer *t=(buffer*)callocMustSucceed(1,
sizeof(buffer)-1+m_bsize,
"bufRxManager buffer");
78 ellAdd(&freebufs, &t->node);
88 for(node=ellFirst(&freebufs), next=node ? ellNext(node):NULL;
90 node=next, next=next ? ellNext(next) : NULL)
103 node=ellGet(&freebufs);
109 buffer *buf=
CONTAINER(node, buffer, node);
111 if (blen) *blen=
bsize();
124 buffer *buf=(buffer*)((
char*)(raw) - offsetof(buffer, data));
127 throw std::out_of_range(
"User admitted overflowing Rx buffer");
134 ellAdd(&freebufs, &buf->node);
137 errlogPrintf(
"buffer ignored\n");
144 ellAdd(&usedbufs, &buf->node);
147 callbackRequest(&received_cb);
151 bufRxManager::received(CALLBACK* cb)
154 callbackGetUser(vptr,cb);
157 SCOPED_LOCK2(
self.guard, G);
160 ELLNODE *node=ellGet(&
self.usedbufs);
164 buffer *buf=
CONTAINER(node, buffer, node);
168 for(ELLNODE *cur=ellFirst(&
self.dispatch); cur; cur=ellNext(cur)) {
169 listener *action=
CONTAINER(cur, listener, node);
171 errlogPrintf(
"buffer listener %p\n", action);
173 (action->fn)(action->fnarg, 0, buf->used, buf->data);
178 ellAdd(&
self.freebufs, &buf->node);
197 for(ELLNODE *node=ellFirst(&dispatch); node; node=ellNext(node))
201 if (l->fn==fn && l->fnarg==arg) {
210 ellAdd(&dispatch, &l->node);
220 for(ELLNODE *node=ellFirst(&dispatch); node; node=ellNext(node))
223 if (l->fn==fn && l->fnarg==arg) {
224 ellDelete(&dispatch, node);
virtual void dataRxAddReceive(dataBufComplete fptr, void *arg=0) OVERRIDE FINAL
Register to receive data buffers.
#define CONTAINER(ptr, structure, member)
void receive(epicsUInt8 *, unsigned int)
virtual void dataRxError(dataBufComplete, void *) OVERRIDE FINAL
Notification if Rx queue overflows.
virtual void dataRxDeleteReceive(dataBufComplete fptr, void *arg=0) OVERRIDE FINAL
Unregister.
void(* dataBufComplete)(void *arg, epicsStatus ok, epicsUInt32 len, const epicsUInt8 *buf)
bufRxManager(const std::string &, unsigned int qdepth, unsigned int bsize=0)
epicsUInt8 * getFree(unsigned int *)
#define CBINIT(ptr, prio, fn, valptr)