All random numbers generated via one PRNG seeded in one place.
[invirt/third/libt4.git] / lock_client.h
1 // lock client interface.
2
3 #ifndef lock_client_h
4 #define lock_client_h
5
6 #ifdef __cplusplus
7
8 #include "types.h"
9 #include "lock_protocol.h"
10 #include "rpc/fifo.h"
11 #include "rsm_client.h"
12 #include "maybe.h"
13
14 class lock_release_user {
15     public:
16         virtual void dorelease(lock_protocol::lockid_t) = 0;
17         virtual ~lock_release_user() {}
18 };
19
20 class lock_state {
21 public:
22     enum {
23         none = 0,
24         retrying,
25         free,
26         locked,
27         acquiring,
28         releasing
29     } state = none;
30     std::thread::id held_by;
31     std::list<thread::id> wanted_by;
32     std::mutex m;
33     std::map<thread::id, cond> c;
34     lock_protocol::xid_t xid;
35     void wait(lock & mutex_lock);
36     void signal();
37     void signal(thread::id who);
38 };
39
40 typedef std::map<lock_protocol::lockid_t, lock_state> lock_map;
41
42 // Clients that caches locks.  The server can revoke locks using
43 // lock_revoke_server.
44 class lock_client {
45     private:
46         unique_ptr<rpcc> cl;
47         unique_ptr<rpcs> rlsrpc;
48         thread releaser_thread;
49         unique_ptr<rsm_client> rsmc;
50         lock_release_user *lu;
51         in_port_t rlock_port;
52         string hostname;
53         string id;
54         std::mutex xid_mutex;
55         lock_protocol::xid_t next_xid;
56         fifo<maybe<lock_protocol::lockid_t>> release_fifo;
57         std::mutex lock_table_lock;
58         lock_map lock_table;
59         lock_state & get_lock_state(lock_protocol::lockid_t lid);
60     public:
61         lock_client(string xdst, lock_release_user *l = 0);
62         ~lock_client();
63         lock_protocol::status acquire(lock_protocol::lockid_t);
64         lock_protocol::status release(lock_protocol::lockid_t);
65         int stat(lock_protocol::lockid_t);
66         void releaser();
67         rlock_protocol::status revoke_handler(int &, lock_protocol::lockid_t, lock_protocol::xid_t);
68         rlock_protocol::status retry_handler(int &, lock_protocol::lockid_t, lock_protocol::xid_t);
69 };
70
71 #endif // C++
72
73 #ifdef __cplusplus
74 extern "C" {
75 #endif
76
77 struct _t4_lock_client;
78 typedef struct _t4_lock_client t4_lock_client;
79
80 typedef enum {
81     T4_OK,
82     T4_RETRY,
83     T4_RPCERR,
84     T4_NOENT,
85     T4_IOERR
86 } t4_xxstatus;
87
88 typedef int t4_status;
89
90 typedef const char * t4_lockid_t;
91
92 t4_lock_client *t4_lock_client_new(const char *dst);
93 void t4_lock_client_delete(t4_lock_client *);
94 t4_status t4_lock_client_acquire(t4_lock_client *, t4_lockid_t);
95 t4_status t4_lock_client_release(t4_lock_client *, t4_lockid_t);
96 t4_status t4_lock_client_stat(t4_lock_client *, t4_lockid_t);
97
98 #ifdef __cplusplus
99 }
100 #endif
101
102 #endif