source: XIOS/trunk/src/filter/store_filter.cpp @ 1025

Last change on this file since 1025 was 1006, checked in by rlacroix, 8 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: 3.2 KB
Line 
1#include "store_filter.hpp"
2#include "context.hpp"
3#include "grid.hpp"
4#include "timer.hpp"
5
6namespace xios
7{
8  CStoreFilter::CStoreFilter(CGarbageCollector& gc, CContext* context, CGrid* grid)
9    : CInputPin(gc, 1)
10    , gc(gc)
11    , context(context)
12    , grid(grid)
13  {
14    if (!context)
15      ERROR("CStoreFilter::CStoreFilter(CContext* context, CGrid* grid)",
16            "Impossible to construct a store filter without providing a context.");
17    if (!grid)
18      ERROR("CStoreFilter::CStoreFilter(CContext* context, CGrid* grid)",
19            "Impossible to construct a store filter without providing a grid.");
20  }
21
22  CConstDataPacketPtr CStoreFilter::getPacket(Time timestamp)
23  {
24    CTimer timer("CStoreFilter::getPacket");
25    CConstDataPacketPtr packet;
26    const double timeout = 10 ; // 10 seconds timeout
27
28    do
29    {
30      if (canBeTriggered())
31        trigger(timestamp);
32
33      timer.resume();
34
35      std::map<Time, CDataPacketPtr>::const_iterator it = packets.find(timestamp);
36      if (it != packets.end())
37        packet = it->second;
38      else // if the packet is not available yet, check if it can be received
39        context->checkBuffersAndListen();
40
41      timer.suspend();
42    } while (!packet && timer.getCumulatedTime() < timeout);
43
44    if (!packet)
45    {
46      std::map<Time, CDataPacketPtr>::const_iterator it ;
47      info(0)<<"Impossible to get the packet with timestamp = " << timestamp<<std::endl<<"Available timestamp are : "<<std::endl ;
48      for(it=packets.begin();it!=packets.end();++it) info(0)<<it->first<<"  ";
49      info(0)<<std::endl ;
50      ERROR("CConstDataPacketPtr CStoreFilter::getPacket(Time timestamp) const",
51            << "Impossible to get the packet with timestamp = " << timestamp);
52    }
53    return packet;
54  }
55
56  template <int N>
57  CDataPacket::StatusCode CStoreFilter::getData(Time timestamp, CArray<double, N>& data)
58  {
59    CConstDataPacketPtr packet = getPacket(timestamp);
60
61    if (packet->status == CDataPacket::NO_ERROR)
62      grid->outputField(packet->data, data);
63
64    return packet->status;
65  }
66
67  template CDataPacket::StatusCode CStoreFilter::getData<1>(Time timestamp, CArray<double, 1>& data);
68  template CDataPacket::StatusCode CStoreFilter::getData<2>(Time timestamp, CArray<double, 2>& data);
69  template CDataPacket::StatusCode CStoreFilter::getData<3>(Time timestamp, CArray<double, 3>& data);
70  template CDataPacket::StatusCode CStoreFilter::getData<4>(Time timestamp, CArray<double, 4>& data);
71  template CDataPacket::StatusCode CStoreFilter::getData<5>(Time timestamp, CArray<double, 5>& data);
72  template CDataPacket::StatusCode CStoreFilter::getData<6>(Time timestamp, CArray<double, 6>& data);
73  template CDataPacket::StatusCode CStoreFilter::getData<7>(Time timestamp, CArray<double, 7>& data);
74
75  void CStoreFilter::onInputReady(std::vector<CDataPacketPtr> data)
76  {
77    packets.insert(std::make_pair(data[0]->timestamp, data[0]));
78    // The packet is always destroyed by the garbage collector
79    // so we register but never unregister
80    gc.registerObject(this, data[0]->timestamp);
81  }
82
83  void CStoreFilter::invalidate(Time timestamp)
84  {
85    CInputPin::invalidate(timestamp);
86    packets.erase(packets.begin(), packets.lower_bound(timestamp));
87  }
88} // namespace xios
Note: See TracBrowser for help on using the repository browser.