20438f9fa7b5dd640974a8eb3f06bd08f935494a
[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     std::mutex client_mutex;
9     hinfo(const string & destination_) : destination(destination_) {}
10 };
11
12 static std::mutex mgr_mutex;
13 static std::map<string, shared_ptr<hinfo>> hmap;
14
15 void handle::shutdown() {
16     lock ml(mgr_mutex);
17     LOG_NONMEMBER << "Shutting down handle manager";
18     for (auto p : hmap) {
19         p.second->valid = false;
20         LOG_NONMEMBER << "cl " << p.first << " refcnt " << p.second.use_count();
21     }
22     hmap.clear();
23 }
24
25 handle::handle(const string & destination) : destination_(destination) {
26     lock ml(mgr_mutex);
27     h = hmap[destination];
28     if (!h || !h->valid)
29         h = (hmap[destination] = std::make_shared<hinfo>(destination));
30 }
31
32 rpcc * handle::safebind() {
33     if (!h)
34         return nullptr;
35     lock cl(h->client_mutex);
36     if (!h->valid)
37         return nullptr;
38     if (!h->client) {
39         unique_ptr<rpcc> client(new rpcc(h->destination));
40         LOG << "bind(\"" << h->destination << "\")";
41         int ret = client->bind(milliseconds(1000));
42         if (ret < 0) {
43             LOG << "bind failure! " << h->destination << " " << ret;
44             h->valid = false;
45         } else {
46             LOG << "bind succeeded " << h->destination;
47             h->client = std::move(client);
48         }
49     }
50     return h->client.get();
51 }
52
53 void handle::invalidate() {
54     h.reset();
55     lock ml(mgr_mutex);
56     if (hmap.find(destination_) != hmap.end()) {
57         hmap[destination_]->valid = false;
58         LOG << "cl " << destination_ << " refcnt " << hmap[destination_].use_count();
59         hmap.erase(destination_);
60     }
61 }