fa7495cd3d1ee19a6e32600ea53b169785a9b6be
[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) : destination_(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 << "bind(\"" << h->destination << "\")";
31         int ret = client->bind(milliseconds(1000));
32         if (ret < 0) {
33             LOG << "bind failure! " << h->destination << " " << ret;
34             h->valid = false;
35         } else {
36             LOG << "bind succeeded " << h->destination;
37             h->client = move(client);
38         }
39     }
40     return h->client.get();
41 }
42
43 void handle::invalidate() {
44     h.reset();
45     lock ml(mgr_mutex);
46     if (hmap.find(destination_) != hmap.end()) {
47         hmap[destination_]->valid = false;
48         LOG << "cl " << destination_ << " refcnt " << hmap[destination_].use_count();
49         hmap.erase(destination_);
50     }
51 }