YARP
Yet Another Robot Platform
AllocatorOnTriples.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2020 Istituto Italiano di Tecnologia (IIT)
3  * Copyright (C) 2006-2010 RobotCub Consortium
4  * All rights reserved.
5  *
6  * This software may be modified and distributed under the terms of the
7  * BSD-3-Clause license. See the accompanying LICENSE file for details.
8  */
9 
10 #include <cstdio>
11 #include <cstdlib>
12 
15 
16 using namespace yarp::os;
17 using namespace yarp::serversql::impl;
18 using namespace std;
19 
20 namespace {
21 YARP_SERVERSQL_LOG_COMPONENT(ALLOCATORONTRIPLES, "yarp.serversql.impl.AllocatorOnTriples")
22 } // namespace
23 
24 Contact AllocatorOnTriples::completePortName(const Contact& c) {
25  string name;
26  Triple t;
27  t.setNsNameValue("alloc","tmpid","*");
28  TripleContext context;
29  context.setRid(db->find(t, nullptr));
30  if (context.rid>=0) {
31  t.setNsNameValue("alloc","*","free");
32  list<Triple> match = db->query(t,&context);
33  if (match.size()>0) {
34  name = match.begin()->name;
35  }
36  }
37 
38  if (name=="") {
39  if (tmpid==-1) {
40  t.setNsNameValue("alloc","tmpid","*");
41  list<Triple> lst = db->query(t, nullptr);
42  if (lst.size()>0) {
43  tmpid = atoi(lst.begin()->value.c_str());
44  }
45  if (tmpid==-1) {
46  tmpid = 0;
47  }
48  }
49  tmpid++;
50  char buf[256];
51  std::snprintf(buf, 256, "%d", tmpid);
52  t.setNsNameValue("alloc","tmpid",buf);
53  db->update(t, nullptr);
54  t.setNsNameValue("alloc","tmpid","*");
55  context.setRid(db->find(t, nullptr));
56  std::snprintf(buf, 256, "/tmp/port/%u", tmpid);
57  name = buf;
58  }
59 
60  t.setNsNameValue("alloc",name.c_str(),"in_use");
61  db->update(t,&context);
62 
63  return Contact(name,
64  c.getCarrier(),
65  c.getHost(),
66  c.getPort());
67 }
68 
69 
70 Contact AllocatorOnTriples::completeSocket(const Contact& c) {
71  Contact tmp = completeHost(c);
72  return completePortNumber(tmp);
73 }
74 
75 Contact AllocatorOnTriples::completePortNumber(const Contact& c) {
76  if (c.getPort()!=-1 && c.getPort()!=0) {
77  return c;
78  }
79 
80  // unlike standard yarp name server, port number allocation
81  // is global across the network, rather than per machine.
82 
83  // we also try to keep port numbers stable for port names,
84  // when possible.
85 
86  string npref;
87  int pref = -1;
88  string nstring;
89  int number = -1;
90  Triple t;
91  t.setNsNameValue("alloc","regid","*");
92  TripleContext context;
93  context.setRid(db->find(t, nullptr));
94  if (context.rid>=0) {
95  t.setNsNameValue("prefer","*",c.getName().c_str());
96  list<Triple> match = db->query(t,&context);
97  if (match.size()>0) {
98  npref = match.begin()->name;
99  pref = atoi(npref.c_str());
100  t.setNsNameValue("alloc",npref.c_str(),"in_use");
101  match = db->query(t,&context);
102  if (match.size()==0) {
103  nstring = npref;
104  number = pref;
105  }
106  }
107  }
108 
109  if (nstring=="") {
110  if (regid==-1) {
111  Triple t;
112  t.setNsNameValue("alloc","regid","*");
113  list<Triple> lst = db->query(t, nullptr);
114  if (lst.size()>0) {
115  regid = atoi(lst.begin()->value.c_str());
116  }
117  if (regid==-1) {
118  regid = config.minPortNumber-1;
119  }
120  }
121  if (regid>=config.maxPortNumber && config.maxPortNumber!=0) {
122  if (nstring == "") {
123  t.setNsNameValue("alloc","*","free");
124  list<Triple> match = db->query(t,&context);
125  if (match.size()>0) {
126  nstring = match.begin()->name;
127  number = atoi(nstring.c_str());
128  }
129  }
130  if (nstring=="") {
131  yCError(ALLOCATORONTRIPLES, "Ran out of port numbers");
132  yCError(ALLOCATORONTRIPLES, "* Make sure ports/programs get closed properly.");
133  yCError(ALLOCATORONTRIPLES, "* If programs terminate without closing ports, run \"yarp clean\" from time to time..");
134  std::exit(1);
135  }
136  } else {
137  regid++;
138  Triple t;
139  char buf[256];
140  std::snprintf(buf, 256, "%d", regid);
141  t.setNsNameValue("alloc","regid",buf);
142  db->update(t, nullptr);
143  t.setNsNameValue("alloc","regid","*");
144  context.setRid(db->find(t, nullptr));
145  nstring = buf;
146  number = regid;
147  }
148  }
149  t.setNsNameValue("alloc",nstring.c_str(),"in_use");
150  db->update(t,&context);
151  t.setNsNameValue("prefer",nstring.c_str(),c.getName().c_str());
152  db->update(t,&context);
153 
154  Contact contact = c;
155  contact.setPort(number);
156  return contact;
157 }
158 
159 
160 Contact AllocatorOnTriples::completeHost(const yarp::os::Contact& c) {
161  // deal with allocating multicast ips
162 
163  if (c.getCarrier()!="mcast") {
164  return c;
165  }
166  if (c.getHost()!="...") {
167  return c;
168  }
169 
170  string name;
171  Triple t;
172  t.setNsNameValue("alloc","mcastCursor","*");
173  TripleContext context;
174  context.setRid(db->find(t, nullptr));
175  if (context.rid>=0) {
176  t.setNsNameValue("alloc","*","free");
177  list<Triple> match = db->query(t,&context);
178  if (match.size()>0) {
179  name = match.begin()->name;
180  }
181  }
182 
183  if (name=="") {
184  if (mcastCursor==-1) {
185  t.setNsNameValue("alloc","mcastCursor","*");
186  list<Triple> lst = db->query(t, nullptr);
187  if (lst.size()>0) {
188  mcastCursor = atoi(lst.begin()->value.c_str());
189  }
190  if (mcastCursor==-1) {
191  mcastCursor = 1;
192  }
193  }
194  mcastCursor++;
195  char buf[256];
196  std::snprintf(buf, 256, "%d", mcastCursor);
197  t.setNsNameValue("alloc","mcastCursor",buf);
198  db->update(t, nullptr);
199  t.setNsNameValue("alloc","mcastCursor","*");
200  context.setRid(db->find(t, nullptr));
201 
202  int v1 = mcastCursor%255;
203  int v2 = mcastCursor/255;
204  if (v2>=255) {
205  yCError(ALLOCATORONTRIPLES, "Ran out of mcast addresses");
206  std::exit(1);
207  }
208  std::snprintf(buf, 256, "224.1.%d.%d", v2+1, v1+1);
209  name = buf;
210  }
211 
212  t.setNsNameValue("alloc",name.c_str(),"in_use");
213  db->update(t,&context);
214 
215  Contact contact = c;
216  contact.setHost(name);
217  return contact;
218 }
219 
220 
221 bool AllocatorOnTriples::freePortResources(const yarp::os::Contact& c) {
222  string portName = c.getName();
223  int portNumber = c.getPort();
224  string hostName = c.getHost();
225 
226  // free up automatic name for port, if one was allocated
227  Triple t;
228  t.setNsNameValue("alloc","tmpid","*");
229  TripleContext context;
230  context.setRid(db->find(t, nullptr));
231  t.setNsNameValue("alloc",portName.c_str(),"in_use");
232  if (db->find(t,&context)>=0) {
233  t.setNsNameValue("alloc",portName.c_str(),"free");
234  db->update(t,&context);
235  }
236 
237  t.setNsNameValue("alloc","regid","*");
238  context.setRid(db->find(t, nullptr));
239  char buf[256];
240  std::snprintf(buf, 256, "%d", portNumber);
241  t.setNsNameValue("alloc",buf,"in_use");
242  if (db->find(t,&context)>=0) {
243  t.setNsNameValue("alloc",buf,"free");
244  db->update(t,&context);
245  }
246 
247  t.setNsNameValue("alloc","mcastCursor","*");
248  context.setRid(db->find(t, nullptr));
249  t.setNsNameValue("alloc",hostName.c_str(),"in_use");
250  if (db->find(t,&context)>=0) {
251  t.setNsNameValue("alloc",hostName.c_str(),"free");
252  db->update(t,&context);
253  }
254 
255  return true;
256 }
YARP_SERVERSQL_LOG_COMPONENT
#define YARP_SERVERSQL_LOG_COMPONENT(name, name_string)
Definition: LogComponent.h:37
t
float t
Definition: FfmpegWriter.cpp:74
yarp::serversql::impl::TripleContext
Side information for controlling access to triples.
Definition: TripleSource.h:27
yarp::serversql::impl::Triple
The basic unit of data the name server works with.
Definition: Triple.h:28
yarp::os::Contact::getName
std::string getName() const
Get the name associated with this Contact.
Definition: Contact.cpp:208
yarp::serversql::impl::TripleContext::rid
int rid
Definition: TripleSource.h:29
LogComponent.h
yarp::serversql::impl::TripleContext::setRid
void setRid(int rid)
Definition: TripleSource.h:33
yarp::os::Contact::getPort
int getPort() const
Get the port number associated with this Contact for socket communication.
Definition: Contact.cpp:242
yarp::os::Contact::getCarrier
std::string getCarrier() const
Get the carrier associated with this Contact for socket communication.
Definition: Contact.cpp:253
yarp::os::Contact::setPort
void setPort(int port)
Set the port number to be the input parameter.
Definition: Contact.cpp:247
yCError
#define yCError(component,...)
Definition: LogComponent.h:157
yarp::os
An interface to the operating system, including Port based communication.
Definition: AbstractCarrier.h:17
yarp::os::Contact::getHost
std::string getHost() const
Get the host name associated with this Contact for socket communication.
Definition: Contact.cpp:231
yarp::os::Contact
Represents how to reach a part of a YARP network.
Definition: Contact.h:39
AllocatorOnTriples.h
yarp::os::Contact::setHost
void setHost(const std::string &hostname)
Set the host name to be the input parameter.
Definition: Contact.cpp:236
yarp::serversql::impl
Definition: Allocator.h:18