4 |
4 |
5 #include "request.h" |
5 #include "request.h" |
6 #include "memcache.h" |
6 #include "memcache.h" |
7 #include "../common.h" |
7 #include "../common.h" |
8 |
8 |
9 struct memcache_req *memcache_req_alloc (struct memcache *mc, enum memcache_command cmd_type, const struct memcache_key *key, void *cb_arg) { |
9 struct memcache_req *memcache_req_alloc (struct memcache *mc, enum memcache_command cmd_type, const struct memcache_key *key, const struct memcache_obj *obj, const struct memcache_buf *buf, void *cb_arg) { |
10 struct memcache_req *req = NULL; |
10 struct memcache_req *req = NULL; |
|
11 |
|
12 // ensure key is provided |
|
13 assert(key != NULL); |
11 |
14 |
12 // allocate it |
15 // allocate it |
13 if ((req = calloc(1, sizeof(*req))) == NULL) |
16 if ((req = calloc(1, sizeof(*req))) == NULL) |
14 ERROR("calloc"); |
17 ERROR("calloc"); |
15 |
18 |
18 |
21 |
19 // copy the key |
22 // copy the key |
20 if ((req->key.buf = malloc(key->len)) == NULL) |
23 if ((req->key.buf = malloc(key->len)) == NULL) |
21 ERROR("malloc key buf"); |
24 ERROR("malloc key buf"); |
22 |
25 |
23 // copy over the key |
|
24 memcpy(req->key.buf, key->buf, key->len); |
26 memcpy(req->key.buf, key->buf, key->len); |
25 req->key.len = key->len; |
27 req->key.len = key->len; |
|
28 |
|
29 // copy the obj if provided |
|
30 if (obj) { |
|
31 memcpy(&req->obj, obj, sizeof(req->obj)); |
|
32 req->have_obj = 1; |
|
33 } |
|
34 |
|
35 // copy the buf if provided |
|
36 if (buf) { |
|
37 memcpy(&req->buf, buf, sizeof(req->buf)); |
|
38 req->have_buf = 1; |
|
39 } |
26 |
40 |
27 // store the other data |
41 // store the other data |
28 req->mc = mc; |
42 req->mc = mc; |
29 req->cmd_type = cmd_type; |
43 req->cmd_type = cmd_type; |
30 req->cb_arg = cb_arg; |
44 req->cb_arg = cb_arg; |
39 } |
53 } |
40 |
54 |
41 return NULL; |
55 return NULL; |
42 } |
56 } |
43 |
57 |
|
58 // accessors |
|
59 enum memcache_req_state memcache_req_state (struct memcache_req *req) { |
|
60 return req->state; |
|
61 } |
|
62 |
|
63 enum memcache_command memcache_req_cmd (struct memcache_req *req) { |
|
64 return req->cmd_type; |
|
65 } |
|
66 |
|
67 enum memcache_reply memcache_req_reply (struct memcache_req *req) { |
|
68 return req->reply_type; |
|
69 } |
|
70 |
|
71 const struct memcache_key *keymemcache_req_key (struct memcache_req *req) { |
|
72 return &req->key; |
|
73 } |
|
74 |
|
75 const struct memcache_obj *memcache_req_obj (struct memcache_req *req) { |
|
76 return req->have_obj ? &req->obj : NULL; |
|
77 } |
|
78 |
|
79 const struct memcache_buf *memcache_req_buf (struct memcache_req *req) { |
|
80 return req->have_buf ? &req->buf : NULL; |
|
81 } |
|
82 |
|
83 // events |
44 static void _memcache_req_notify (struct memcache_req *req) { |
84 static void _memcache_req_notify (struct memcache_req *req) { |
45 req->mc->cb_fn(req, req->cb_arg); |
85 req->mc->cb_fn(req, req->cb_arg); |
46 } |
86 } |
47 |
87 |
48 void memcache_req_queued (struct memcache_req *req) { |
88 void memcache_req_queued (struct memcache_req *req) { |
55 req->state = MEMCACHE_STATE_SEND; |
95 req->state = MEMCACHE_STATE_SEND; |
56 |
96 |
57 // _memcache_req_notify(req); |
97 // _memcache_req_notify(req); |
58 } |
98 } |
59 |
99 |
60 void memcache_req_reply (struct memcache_req *req, enum memcache_reply reply_type) { |
100 void memcache_req_recv (struct memcache_req *req, enum memcache_reply reply_type) { |
61 req->state = MEMCACHE_STATE_REPLY; |
101 req->state = MEMCACHE_STATE_REPLY; |
62 req->reply_type = reply_type; |
102 req->reply_type = reply_type; |
|
103 |
|
104 // we must surely have a valid obj now |
|
105 req->have_obj = 1; |
63 |
106 |
64 _memcache_req_notify(req); |
107 _memcache_req_notify(req); |
65 } |
108 } |
66 |
109 |
67 void memcache_req_data (struct memcache_req *req) { |
110 void memcache_req_data (struct memcache_req *req) { |
68 assert(req->state == MEMCACHE_STATE_REPLY || req->state == MEMCACHE_STATE_REPLY_DATA); |
111 assert(req->state == MEMCACHE_STATE_REPLY || req->state == MEMCACHE_STATE_REPLY_DATA); |
69 |
112 |
70 req->state = MEMCACHE_STATE_REPLY_DATA; |
113 req->state = MEMCACHE_STATE_REPLY_DATA; |
|
114 |
|
115 // we must surely have a valid buf now |
|
116 req->have_buf = 1; |
71 |
117 |
72 _memcache_req_notify(req); |
118 _memcache_req_notify(req); |
73 } |
119 } |
74 |
120 |
75 void memcache_req_done (struct memcache_req *req) { |
121 void memcache_req_done (struct memcache_req *req) { |
76 // make sure we are in the REPLY/REPLY_DATA state |
122 // make sure we are in the REPLY/REPLY_DATA state |
77 assert(req->state == MEMCACHE_STATE_REPLY || req->state == MEMCACHE_STATE_REPLY_DATA); |
123 assert(req->state == MEMCACHE_STATE_REPLY || req->state == MEMCACHE_STATE_REPLY_DATA); |
|
124 |
|
125 // are we supposed to have data? |
|
126 if (req->buf.data) { |
|
127 // make sure we really have the full data, if applicable |
|
128 assert(req->buf.offset == req->buf.len); |
|
129 |
|
130 // yes... |
|
131 req->have_buf = 1; |
78 |
132 |
79 // make sure we really have the full data, if applicable |
133 // have data |
80 assert(req->buf.data == NULL || req->buf.offset == req->buf.len); |
134 req->state = MEMCACHE_STATE_DATA_DONE; |
|
135 |
|
136 } else { |
|
137 // no data |
|
138 req->state = MEMCACHE_STATE_DONE; |
|
139 } |
81 |
140 |
82 // forget the connection |
141 // forget the connection |
83 req->conn = NULL; |
142 req->conn = NULL; |
84 |
143 |
85 // state depends on if we have data or not... |
144 _memcache_req_notify(req); |
86 req->state = req->buf.data ? MEMCACHE_STATE_DATA_DONE : MEMCACHE_STATE_DONE; |
|
87 } |
145 } |
88 |
146 |
89 void memcache_req_error (struct memcache_req *req) { |
147 void memcache_req_error (struct memcache_req *req) { |
90 // forget our connection |
148 // forget our connection |
91 req->conn = NULL; |
149 req->conn = NULL; |