class hinfo {
public:
- unique_ptr<rpcc> cl;
- bool del = false;
- string m;
+ unique_ptr<rpcc> client;
+ bool valid = true;
+ string destination;
mutex client_mutex;
- hinfo(const string & m_) : m(m_) {}
+ hinfo(const string & destination_) : destination(destination_) {}
};
static mutex mgr_mutex;
static map<string, shared_ptr<hinfo>> hmap;
-static shared_ptr<hinfo> acquire_handle(string m) {
+handle::handle(const string & destination) : destination_(destination) {
lock ml(mgr_mutex);
- shared_ptr<hinfo> h = hmap[m];
- if (!h || h->del)
- return (hmap[m] = make_shared<hinfo>(m));
- return h;
+ h = hmap[destination];
+ if (!h || !h->valid)
+ h = (hmap[destination] = make_shared<hinfo>(destination));
}
-static void delete_handle(const string & m, lock &) {
- if (hmap.find(m) == hmap.end()) {
- LOG_NONMEMBER("cl " << m << " isn't in cl list");
- return;
- }
-
- hmap[m]->del = true;
- LOG_NONMEMBER("cl " << m << " refcnt " << hmap[m].use_count());
- hmap.erase(m);
-}
-
-void invalidate_handle(const string & m) {
- lock ml(mgr_mutex);
- delete_handle(m, ml);
-}
-
-handle::handle(const string & m) : h(acquire_handle(m)) {}
-
rpcc * handle::safebind() {
if (!h)
return nullptr;
- lock ml(h->client_mutex);
- if (h->del)
+ lock cl(h->client_mutex);
+ if (!h->valid)
return nullptr;
- if (!h->cl) {
- unique_ptr<rpcc> cl(new rpcc(h->m));
- LOG("trying to bind..." << h->m);
- // The test script assumes that the failure can be detected by paxos and
- // rsm layer within few seconds. We have to set the timeout with a small
- // value to support the assumption.
- //
- // With RPC_LOSSY=5, tests may fail due to delays and time outs.
- int ret = cl->bind(milliseconds(1000));
+ if (!h->client) {
+ unique_ptr<rpcc> client(new rpcc(h->destination));
+ LOG("bind(\"" << h->destination << "\")");
+ int ret = client->bind(milliseconds(1000));
if (ret < 0) {
- LOG("bind failure! " << h->m << " " << ret);
- h->del = true;
+ LOG("bind failure! " << h->destination << " " << ret);
+ h->valid = false;
} else {
- LOG("bind succeeded " << h->m);
- h->cl = move(cl);
+ LOG("bind succeeded " << h->destination);
+ h->client = move(client);
}
}
- return h->cl.get();
+ return h->client.get();
+}
+
+void handle::invalidate() {
+ h.reset();
+ lock ml(mgr_mutex);
+ if (hmap.find(destination_) != hmap.end()) {
+ hmap[destination_]->valid = false;
+ LOG_NONMEMBER("cl " << destination_ << " refcnt " << hmap[destination_].use_count());
+ hmap.erase(destination_);
+ }
}