e998b3c09841e5076fbeb9e25860a94ded646d61
[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     // Starting with lab 6, our test script assumes that the failure
29     // can be detected by paxos and rsm layer within few seconds. We have
30     // to set the timeout with a small value to support the assumption.
31     // 
32     // Note: with RPC_LOSSY=5, your lab would failed to pass the tests of
33     // lab 6 and lab 7 because the rpc layer may delay your RPC request, 
34     // and cause a time out failure. Please make sure RPC_LOSSY is set to 0.
35     ret = cl->bind(rpcc::to(1000));
36     if (ret < 0) {
37         tprintf("handle_mgr::get_handle bind failure! %s %d\n", h->m.c_str(), ret);
38         delete cl;
39         h->del = true;
40     } else {
41         tprintf("handle_mgr::get_handle bind succeeded %s\n", h->m.c_str());
42         h->cl = cl;
43     }
44     return h->cl;
45 }
46
47 handle::~handle() 
48 {
49     if (h) mgr.done_handle(h);
50 }
51
52 handle_mgr::handle_mgr()
53 {
54 }
55
56 struct hinfo *
57 handle_mgr::get_handle(std::string m)
58 {
59     lock ml(handle_mutex);
60     struct hinfo *h = 0;
61     if (hmap.find(m) == hmap.end()) {
62         h = new hinfo;
63         h->cl = NULL;
64         h->del = false;
65         h->refcnt = 1;
66         h->m = m;
67         hmap[m] = h;
68     } else if (!hmap[m]->del) {
69         h = hmap[m];
70         h->refcnt ++;
71     }
72     return h;
73 }
74
75 void 
76 handle_mgr::done_handle(struct hinfo *h)
77 {
78     lock ml(handle_mutex);
79     h->refcnt--;
80     if (h->refcnt == 0 && h->del)
81         delete_handle_wo(h->m);
82 }
83
84 void
85 handle_mgr::delete_handle(std::string m)
86 {
87     lock ml(handle_mutex);
88     delete_handle_wo(m);
89 }
90
91 // Must be called with handle_mutex locked.
92 void
93 handle_mgr::delete_handle_wo(std::string m)
94 {
95     if (hmap.find(m) == hmap.end()) {
96         tprintf("handle_mgr::delete_handle_wo: cl %s isn't in cl list\n", m.c_str());
97     } else {
98         tprintf("handle_mgr::delete_handle_wo: cl %s refcnt %d\n", m.c_str(),
99                 hmap[m]->refcnt);
100         struct hinfo *h = hmap[m];
101         if (h->refcnt == 0) {
102             if (h->cl) {
103                 h->cl->cancel();
104                 delete h->cl;
105             }
106             hmap.erase(m);
107             delete h;
108         } else {
109             h->del = true;
110         }
111     }
112 }