Includes cleanups
[invirt/third/libt4.git] / handle.cc
1 #include "handle.h"
2
3 class hinfo {
4 public:
5     unique_ptr<rpcc> client;
6     bool valid = true;
7     string destination;
8     mutex client_mutex;
9     hinfo(const string & destination_) : destination(destination_) {}
10 };
11
12 static mutex mgr_mutex;
13 static map<string, shared_ptr<hinfo>> hmap;
14
15 handle::handle(const string & destination) {
16     lock ml(mgr_mutex);
17     h = hmap[destination];
18     if (!h || !h->valid)
19         h = (hmap[destination] = make_shared<hinfo>(destination));
20 }
21
22 rpcc * handle::safebind() {
23     if (!h)
24         return nullptr;
25     lock cl(h->client_mutex);
26     if (!h->valid)
27         return nullptr;
28     if (!h->client) {
29         unique_ptr<rpcc> client(new rpcc(h->destination));
30         LOG("trying to bind..." << h->destination);
31         // The test script assumes that the failure can be detected by paxos and
32         // rsm layer within few seconds. We have to set the timeout with a small
33         // value to support the assumption.
34         // 
35         // With RPC_LOSSY=5, tests may fail due to delays and time outs.
36         int ret = client->bind(milliseconds(1000));
37         if (ret < 0) {
38             LOG("bind failure! " << h->destination << " " << ret);
39             h->valid = false;
40         } else {
41             LOG("bind succeeded " << h->destination);
42             h->client = move(client);
43         }
44     }
45     return h->client.get();
46 }
47
48 void handle::invalidate() {
49     {
50         lock cl(h->client_mutex);
51         h->valid = false;
52
53         LOG_NONMEMBER("cl " << h->destination << " refcnt " << h.use_count());
54     }
55     lock ml(mgr_mutex);
56     hmap.erase(h->destination);
57     h = nullptr;
58 }
59
60 void invalidate_handle(const string & m) {
61     lock ml(mgr_mutex);
62     if (hmap.find(m) == hmap.end()) {
63         LOG_NONMEMBER("cl " << m << " isn't in cl list");
64         return;
65     }
66
67     hmap[m]->valid = false;
68     LOG_NONMEMBER("cl " << m << " refcnt " << hmap[m].use_count());
69     hmap.erase(m);
70 }