25 Worker(MakePair(name.empty() ? cmd.GetStr(
"Name",
"module") : name)),
31 fSysTimerIndex((unsigned)-1),
43 DOUT2(
"Create module %s with pool:%s numinp:%d numout:%d",
GetName(), poolname.c_str(), numinp, numout);
56 DOUT3(
"++++++++++ dabc::Module::Module() %s done",
GetName());
61 DOUT3(
"dabc::Module::~Module() %s", GetName());
63 if (fRunState)
EOUT(
"Module %s destroyed in running state", GetName());
68 while (NumInputs() < numinp)
69 CreateInput(
format(
"Input%u", NumInputs()));
71 while (NumOutputs() < numout)
72 CreateOutput(
format(
"Output%u", NumOutputs()));
74 if (!poolname.empty() && (NumPools()==0) && ((NumInputs() + NumOutputs())>0))
75 CreatePoolHandle(poolname);
81 DOUT5(
"Module %s on thread assigned", GetName());
83 if (!fPublishPars.empty())
84 PublishPars(fPublishPars);
86 for (
unsigned n=0;n<fItems.size();n++) {
95 if (indx >= fTimers.size())
return "";
96 if (fullname)
return fTimers[indx]->ItemName();
97 return fTimers[indx]->GetName();
103 for (
unsigned n=0;n<fTimers.size();n++)
104 if (fTimers[n]->IsName(name.c_str()))
return n;
105 return (
unsigned) -1;
111 unsigned indx = FindTimer(name);
112 if (IsValidTimer(indx))
return indx;
114 bool systimer = !IsValidTimer(fSysTimerIndex) && (name.find(
"Sys")==0);
118 AddModuleItem(timer);
122 if (systimer) fSysTimerIndex = timer->
ItemSubId();
124 fTimers.push_back(timer);
133 if (kind ==
"info") {
134 std::string itemname = par.
ItemName();
136 if (fInfoParName.empty())
137 fInfoParName = itemname;
146 fInfoParName = parname;
160 for (
unsigned n=0;n<fOutputs.size();n++)
161 if (fOutputs[n]->IsName(name))
return n;
162 return (
unsigned) -1;
168 for (
unsigned n=0;n<fInputs.size();n++)
169 if (fInputs[n]->IsName(name))
return n;
170 return (
unsigned) -1;
176 for (
unsigned n=0;n<fPools.size();n++)
177 if (fPools[n]->IsName(name))
return n;
178 return (
unsigned) -1;
183 if (indx>=fOutputs.size())
return "";
184 if (fullname)
return fOutputs[indx]->ItemName();
185 return fOutputs[indx]->GetName();
190 if (indx>=fInputs.size())
return "";
191 if (fullname)
return fInputs[indx]->ItemName();
192 return fInputs[indx]->GetName();
197 if (indx>=fPools.size())
return "";
198 if (fullname)
return fPools[indx]->ItemName();
199 return fPools[indx]->GetName();
205 unsigned indx = FindUserItem(name);
206 if (IsValidUserItem(indx))
return indx;
214 fUsers.push_back(item);
222 for (
unsigned n=0;n<fUsers.size();n++)
223 if (fUsers[n]->IsName(name))
return n;
224 return (
unsigned) -1;
229 if (indx>=fUsers.size())
return "";
230 if (fullname)
return fUsers[indx]->ItemName();
231 return fUsers[indx]->GetName();
236 while (IsValidUserItem(indx) && cnt--)
237 FireEvent(
evntUser, fUsers[indx]->ItemId());
242 DOUT3(
"Start module %s thrd %s", GetName(), ThreadName().c_str());
244 if (thread().IsItself())
return DoStart();
246 return Execute(
"StartModule") ==
cmd_true;
251 DOUT3(
"Stop module %s thrd %s done", GetName(), ThreadName().c_str());
253 if (thread().IsItself())
return DoStop();
255 return Execute(
"StopModule") ==
cmd_true;
271 PortRef port = FindPort(portname);
273 if (port.
null())
return false;
286 SetWorkerPriority(pri);
288 for (
unsigned n=0;n<fItems.size();n++)
289 if (fItems[n]) fItems[n]->SetItemPriority(pri);
294 for (
unsigned n=0;n<fItems.size();n++) {
295 Port* port =
dynamic_cast<Port*
> (fItems[n]);
303 PortRef port = FindPort(portname);
305 if (port.
null())
return false;
307 return port()->SubmitCommandToTransport(cmd);
319 DOUT3(
"Module:%s PreviewCommand %s", GetName(), cmd.
GetName());
321 if (cmd.
HasField(
"_for_the_port_")) {
323 std::string portname = cmd.
GetStr(
"_for_the_port_");
325 if (SubmitCommandToTransport(portname, cmd)) cmd_res =
cmd_postponed;
328 if (cmd.
IsName(
"SetQueue")) {
332 EOUT(
"Wrong port id when assigning queue");
340 cmd_res = cmd_bool(DoStart());
343 cmd_res = cmd_bool(DoStop());
345 if (cmd.
IsName(
"SetPriority")) {
347 fThread()->SetPriority(cmd.
GetInt(
"Priority",0));
352 if (cmd.
IsName(
"CheckConnected")) {
354 for (
unsigned n=0;n<NumInputs();n++)
355 if (!Input(n)->IsConnected()) cmd_res =
cmd_false;
356 for (
unsigned n=0;n<NumOutputs();n++)
357 if (!Output(n)->IsConnected()) cmd_res =
cmd_false;
359 if (cmd.
IsName(
"IsInputConnect")) {
360 unsigned ninp = cmd.
GetUInt(
"Number");
361 cmd_res = cmd_bool((ninp<NumInputs()) && Input(ninp)->IsConnected());
363 if (cmd.
IsName(
"IsOutputConnect")) {
364 unsigned nout = cmd.
GetUInt(
"Number");
365 cmd_res = cmd_bool((nout<NumOutputs()) && Output(nout)->IsConnected());
367 if (cmd.
IsName(
"DisconnectPort")) {
368 cmd_res = cmd_bool(DisconnectPort(cmd.
GetStr(
"Port"), cmd.
GetBool(
"WithErr")));
370 if (cmd.
IsName(
"IsPortConnected")) {
373 cmd_res = cmd_bool(port()->IsConnected());
377 if (cmd.
IsName(
"GetSignalingKind")) {
381 cmd.
SetInt(
"Kind", port()->SignalingKind());
386 if (cmd.
IsName(
"GetPoolHandle")) {
387 unsigned cnt = cmd.
GetUInt(
"Number");
392 for (
unsigned indx=0;indx<fPools.size();indx++) {
396 if (cnt>0) { cnt--;
continue; }
403 if (cmd.
IsName(
"GetNumInputs")) {
404 cmd.
SetUInt(
"Number", NumInputs());
407 if (cmd.
IsName(
"GetNumOutputs")) {
408 cmd.
SetUInt(
"Number", NumOutputs());
411 if (cmd.
IsName(
"GetInputName")) {
412 unsigned id = cmd.
GetUInt(
"Id");
413 bool asitem = cmd.
GetBool(
"AsItem");
414 if (
id < NumInputs()) {
415 cmd.
SetStr(
"Name", asitem ? Input(
id)->ItemName() : std::string(Input(
id)->GetName()));
421 if (cmd.
IsName(
"GetOutputName")) {
422 unsigned id = cmd.
GetUInt(
"Id");
423 bool asitem = cmd.
GetBool(
"AsItem");
424 if (
id < NumOutputs()) {
425 cmd.
SetStr(
"Name", asitem ? Output(
id)->ItemName() : std::string(Output(
id)->GetName()));
431 if (cmd.
IsName(
"MakeConnReq")) {
443 if (thrdname.empty())
449 default: thrdname = ThreadName();
break;
461 cmd.
SetRef(
"ConnReq", req);
468 if (cmd.
IsName(dabc::CmdGetBinary::CmdName()) && (cmd.
GetStr(
"Kind")==
"module.json")) {
474 info.
SetField(
"NumInputs", NumInputs());
475 info.
SetField(
"NumOutputs", NumOutputs());
476 info.
SetField(
"NumPools", NumPools());
478 std::vector<int64_t> outq, inpq, cansend, canrecv, cantake;
479 for (
unsigned indx=0;indx<NumOutputs();++indx) {
480 outq.push_back(OutputQueueCapacity(indx));
481 cansend.push_back(fOutputs[indx]->NumCanSend());
483 for (
unsigned indx=0;indx<NumInputs();++indx) {
484 inpq.push_back(InputQueueCapacity(indx));
485 canrecv.push_back(fInputs[indx]->NumCanRecv());
487 for (
unsigned indx=0;indx<NumPools();++indx) {
488 cantake.push_back(fPools[indx]->CanTakeBuffer() ? 0 : 1);
491 info.
SetField(
"InputQueueCapacity", inpq);
492 info.
SetField(
"OutputQueueCapacity", outq);
493 info.
SetField(
"NumCanSend", cansend);
494 info.
SetField(
"NumCanRecv", canrecv);
495 info.
SetField(
"NumCanTake", cantake);
501 if (cmd.
IsName(dabc::CmdGetBinary::CmdName()) && (cmd.
GetStr(
"Kind")==
"transport.json") && !FindPort(cmd.
GetStr(
"subitem")).
null()) {
502 std::string portname = cmd.
GetStr(
"subitem");
504 if (SubmitCommandToTransport(portname, cmd)) cmd_res =
cmd_postponed;
510 DOUT3(
"Module:%s PreviewCommand %s res=%d", GetName(), cmd.
GetName(), cmd_res);
518 DOUT4(
"Module::Find %p name = %s parent %p",
this, GetName(),
GetParent());
538 if (IsRunning()) DoStop();
542 DOUT3(
"Module cleanup %s numchilds %u", GetName(), NumChilds());
544 for (
unsigned n=0;n<fItems.size();n++)
545 if (fItems[n]) fItems[n]->DoCleanup();
556 if (fSysTimerIndex < fTimers.size())
557 return fTimers[fSysTimerIndex]->ProcessTimeout(last_diff);
565 if (IsRunning())
return true;
567 DOUT3(
"dabc::Module::DoStart() %s", GetName());
573 for (
unsigned n=0;n<fItems.size();n++)
574 if (fItems[n]) fItems[n]->DoStart();
577 if ((fSysTimerIndex < fTimers.size()) && (fTimers[fSysTimerIndex]->fPeriod>0))
578 ActivateTimeout(fTimers[fSysTimerIndex]->fPeriod);
581 DOUT3(
"dabc::Module::DoStart() %s done", GetName());
588 DOUT3(
"dabc::Module::DoStop() %s", GetName());
590 if (!IsRunning())
return true;
593 if (fSysTimerIndex < fTimers.size()) ActivateTimeout(-1);
595 for (
unsigned n=0;n<fItems.size();n++)
596 if (fItems[n]) fItems[n]->DoStop();
602 DOUT3(
"dabc::Module::DoStop() %s done", GetName());
609 unsigned index = FindPool(poolname);
610 if (IsValidPool(index))
return index;
615 EOUT(
"Pool %s not exists - cannot connect to module %s", poolname.c_str(), GetName());
616 return (
unsigned) -1;
621 AddModuleItem(handle);
624 fPools.push_back(handle);
634 unsigned id = fItems.size();
636 fItems.push_back(item);
641 EOUT(
"Item id is too big, event propagation will not work");
653 unsigned id = item->
ItemId();
655 for (
unsigned n=0;n<fInputs.size();n++) {
656 if (fInputs[n] == item) {
657 fInputs.erase(fInputs.begin()+n);
659 fInputs[n]->SetItemSubId(n);
663 for (
unsigned n=0;n<fOutputs.size();n++) {
664 if (fOutputs[n] == item) {
665 fOutputs.erase(fOutputs.begin()+n);
667 fOutputs[n]->SetItemSubId(n);
671 for (
unsigned n=0;n<fPools.size();n++) {
672 if (fPools[n] == item) {
673 fPools.erase(fPools.begin()+n);
675 fPools[n]->SetItemSubId(n);
679 for (
unsigned n=0;n<fTimers.size();n++) {
680 if (fTimers[n] == item) {
681 fTimers.erase(fTimers.begin()+n);
683 fTimers[n]->SetItemSubId(n);
687 for (
unsigned n=0;n<fUsers.size();n++) {
688 if (fUsers[n] == item) {
689 fUsers.erase(fUsers.begin()+n);
691 fUsers[n]->SetItemSubId(n);
701 return FindChildRef(name.c_str());
706 unsigned indx = FindInput(name);
707 if (IsValidInput(indx))
return indx;
709 if (queue == 0)
return (
unsigned) -1;
716 fInputs.push_back(port);
720 CreatePar(port->
fRateName).SetRatemeter(
false, 3.).SetUnits(
"MB");
729 unsigned indx = FindOutput(name);
730 if (IsValidOutput(indx))
return indx;
732 if (queue == 0)
return (
unsigned) -1;
739 fOutputs.push_back(port);
743 CreatePar(port->
fRateName).SetRatemeter(
false, 3.).SetUnits(
"MB");
752 unsigned inpindx = FindInput(inpname);
753 unsigned outindx = FindOutput(outname);
755 if (IsValidInput(inpindx) && IsValidOutput(outindx)) {
756 fInputs[inpindx]->SetBindName(outname);
757 fOutputs[outindx]->SetBindName(inpname);
768 while (IsValidInput(indx) && cnt--)
769 FireEvent(
evntInput, fInputs[indx]->ItemId());
774 while (IsValidPool(indx) && cnt--)
775 FireEvent(
evntInput, fPools[indx]->ItemId());
781 while (IsValidOutput(indx) && cnt--)
782 FireEvent(
evntOutput, fOutputs[indx]->ItemId());
787 return FindPort(name).IsConnected();
795 port()->SetSignaling(signal);
806 port()->SetRateMeter(ref);
816 port()->SetMaxLoopLength(cnt);
865 dostop = fAutoStop && IsRunning();
886 AddModuleItem(timer);
894 DOUT1(
"Module %s will try to reconnect port %s", GetName(), port->
ItemName().c_str());
900 if (fAutoStop && IsRunning() && !dostop) {
901 for (
unsigned n=0;n<NumOutputs();n++)
902 if (Output(n)->IsConnected() || Output(n)->IsDoingReconnect())
return;
904 for (
unsigned n=0;n<NumInputs();n++)
905 if (Input(n)->IsConnected() || Input(n)->IsDoingReconnect())
return;
911 DOUT2(
"Module %s automatically stopped while all connections are now disconnected", GetName());
934 for(
unsigned n=0;n<NumOutputs();n++) {
936 if (exclude_disconnected && !out->
IsConnected())
continue;
937 if (!out->
CanSend())
return false;
944 if (buf.
null())
return;
946 unsigned last_can_send = NumOutputs();
947 for(
unsigned n=0;n<NumOutputs();n++) {
953 for(
unsigned n=0;n<NumOutputs();n++) {
957 if (n==last_can_send) {
958 Output(n)->Send(buf);
959 if (!buf.
null()) {
EOUT(
"buffer not null after sending to output %u", n); exit(333); }
962 Output(n)->Send(dupl);
963 if (!dupl.
null()) {
EOUT(
"buffer not null after sending to output %u", n); exit(333); }
967 if ((last_can_send != NumOutputs()) && !buf.
null()) {
981 if (GetObject()==0)
return false;
984 cmd.
SetInt(
"Number", ninp);
991 if (GetObject()==0)
return false;
994 cmd.
SetInt(
"Number", ninp);
1001 if (GetObject()==0)
return false;
1009 if (Execute(cmd) !=
cmd_true)
return false;
1014 if (portinp.
null())
break;
1016 if (poolref.
null()) {
1017 EOUT(
"Something went wrong with connection to the pools");
1021 DOUT3(
"@@@@@ Create requester for item %s", portinp.
ItemName().c_str());
1033 return FindChild(name.c_str());
1039 cmd.
SetStr(
"Port", name);
1060 cmd.
SetBool(
"AsItem", itemname);
1063 return std::string();
1070 cmd.
SetBool(
"AsItem", itemname);
1073 return std::string();
Reference on memory from memory pool.
Buffer Duplicate() const
Duplicates instance of Buffer with new segments list independent from source.
BufferSize_t GetTotalSize() const
Return total size of all buffer segments.
static const char * CmdName()
static const char * CmdName()
Represents command with its arguments.
unsigned GetUInt(const std::string &name, unsigned dflt=0) const
bool SetStr(const std::string &name, const char *value)
bool SetBool(const std::string &name, bool v)
bool SetInt(const std::string &name, int v)
std::string GetStr(const std::string &name, const std::string &dflt="") const
bool SetUInt(const std::string &name, unsigned v)
bool GetBool(const std::string &name, bool dflt=false) const
Reference GetRef(const std::string &name)
Returns reference from the command, can be called only once.
int GetInt(const std::string &name, int dflt=0) const
bool SetRef(const std::string &name, Reference ref)
Set reference to the command.
Interface class between xml configuration and dabc objects.
bool FindItem(const char *name)
bool CheckAttr(const char *name, const char *value)
Check if item, found by FindItem routine, has attribute with specified value.
Special timer to reestablish port connections in the module.
bool fErrorFlag
indicate why reconnection was started
void Activate(double period)
@ sDisconnected
connection is down by user, will not be reconnected
@ sConnected
connection is up and working
@ sBroken
connection is broken and should be reactivated by connection manager
void SetServerSide(bool isserver=true)
void SetUseAckn(bool on=true)
bool IsOptional() const
indicate if connection is optional and therefore may be ignored during failure or long timeout
void ChangeState(ConnectionObject::EState state, bool force)
void SetConnDevice(const std::string &dev)
void SetRemoteUrl(const std::string &url)
void SetConnThread(const std::string &name)
void SetConnTimeout(double tm)
void SetInitState()
Change state of the connection to init that other parameters can be changed.
void SetOptional(bool on=true)
static int ConnectPorts(Reference port1ref, Reference port2ref, Command cmd=nullptr)
Lock guard for posix mutex.
Reference FindPool(const std::string &name)
Reference on dabc::MemoryPool class
Reference CreateNewRequester()
Buffer TakeBuffer(BufferSize_t size=0)
Returns Buffer object with exclusive access rights.
Base class for module items like ports, timers, pool handles.
virtual bool ItemNeedThread() const
void SetItemSubId(unsigned id)
void SetItemId(unsigned id)
unsigned ItemSubId() const
std::string OutputName(unsigned n=0, bool itemname=true)
Return item name of the output, can be used in connect command.
unsigned NumOutputs()
Returns number of outputs in the module.
bool IsInputConnected(unsigned ninp)
Returns true if specified input is connected.
bool IsPortConnected(const std::string &name)
Returns true if port with specified name is connected - thread safe.
unsigned NumInputs()
Returns number of inputs in the module.
PortRef FindPort(const std::string &name)
Return reference on the port.
bool IsOutputConnected(unsigned ninp)
Returns true if specified output is connected.
bool ConnectPoolHandles()
Method called by manager to establish connection to pools TODO: while used from devices,...
std::string InputName(unsigned n=0, bool itemname=true)
Return item name of the input, can be used in connect command.
bool SubmitCommandToTransport(const std::string &portname, Command cmd)
Submits command to transport, assigned with the port.
bool SetPortSignaling(const std::string &name, Port::EventsProducing signal)
unsigned FindOutput(const std::string &name) const
virtual void ObjectCleanup()
Inherited method, called during module destroy.
virtual bool Find(ConfigIO &cfg)
Method to locate object in xml file.
unsigned FindPool(const std::string &name) const
void RemoveModuleItem(ModuleItem *item)
void ProduceOutputEvent(unsigned indx=0, unsigned cnt=1)
virtual Parameter CreatePar(const std::string &name, const std::string &kind="")
bool IsPortConnected(const std::string &name) const
virtual void BuildFieldsMap(RecordFieldsMap *cont)
Fill fields map, which is relevant for the object Objects hierarchy produced from dabc::Manager.
std::string OutputName(unsigned indx=0, bool fullname=false) const
virtual void OnThreadAssigned()
bool CanSendToAllOutputs(bool exclude_disconnected=true) const
std::string PoolName(unsigned indx=0, bool fullname=false) const
virtual void ProcessEvent(const EventId &)
bool BindPorts(const std::string &inpname, const std::string &outname)
Bind input and output ports that both will share same connection.
std::string InputName(unsigned indx=0, bool fullname=false) const
void ProduceUserItemEvent(unsigned indx=0, unsigned cnt=1)
unsigned FindInput(const std::string &name) const
unsigned FindUserItem(const std::string &name)
unsigned CreatePoolHandle(const std::string &poolname, unsigned queue=10)
Creates handle for memory pool, which preserves reference on memory pool and provides fast access to ...
virtual void SetModulePriority(int pri=-1)
void SetInfoParName(const std::string &name)
unsigned CreateUserItem(const std::string &name)
bool SetPortLoopLength(const std::string &name, unsigned cnt)
void AddModuleItem(ModuleItem *item)
std::string GetInfoParName() const
bool fAutoStop
module will automatically stop when all i/o ports will be disconnected
virtual int PreviewCommand(Command cmd)
This method called before command will be executed.
virtual double ProcessTimeout(double last_diff)
std::string UserItemName(unsigned indx=0, bool fullname=false) const
unsigned CreateInput(const std::string &name, unsigned queue=10)
void DisconnectAllPorts(bool witherr=false)
Method disconnects all module ports, should be called only from Module thread.
void ProduceInputEvent(unsigned indx=0, unsigned cnt=1)
unsigned CreateOutput(const std::string &name, unsigned queue=10)
std::string fPublishPars
path where module pars will be published
void ProducePoolEvent(unsigned indx=0, unsigned cnt=1)
unsigned CreateTimer(const std::string &name, double period_sec=-1., bool synchron=false)
PortRef FindPort(const std::string &name) const
bool Stop()
Stops execution of the module code.
std::string TimerName(unsigned n=0, bool fullname=false) const
bool DisconnectPort(const std::string &name, bool witherr=false)
Disconnect port from transport.
bool Start()
Starts execution of the module code.
void EnsurePorts(unsigned numinp=0, unsigned numout=0, const std::string &poolname="")
Method ensure that at least specified number of input and output ports will be created.
bool SetPortRatemeter(const std::string &name, const Parameter &ref)
void SendToAllOutputs(Buffer &buf)
unsigned FindTimer(const std::string &name)
Module(const std::string &name, Command cmd)
std::string ItemName(bool compact=true) const
Produce string, which can be used as name argument in dabc::mgr.FindItem(name) call.
const char * GetName() const
Returns name of the object, thread safe
bool CanSend() const
Returns true if user can send get buffer via the port.
Handle for pool connection.
Reference on the dabc::Port class
bool IsInput() const
Returns true if it is input port.
bool Disconnect(bool witherr=false)
Disconnect port
Base class for input and output ports.
void SetRateMeter(const Parameter &ref)
Set port ratemeter - must be used from module thread.
unsigned QueueCapacity() const
Method returns actual queue capacity of the port, object mutex is used.
ConnectionRequest GetConnReq(bool force=false)
Return reference on existing request object.
void Disconnect(bool witherr=false)
Parameter fRate
parameter for rate calculations
bool TryNextReconnect(bool caused_by_error, bool can_disconnect=true)
Returns true when reconnection should be attempted.
double GetReconnectPeriod() const
bool IsConnected() const
Method can only be used from thread itself.
void SetDoingReconnect(bool on=true)
std::string fRateName
name of rate parameter, which should be assigned to port
bool AsBool(bool dflt=false) const
std::string AsStr(const std::string &dflt="") const
int64_t AsInt(int64_t dflt=0) const
double AsDouble(double dflt=0.) const
RecordField & Field(const std::string &name)
Direct access to the fields.
bool HasField(const std::string &name) const
bool SetField(const std::string &name, const RecordField &v)
std::string SaveToJson(unsigned mask=0)
Store record in JSON form.
bool RemoveField(const std::string &name)
virtual void CreateRecord(const std::string &name)
Reference on the arbitrary object
void Release()
Releases reference on the object.
const char * GetName() const
Return name of referenced object, if object not assigned, returns "---".
bool IsName(const char *name) const
Returns true if object name is the same as specified one.
bool null() const
Returns true if reference contains nullptr.
std::string ItemName(bool compact=true) const
Produce string, which can be used as name argument in dabc::mgr.FindItem(name) call.
Provides timer event to the module.
std::string ThreadName() const
Returns thread name of worker assigned.
RecordField Cfg(const std::string &name, Command cmd=nullptr) const
Returns configuration record of specified name.
Active object, which is working inside dabc::Thread.
virtual int PreviewCommand(Command cmd)
This method called before command will be executed.
virtual void ProcessEvent(const EventId &)
bool AssignToThread(ThreadRef thrd, bool sync=true)
Assign worker to thread, worker becomes active immediately.
RecordField Cfg(const std::string &name, Command cmd=nullptr) const
Returns configuration field of specified name Configuration value of specified name searched in follo...
bool HasThread() const
Indicates if pointer on thread is not zero; thread-safe.
virtual void ObjectCleanup()
Central cleanup method for worker.
virtual Parameter CreatePar(const std::string &name, const std::string &kind="")
XMLNodePointer_t GetParent(XMLNodePointer_t xmlnode)
const char * xmlNumOutputs
const char * xmlTimeoutAttr
const char * xmlUseacknAttr
const char * xmlDeviceAttr
std::string format(const char *fmt,...)
const char * xmlOptionalAttr
const char * xmlThreadAttr
const char * xmlModuleNode
const char * xmlNumInputs
Event structure, exchanged between DABC threads.