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