Lots of clean-ups and simplifications
[invirt/third/libt4.git] / handle.cc
1 #include "handle.h"
2 #include <stdio.h>
3 #include "tprintf.h"
4 #include "lock.h"
5
6 handle_mgr mgr;
7
8 handle::handle(std::string m) 
9 {
10     h = mgr.get_handle(m);
11 }
12
13 rpcc *
14 handle::safebind()
15 {
16     if (!h)
17         return NULL;
18     lock ml(h->cl_mutex);
19     if (h->del)
20         return NULL;
21     if (h->cl)
22         return h->cl;
23     sockaddr_in dstsock;
24     make_sockaddr(h->m.c_str(), &dstsock);
25     rpcc *cl = new rpcc(dstsock);
26     tprintf("handler_mgr::get_handle trying to bind...%s\n", h->m.c_str());
27     int ret;
28     // The test script assumes that the failure can be detected by paxos and
29     // rsm layer within few seconds. We have to set the timeout with a small
30     // value to support the assumption.
31     // 
32     // With RPC_LOSSY=5, tests may fail due to delays and time outs.
33     ret = cl->bind(rpcc::to(1000));
34     if (ret < 0) {
35         tprintf("handle_mgr::get_handle bind failure! %s %d\n", h->m.c_str(), ret);
36         delete cl;
37         h->del = true;
38     } else {
39         tprintf("handle_mgr::get_handle bind succeeded %s\n", h->m.c_str());
40         h->cl = cl;
41     }
42     return h->cl;
43 }
44
45 handle::~handle() 
46 {
47     if (h) mgr.done_handle(h);
48 }
49
50 handle_mgr::handle_mgr()
51 {
52 }
53
54 struct hinfo *
55 handle_mgr::get_handle(std::string m)
56 {
57     lock ml(handle_mutex);
58     struct hinfo *h = 0;
59     if (hmap.find(m) == hmap.end()) {
60         h = new hinfo;
61         h->cl = NULL;
62         h->del = false;
63         h->refcnt = 1;
64         h->m = m;
65         hmap[m] = h;
66     } else if (!hmap[m]->del) {
67         h = hmap[m];
68         h->refcnt ++;
69     }
70     return h;
71 }
72
73 void 
74 handle_mgr::done_handle(struct hinfo *h)
75 {
76     lock ml(handle_mutex);
77     h->refcnt--;
78     if (h->refcnt == 0 && h->del)
79         delete_handle_wo(h->m);
80 }
81
82 void
83 handle_mgr::delete_handle(std::string m)
84 {
85     lock ml(handle_mutex);
86     delete_handle_wo(m);
87 }
88
89 // Must be called with handle_mutex locked.
90 void
91 handle_mgr::delete_handle_wo(std::string m)
92 {
93     if (hmap.find(m) == hmap.end()) {
94         tprintf("handle_mgr::delete_handle_wo: cl %s isn't in cl list\n", m.c_str());
95     } else {
96         tprintf("handle_mgr::delete_handle_wo: cl %s refcnt %d\n", m.c_str(),
97                 hmap[m]->refcnt);
98         struct hinfo *h = hmap[m];
99         if (h->refcnt == 0) {
100             if (h->cl) {
101                 h->cl->cancel();
102                 delete h->cl;
103             }
104             hmap.erase(m);
105             delete h;
106         } else {
107             h->del = true;
108         }
109     }
110 }