source: XIOS/trunk/src/filter/output_pin.cpp @ 1113

Last change on this file since 1113 was 1006, checked in by rlacroix, 7 years ago

The workflow is now triggered when using xios_recv_field for fields in read mode received from the servers.

Previously the workflow was triggered upon receiving the data which could cause deadlocks since there are no garanties that clients are receiving data at the same time.

File size: 2.3 KB
Line 
1#include "output_pin.hpp"
2#include "exception.hpp"
3
4namespace xios
5{
6  COutputPin::COutputPin(CGarbageCollector& gc, bool manualTrigger /*= false*/)
7    : gc(gc)
8    , manualTrigger(manualTrigger)
9  { /* Nothing to do */ }
10
11  void COutputPin::connectOutput(boost::shared_ptr<CInputPin> inputPin, size_t inputSlot)
12  {
13    if (!inputPin)
14      ERROR("void COutputPin::connectOutput(CInputPin* inputPin, size_t inputSlot)",
15            "The input pin cannot be null.");
16
17    outputs.push_back(std::make_pair(inputPin, inputSlot));
18
19    if (canBeTriggered())
20      inputPin->setInputTrigger(inputSlot, this);
21  }
22
23  void COutputPin::onOutputReady(CDataPacketPtr packet)
24  {
25    if (!packet)
26      ERROR("void COutputPin::onOutputReady(CDataPacketPtr packet)",
27            "The packet cannot be null.");
28
29    if (manualTrigger) // Don't use canBeTriggered here, this function is virtual and can be overriden
30    {
31      outputPackets[packet->timestamp] = packet;
32      gc.registerObject(this, packet->timestamp);
33    }
34    else
35      deliverOuput(packet);
36  }
37
38  void COutputPin::deliverOuput(CDataPacketPtr packet)
39  {
40    if (!packet)
41      ERROR("void COutputPin::deliverOuput(CDataPacketPtr packet)",
42            "The packet cannot be null.");
43
44    std::vector<std::pair<boost::shared_ptr<CInputPin>, size_t> >::iterator it, itEnd;
45    for (it = outputs.begin(), itEnd = outputs.end(); it != itEnd; ++it)
46      it->first->setInput(it->second, packet);
47  }
48
49  void COutputPin::trigger(Time timestamp)
50  {
51    if (manualTrigger) // Don't use canBeTriggered here, this function is virtual and can be overriden
52    {
53      std::map<Time, CDataPacketPtr>::iterator it = outputPackets.find(timestamp);
54      if (it != outputPackets.end())
55      {
56        gc.unregisterObject(this, timestamp);
57        deliverOuput(it->second);
58        outputPackets.erase(it);
59      }
60    }
61  }
62
63  bool COutputPin::canBeTriggered() const
64  {
65    return manualTrigger;
66  }
67
68  void COutputPin::setOutputTriggers()
69  {
70    std::vector<std::pair<boost::shared_ptr<CInputPin>, size_t> >::iterator it, itEnd;
71    for (it = outputs.begin(), itEnd = outputs.end(); it != itEnd; ++it)
72      it->first->setInputTrigger(it->second, this);
73  }
74
75  void COutputPin::invalidate(Time timestamp)
76  {
77    outputPackets.erase(outputPackets.begin(), outputPackets.lower_bound(timestamp));
78  }
79} // namespace xios
Note: See TracBrowser for help on using the repository browser.