OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
DataSource.cpp
Go to the documentation of this file.
1 // -*- C++ -*-
2 /***************************************************************************
3  *
4  * The IPPL Framework
5  *
6  * This program was prepared by PSI.
7  * All rights in the program are reserved by PSI.
8  * Neither PSI nor the author(s)
9  * makes any warranty, express or implied, or assumes any liability or
10  * responsibility for the use of this software
11  *
12  * Visit www.amas.web.psi for more details
13  *
14  ***************************************************************************/
15 
16 // -*- C++ -*-
17 /***************************************************************************
18  *
19  * The IPPL Framework
20  *
21  *
22  * Visit http://people.web.psi.ch/adelmann/ for more details
23  *
24  ***************************************************************************/
25 
26 // include files
27 #include "DataSource/DataSource.h"
29 #include "DataSource/DataConnect.h"
31 #include "Utility/IpplInfo.h"
32 
33 
35 // constructor
37  // nothing to do
38 }
39 
40 
42 // destructor
44  //Inform dbgmsg("DataSource::~DataSource", INFORM_ALL_NODES);
45  //dbgmsg << "Calling disconnect() from DataSource destructor." << endl;
46 
47  // disconnect from all existing connections, if we still have any
48  disconnect();
49 }
50 
51 
53 // find the first DataSourceObject which is connected to the given DataConnect,
54 // and return it; otherwise, return 0
56  container_t::const_iterator a = ConnectionList.begin();
57  for ( ; a != ConnectionList.end(); ++a)
58  if (dc == (*a)->getConnection())
59  return (*a);
60 
61  // if we're here, we're not connected
62  return 0;
63 }
64 
65 
67 // Are we connected to the given DataConnect? If not specified, just return
68 // whether we're connected to anything.
69 bool DataSource::connected(DataConnect *dataconn) const {
70  if (dataconn == 0)
71  return ( ! ConnectionList.empty() );
72  else
73  return (findDataSourceObject(dataconn) != 0);
74 }
75 
76 
78 // Register an object as something that can be a source of data. Return
79 // success. Arguments = name of item, connection to use, and type of
80 // connection (INPUT, OUTPUT, or BOTH). If the connection
81 // has not been created yet (e.g., it is NULL), create a new default
82 // connection (or use the existing default one). Return the connection.
83 DataConnect *DataSource::connect(const char *nm,DataConnect *dataconn,int tm) {
84  //Inform dbgmsg("DataSource::connect", INFORM_ALL_NODES);
85  //dbgmsg << "Connecting '" << nm << "'" << endl;
86  //if (dataconn != 0)
87  // dbgmsg << " to '" << dataconn->name() << "'";
88  //dbgmsg << endl;
89 
90  // figure out which connection to use ... if none given, we must get a
91  // new one
92  if (dataconn == 0) {
93  //dbgmsg << "Creating new connection ..." << endl;
94  dataconn = DataConnectCreator::create();
95  }
96 
97  // make sure we're not already connected to this object
98  if (connected(dataconn)) {
99  ERRORMSG("Cannot connect '" << nm << "' to the same agency twice." <<endl);
100  ERRORMSG("dataconn = " << (void *)dataconn << endl);
101  return 0;
102  }
103 
104  // set the transfer method properly, if we are requested to use the default
105  if (tm == DataSource::DEFAULT)
106  tm = dataconn->getDefaultTransferMethod();
107 
108  // OK, connect away ... create new DataSourceObject, which establishes
109  // the connection. If we fail to connect, delete the created Obj
110  DataSourceObject *dso = createDataSourceObject(nm, dataconn, tm);
111  if (dso != 0 && !connect(dso)) {
112  delete dso;
113  return 0;
114  }
115 
116  // if we're here, everything was ok ... return the connection we used
117  return dataconn;
118 }
119 
120 
122 // Register the given DataSourceObject directly. This is simpler than
123 // the above version of connect, since the DataSourceObject has already
124 // been created. It can be used to register most any type of connection,
125 // even one using DataConnect objects that are not part of IPPL itself.
126 // Return success.
128 
129  // make sure the connection is OK
130  if (dso != 0 && dso->connected() && dso->getSource() == this) {
131  ConnectionList.push_back(dso);
132  dso->getConnection()->checkin(this);
133  return true;
134  }
135 
136  // if we're here, there was a problem
137  return false;
138 }
139 
140 
142 // Disconnect an object from the given receiver. Return success.
144  //Inform dbgmsg("DataSource::disconnect", INFORM_ALL_NODES);
145  //dbgmsg << "Disconnecting source from connection(s) '";
146  //dbgmsg << (dataconn != 0 ? dataconn->name() : "(all)")<< "' ..." << endl;
147 
149  for ( ; a != ConnectionList.end(); ++a) {
150  DataConnect *dc = (*a)->getConnection();
151  if (dataconn == 0 || dataconn == dc) {
152  //dbgmsg << "Calling checkout from the DataSource ..." << endl;
153  dc->checkout(this, false);
154  //dbgmsg << "Deleting DSO '" << (*a)->name() << "' ..." << endl;
155  delete (*a);
156  if (dataconn == dc) {
157  ConnectionList.erase(a);
158  return true;
159  }
160  }
161  }
162 
163  // if we've removed all, we can erase all
164  if (dataconn == 0 && ConnectionList.size() > 0) {
165  //dbgmsg<<"Erasing all " << ConnectionList.size() << " DSO's ..." << endl;
166  ConnectionList.erase(ConnectionList.begin(), ConnectionList.end());
167  }
168 
169  return (dataconn == 0);
170 }
171 
172 
174 // Update the object, that is, make sure the receiver of the data has a
175 // current and consistent snapshot of the current state. Return success.
178  for ( ; a != ConnectionList.end(); ++a) {
179  if (dataconn == 0)
180  (*a)->update();
181  else if (dataconn == (*a)->getConnection())
182  return (*a)->update();
183  }
184 
185  // if we're here, we were successful only if we tried to disconnect all
186  return (dataconn == 0);
187 }
188 
189 
191 // Indicate to the receiver that we're allowing them time to manipulate the
192 // data (e.g., for a viz program, to rotate it, change representation, etc.)
193 // This should only return when the manipulation is done. For some cases,
194 // this will be a no-op.
197  for ( ; a != ConnectionList.end(); ++a) {
198  if (dataconn == 0 || dataconn == (*a)->getConnection())
199  (*a)->interact();
200  }
201 }
202 
203 
205 // Pass on a string to the connection, most likely to give it a
206 // command to do some action. Similar to the above interact, except
207 // the request for interaction involves the given string
208 void DataSource::interact(const char *str, DataConnect *dataconn) {
210  for ( ; a != ConnectionList.end(); ++a) {
211  if (dataconn == 0 || dataconn == (*a)->getConnection())
212  (*a)->interact(str);
213  }
214 }
215 
216 
217 /***************************************************************************
218  * $RCSfile: DataSource.cpp,v $ $Author: adelmann $
219  * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:25 $
220  * IPPL_VERSION_ID: $Id: DataSource.cpp,v 1.1.1.1 2003/01/23 07:40:25 adelmann Exp $
221  ***************************************************************************/
DataConnect * getConnection()
#define ERRORMSG(msg)
Definition: IpplInfo.h:399
int getDefaultTransferMethod() const
Definition: DataConnect.h:58
DataConnect * connect(const char *, DataConnect *=0, int=DataSource::DEFAULT)
Definition: DataSource.cpp:83
bool checkin(DataSource *)
bool connected() const
virtual ~DataSource()
Definition: DataSource.cpp:43
static DataConnect * create()
container_t ConnectionList
Definition: DataSource.h:138
bool checkout(DataSource *, bool=true)
bool updateConnection(DataConnect *=0)
Definition: DataSource.cpp:176
void interact(DataConnect *=0)
Definition: DataSource.cpp:195
DataSourceObject * findDataSourceObject(DataConnect *) const
Definition: DataSource.cpp:55
bool connected(DataConnect *=0) const
Definition: DataSource.cpp:69
std::string::iterator iterator
Definition: MSLang.h:16
DataSource * getSource()
virtual DataSourceObject * createDataSourceObject(const char *, DataConnect *, int)=0
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
bool disconnect(DataConnect *=0)
Definition: DataSource.cpp:143