gdp / gdplogd / logd_pubsub.c @ master
History | View | Annotate | Download (11.5 KB)
1 | 9509f13b | Eric Allman | /* vim: set ai sw=4 sts=4 ts=4 : */
|
---|---|---|---|
2 | |||
3 | /*
|
||
4 | ** Handle publish/subscribe requests
|
||
5 | 055d3009 | Eric Allman | **
|
6 | ** ----- BEGIN LICENSE BLOCK -----
|
||
7 | ** GDPLOGD: Log Daemon for the Global Data Plane
|
||
8 | ** From the Ubiquitous Swarm Lab, 490 Cory Hall, U.C. Berkeley.
|
||
9 | **
|
||
10 | c87dd166 | Eric Allman | ** Copyright (c) 2015-2019, Regents of the University of California.
|
11 | 6bd5476b | Eric Allman | ** All rights reserved.
|
12 | 055d3009 | Eric Allman | **
|
13 | 6bd5476b | Eric Allman | ** Permission is hereby granted, without written agreement and without
|
14 | ** license or royalty fees, to use, copy, modify, and distribute this
|
||
15 | ** software and its documentation for any purpose, provided that the above
|
||
16 | ** copyright notice and the following two paragraphs appear in all copies
|
||
17 | ** of this software.
|
||
18 | 055d3009 | Eric Allman | **
|
19 | 6bd5476b | Eric Allman | ** IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
|
20 | ** SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST
|
||
21 | ** PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
|
||
22 | ** EVEN IF REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
23 | 055d3009 | Eric Allman | **
|
24 | 6bd5476b | Eric Allman | ** REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
|
25 | 055d3009 | Eric Allman | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
26 | 6bd5476b | Eric Allman | ** FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION,
|
27 | ** IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO
|
||
28 | ** OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
|
||
29 | ** OR MODIFICATIONS.
|
||
30 | 055d3009 | Eric Allman | ** ----- END LICENSE BLOCK -----
|
31 | 9509f13b | Eric Allman | */
|
32 | |||
33 | 66474e0a | Eric Allman | #include "logd.h" |
34 | #include "logd_pubsub.h" |
||
35 | 9509f13b | Eric Allman | |
36 | #include <gdp/gdp_priv.h> |
||
37 | 34e502ee | Eric Allman | #include <gdp/gdp_chan.h> |
38 | 42443eab | Eric Allman | #include <ep/ep.h> |
39 | 9509f13b | Eric Allman | #include <ep/ep_dbg.h> |
40 | 42443eab | Eric Allman | #include <ep/ep_hash.h> |
41 | |||
42 | #include <sys/queue.h> |
||
43 | 9509f13b | Eric Allman | |
44 | 66474e0a | Eric Allman | static EP_DBG Dbg = EP_DBG_INIT("gdplogd.pubsub", |
45 | "GDP Log Daemon pub/sub handling");
|
||
46 | 9509f13b | Eric Allman | |
47 | fec93aac | Eric Allman | extern EP_HASH *_OpenGOBCache; // associative cache |
48 | 42443eab | Eric Allman | |
49 | 9509f13b | Eric Allman | |
50 | /*
|
||
51 | ** SUB_SEND_MESSAGE_NOTIFICATION --- inform a subscriber of a new message
|
||
52 | e7b2a80c | Eric Allman | **
|
53 | ** Assumes req is locked.
|
||
54 | 9509f13b | Eric Allman | */
|
55 | |||
56 | 8bebf0e3 | Eric Allman | EP_STAT |
57 | sub_send_message_notification(gdp_req_t *req) |
||
58 | 9509f13b | Eric Allman | { |
59 | EP_STAT estat; |
||
60 | 2e4a5d7d | Eric Allman | |
61 | c5389e19 | Eric Allman | if (ep_dbg_test(Dbg, 33)) |
62 | 9509f13b | Eric Allman | { |
63 | a34bb9a0 | Eric Allman | ep_dbg_printf("sub_send_message_notification: ");
|
64 | 8bebf0e3 | Eric Allman | _gdp_req_dump(req, NULL, GDP_PR_BASIC, 0); |
65 | 9509f13b | Eric Allman | } |
66 | |||
67 | 79ec15a3 | Eric Allman | // sanity checks
|
68 | 8bebf0e3 | Eric Allman | EP_ASSERT(req->rpdu != NULL);
|
69 | EP_ASSERT(req->cpdu != NULL);
|
||
70 | EP_ASSERT(req->rpdu->msg != NULL);
|
||
71 | a34bb9a0 | Eric Allman | |
72 | 8bebf0e3 | Eric Allman | memcpy(req->rpdu->dst, req->cpdu->src, sizeof req->rpdu->dst);
|
73 | req->rpdu->msg->rid = req->cpdu->msg->rid; |
||
74 | e6319882 | Eric Allman | req->rpdu->msg->l5seqno = req->cpdu->msg->l5seqno; |
75 | 80b79281 | Eric Allman | estat = _gdp_pdu_out(req->rpdu, req->chan); |
76 | d65c01e2 | Eric Allman | |
77 | 04ceac3d | Eric Allman | if (!EP_STAT_ISOK(estat))
|
78 | { |
||
79 | ep_dbg_cprintf(Dbg, 1,
|
||
80 | "sub_send_message_notification: couldn't write PDU!\n");
|
||
81 | } |
||
82 | ea6bb08e | Eric Allman | |
83 | 8bebf0e3 | Eric Allman | return estat;
|
84 | 9509f13b | Eric Allman | } |
85 | |||
86 | |||
87 | /*
|
||
88 | ** SUB_NOTIFY_ALL_SUBSCRIBERS --- send something to all interested parties
|
||
89 | e7b2a80c | Eric Allman | **
|
90 | 53393e9c | Eric Allman | ** pubreq should be locked when this is called.
|
91 | 9509f13b | Eric Allman | */
|
92 | |||
93 | void
|
||
94 | 53393e9c | Eric Allman | sub_notify_all_subscribers(gdp_req_t *pubreq) |
95 | 9509f13b | Eric Allman | { |
96 | gdp_req_t *req; |
||
97 | 101504b5 | Eric Allman | gdp_req_t *nextreq; |
98 | 8bebf0e3 | Eric Allman | long timeout;
|
99 | 101504b5 | Eric Allman | EP_TIME_SPEC sub_timeout; |
100 | 9509f13b | Eric Allman | |
101 | 53393e9c | Eric Allman | EP_THR_MUTEX_ASSERT_ISLOCKED(&pubreq->mutex); |
102 | fec93aac | Eric Allman | GDP_GOB_ASSERT_ISLOCKED(pubreq->gob); |
103 | 8bebf0e3 | Eric Allman | EP_ASSERT_ELSE(pubreq->rpdu != NULL, return); |
104 | EP_ASSERT_ELSE(pubreq->rpdu->msg != NULL, return); |
||
105 | 9509f13b | Eric Allman | |
106 | a34bb9a0 | Eric Allman | // set up for subscription timeout
|
107 | 9509f13b | Eric Allman | { |
108 | 101504b5 | Eric Allman | EP_TIME_SPEC sub_delta; |
109 | 8bebf0e3 | Eric Allman | timeout = ep_adm_getlongparam("swarm.gdplogd.subscr.timeout", 0); |
110 | 101504b5 | Eric Allman | |
111 | b068acef | Eric Allman | if (timeout == 0) |
112 | timeout = ep_adm_getlongparam("swarm.gdp.subscr.timeout",
|
||
113 | GDP_SUBSCR_TIMEOUT_DEF); |
||
114 | 101504b5 | Eric Allman | ep_time_from_nsec(-timeout SECONDS, &sub_delta); |
115 | ep_time_deltanow(&sub_delta, &sub_timeout); |
||
116 | } |
||
117 | |||
118 | 8bebf0e3 | Eric Allman | if (ep_dbg_test(Dbg, 32)) |
119 | { |
||
120 | EP_TIME_SPEC now; |
||
121 | char tbuf[100]; |
||
122 | |||
123 | ep_time_now(&now); |
||
124 | ep_dbg_printf("sub_notify_all_subscribers(timeout=%ld, now=%s)\n",
|
||
125 | timeout, |
||
126 | ep_time_format(&now, tbuf, sizeof tbuf, EP_TIME_FMT_HUMAN));
|
||
127 | ep_dbg_printf("%spub", _gdp_pr_indent(1)); |
||
128 | _gdp_req_dump(pubreq, ep_dbg_getfile(), GDP_PR_BASIC, 1);
|
||
129 | } |
||
130 | |||
131 | eae1d3ec | Eric Allman | pubreq->gob->flags |= GOBF_KEEPLOCKED; |
132 | fec93aac | Eric Allman | for (req = LIST_FIRST(&pubreq->gob->reqs); req != NULL; req = nextreq) |
133 | 101504b5 | Eric Allman | { |
134 | 7f515f6d | Eric Allman | _gdp_req_lock(req); |
135 | fec93aac | Eric Allman | nextreq = LIST_NEXT(req, goblist); |
136 | 65f23ae5 | Eric Allman | EP_ASSERT_ELSE(req != nextreq, break);
|
137 | 7f515f6d | Eric Allman | |
138 | 9509f13b | Eric Allman | // make sure we don't tell ourselves
|
139 | if (req == pubreq)
|
||
140 | 7f515f6d | Eric Allman | { |
141 | _gdp_req_unlock(req); |
||
142 | 9509f13b | Eric Allman | continue;
|
143 | 7f515f6d | Eric Allman | } |
144 | e7b2a80c | Eric Allman | |
145 | cf71c5ea | Eric Allman | if (ep_dbg_test(Dbg, 59)) |
146 | { |
||
147 | 02de7463 | Eric Allman | ep_dbg_printf("sub_notify_all_subscribers: checking ");
|
148 | 4102ad3a | Eric Allman | _gdp_req_dump(req, ep_dbg_getfile(), GDP_PR_BASIC, 0);
|
149 | cf71c5ea | Eric Allman | } |
150 | |||
151 | 9509f13b | Eric Allman | // notify subscribers
|
152 | 101504b5 | Eric Allman | if (!EP_UT_BITSET(GDP_REQ_SRV_SUBSCR, req->flags))
|
153 | { |
||
154 | 8bebf0e3 | Eric Allman | ep_dbg_cprintf(Dbg, 59,
|
155 | " ... not a subscription (flags = 0x%x)\n",
|
||
156 | req->flags); |
||
157 | 101504b5 | Eric Allman | } |
158 | 94e663bc | Eric Allman | else if (!ep_time_before(&req->sub_ts, &sub_timeout)) |
159 | 101504b5 | Eric Allman | { |
160 | 8bebf0e3 | Eric Allman | EP_STAT estat; |
161 | EP_ASSERT_ELSE(req->cpdu != NULL, continue); |
||
162 | EP_ASSERT_ELSE(req->cpdu->msg != NULL, continue); |
||
163 | gdp_pdu_t *save_pdu = req->rpdu; |
||
164 | req->rpdu = pubreq->rpdu; |
||
165 | estat = sub_send_message_notification(req); |
||
166 | req->rpdu = save_pdu; |
||
167 | if (EP_STAT_ISOK(estat))
|
||
168 | { |
||
169 | // XXX: This won't really work in case of holes.
|
||
170 | req->nextrec++; |
||
171 | |||
172 | if (req->numrecs > 0 && --req->numrecs <= 0) |
||
173 | sub_end_subscription(req); |
||
174 | } |
||
175 | 101504b5 | Eric Allman | } |
176 | 02de7463 | Eric Allman | else
|
177 | 101504b5 | Eric Allman | { |
178 | // this subscription seems to be dead
|
||
179 | if (ep_dbg_test(Dbg, 18)) |
||
180 | { |
||
181 | 8bebf0e3 | Eric Allman | char tbuf[100]; |
182 | ep_time_format(&sub_timeout, tbuf, sizeof tbuf,
|
||
183 | EP_TIME_FMT_HUMAN); |
||
184 | ep_dbg_printf("sub_notify_all_subscribers: "
|
||
185 | "subscription timeout (%s):\n%s",
|
||
186 | tbuf, _gdp_pr_indent(1));
|
||
187 | _gdp_req_dump(req, ep_dbg_getfile(), GDP_PR_BASIC, 1);
|
||
188 | ep_dbg_printf("%s", _gdp_pr_indent(1)); |
||
189 | _gdp_gob_dump(req->gob, ep_dbg_getfile(), GDP_PR_BASIC, 1);
|
||
190 | 101504b5 | Eric Allman | } |
191 | |||
192 | // actually remove the subscription
|
||
193 | e6b0a042 | Eric Allman | //XXX isn't this done by _gdp_req_free???
|
194 | fec93aac | Eric Allman | //LIST_REMOVE(req, goblist);
|
195 | 19efef53 | Eric Allman | |
196 | fec93aac | Eric Allman | EP_ASSERT(req->gob != NULL);
|
197 | EP_ASSERT(EP_UT_BITSET(GDP_REQ_ON_GOB_LIST, req->flags)); |
||
198 | 283110f2 | Eric Allman | _gdp_req_free(&req); |
199 | 101504b5 | Eric Allman | } |
200 | e7b2a80c | Eric Allman | if (req != NULL) |
201 | _gdp_req_unlock(req); |
||
202 | 9509f13b | Eric Allman | } |
203 | eae1d3ec | Eric Allman | pubreq->gob->flags &= ~GOBF_KEEPLOCKED; |
204 | 9509f13b | Eric Allman | } |
205 | 2e4a5d7d | Eric Allman | |
206 | |||
207 | /*
|
||
208 | ** SUB_END_SUBSCRIPTION --- terminate a subscription
|
||
209 | e7b2a80c | Eric Allman | **
|
210 | fec93aac | Eric Allman | ** req and req->gob should be locked when this is called.
|
211 | 2e4a5d7d | Eric Allman | */
|
212 | |||
213 | void
|
||
214 | sub_end_subscription(gdp_req_t *req) |
||
215 | { |
||
216 | 1b7c480e | Eric Allman | |
217 | 2a8cda22 | Eric Allman | EP_THR_MUTEX_ASSERT_ISLOCKED(&req->mutex); |
218 | fec93aac | Eric Allman | GDP_GOB_ASSERT_ISLOCKED(req->gob); |
219 | e7b2a80c | Eric Allman | |
220 | 2e4a5d7d | Eric Allman | // make it not persistent and not a subscription
|
221 | 1440421a | Eric Allman | req->flags &= ~(GDP_REQ_PERSIST | GDP_REQ_SRV_SUBSCR); |
222 | 2e4a5d7d | Eric Allman | |
223 | // remove the request from the work list
|
||
224 | fec93aac | Eric Allman | if (EP_UT_BITSET(GDP_REQ_ON_GOB_LIST, req->flags))
|
225 | 42443eab | Eric Allman | { |
226 | fec93aac | Eric Allman | gdp_gob_t *gob = req->gob; |
227 | LIST_REMOVE(req, goblist); |
||
228 | req->flags &= ~GDP_REQ_ON_GOB_LIST; |
||
229 | EP_ASSERT(gob->refcnt > 1);
|
||
230 | _gdp_gob_decref(&gob, true);
|
||
231 | 42443eab | Eric Allman | } |
232 | deca9f59 | Eric Allman | |
233 | b27895fb | Eric Allman | // make sure we have a response message available
|
234 | if (req->rpdu == NULL || req->rpdu->msg == NULL) |
||
235 | { |
||
236 | GdpMessage *msg = ep_mem_malloc(sizeof *msg);
|
||
237 | gdp_message__init(msg); |
||
238 | if (req->rpdu == NULL) |
||
239 | 5edf4ad2 | Eric Allman | req->rpdu = _gdp_pdu_new(msg, req->cpdu->dst, req->cpdu->src, |
240 | GDP_SEQNO_NONE); |
||
241 | b27895fb | Eric Allman | req->rpdu->msg = msg; |
242 | } |
||
243 | |||
244 | 2e4a5d7d | Eric Allman | // send an "end of subscription" event
|
245 | b27895fb | Eric Allman | req->rpdu->msg->rid = req->cpdu->msg->rid; |
246 | bd278f2e | Eric Allman | req->rpdu->msg->cmd = GDP_ACK_END_OF_RESULTS; |
247 | 2e4a5d7d | Eric Allman | |
248 | 9c515e64 | Eric Allman | if (ep_dbg_test(Dbg, 39)) |
249 | 2e4a5d7d | Eric Allman | { |
250 | 9c515e64 | Eric Allman | ep_dbg_printf("sub_end_subscription removing:\n ");
|
251 | 4102ad3a | Eric Allman | _gdp_req_dump(req, ep_dbg_getfile(), GDP_PR_BASIC, 0);
|
252 | 2e4a5d7d | Eric Allman | } |
253 | |||
254 | 80b79281 | Eric Allman | (void) _gdp_pdu_out(req->rpdu, req->chan);
|
255 | 2e4a5d7d | Eric Allman | } |
256 | 9d11c6da | Eric Allman | |
257 | |||
258 | /*
|
||
259 | fec93aac | Eric Allman | ** Unsubscribe all requests for a given gob and destination.
|
260 | 9c515e64 | Eric Allman | ** Can also optionally select a particular request id.
|
261 | cf05aa39 | Eric Allman | */
|
262 | |||
263 | EP_STAT |
||
264 | sub_end_all_subscriptions( |
||
265 | fec93aac | Eric Allman | gdp_gob_t *gob, |
266 | 9c515e64 | Eric Allman | gdp_name_t dest, |
267 | gdp_rid_t rid) |
||
268 | cf05aa39 | Eric Allman | { |
269 | EP_STAT estat; |
||
270 | gdp_req_t *req; |
||
271 | gdp_req_t *nextreq; |
||
272 | |||
273 | 2f4bea8c | Eric Allman | if (ep_dbg_test(Dbg, 29)) |
274 | { |
||
275 | cfc94dab | Eric Allman | gdp_pname_t dst_p; |
276 | ep_dbg_printf("sub_end_all_subscriptions: rid %" PRIgdp_rid " dst %s\n ", |
||
277 | rid, gdp_printable_name(dest, dst_p)); |
||
278 | c5a6d4fa | Eric Allman | _gdp_gob_dump(gob, ep_dbg_getfile(), GDP_PR_BASIC, 1);
|
279 | 2f4bea8c | Eric Allman | } |
280 | |||
281 | fec93aac | Eric Allman | GDP_GOB_ASSERT_ISLOCKED(gob); |
282 | eae1d3ec | Eric Allman | if (EP_UT_BITSET(GOBF_KEEPLOCKED, gob->flags) && ep_dbg_test(Dbg, 1)) |
283 | ep_dbg_printf("sub_end_all_subscriptions: GOBF_KEEPLOCKED on entry\n");
|
||
284 | gob->flags |= GOBF_KEEPLOCKED; |
||
285 | 2f4bea8c | Eric Allman | |
286 | cf05aa39 | Eric Allman | do
|
287 | { |
||
288 | estat = EP_STAT_OK; |
||
289 | fec93aac | Eric Allman | for (req = LIST_FIRST(&gob->reqs); req != NULL; req = nextreq) |
290 | cf05aa39 | Eric Allman | { |
291 | estat = _gdp_req_lock(req); |
||
292 | EP_STAT_CHECK(estat, break);
|
||
293 | fec93aac | Eric Allman | nextreq = LIST_NEXT(req, goblist); |
294 | cfc94dab | Eric Allman | if (!GDP_NAME_SAME(req->cpdu->dst, dest) ||
|
295 | (rid != GDP_PDU_NO_RID && rid != req->cpdu->msg->rid) || |
||
296 | fec93aac | Eric Allman | !EP_ASSERT(req->gob == gob)) |
297 | cf05aa39 | Eric Allman | { |
298 | _gdp_req_unlock(req); |
||
299 | continue;
|
||
300 | } |
||
301 | |||
302 | fec93aac | Eric Allman | // remove subscription for this destination (but keep GOB locked)
|
303 | 9c515e64 | Eric Allman | if (ep_dbg_test(Dbg, 39)) |
304 | { |
||
305 | ep_dbg_printf("sub_end_all_subscriptions removing ");
|
||
306 | _gdp_req_dump(req, ep_dbg_getfile(), GDP_PR_BASIC, 0);
|
||
307 | } |
||
308 | fec93aac | Eric Allman | LIST_REMOVE(req, goblist); |
309 | req->flags &= ~GDP_REQ_ON_GOB_LIST; |
||
310 | _gdp_gob_decref(&req->gob, false);
|
||
311 | cf05aa39 | Eric Allman | _gdp_req_free(&req); |
312 | } |
||
313 | } while (!EP_STAT_ISOK(estat));
|
||
314 | eae1d3ec | Eric Allman | gob->flags &= ~GOBF_KEEPLOCKED; |
315 | cf05aa39 | Eric Allman | return estat;
|
316 | } |
||
317 | |||
318 | |||
319 | /*
|
||
320 | 9d11c6da | Eric Allman | ** SUB_RECLAIM_RESOURCES --- remove any expired subscriptions
|
321 | 42443eab | Eric Allman | **
|
322 | ** This is a bit tricky to get lock ordering correct. The
|
||
323 | ** obvious implementation is to loop through the channel
|
||
324 | fec93aac | Eric Allman | ** list, but when you try to lock a GOB or a request you
|
325 | 42443eab | Eric Allman | ** have a lock ordering problem (the channel is quite low
|
326 | ** in the locking hierarchy). Instead you run through
|
||
327 | fec93aac | Eric Allman | ** the GOB hash table.
|
328 | 9d11c6da | Eric Allman | */
|
329 | |||
330 | 42443eab | Eric Allman | // helper (does most of the work)
|
331 | static void |
||
332 | fec93aac | Eric Allman | gob_reclaim_subscriptions(gdp_gob_t *gob) |
333 | 9d11c6da | Eric Allman | { |
334 | 42443eab | Eric Allman | int istat;
|
335 | 9d11c6da | Eric Allman | gdp_req_t *req; |
336 | gdp_req_t *nextreq; |
||
337 | EP_TIME_SPEC sub_timeout; |
||
338 | |||
339 | 42443eab | Eric Allman | // just in case
|
340 | fec93aac | Eric Allman | if (gob == NULL) |
341 | 42443eab | Eric Allman | return;
|
342 | |||
343 | 9d11c6da | Eric Allman | { |
344 | EP_TIME_SPEC sub_delta; |
||
345 | 2f4bea8c | Eric Allman | long timeout = ep_adm_getlongparam("swarm.gdp.subscr.timeout", |
346 | GDP_SUBSCR_TIMEOUT_DEF); |
||
347 | 9d11c6da | Eric Allman | |
348 | ep_time_from_nsec(-timeout SECONDS, &sub_delta); |
||
349 | ep_time_deltanow(&sub_delta, &sub_timeout); |
||
350 | b8f93c05 | Eric Allman | ep_dbg_cprintf(Dbg, 39,
|
351 | fec93aac | Eric Allman | "gob_reclaim_subscriptions: GOB = %p, refcnt = %d, timeout = %ld\n",
|
352 | gob, gob->refcnt, timeout); |
||
353 | 9d11c6da | Eric Allman | } |
354 | |||
355 | fec93aac | Eric Allman | // don't even try locked GOBs
|
356 | 42443eab | Eric Allman | // first check is to avoid extraneous errors
|
357 | eae1d3ec | Eric Allman | if (EP_UT_BITSET(GOBF_ISLOCKED, gob->flags))
|
358 | b8f93c05 | Eric Allman | { |
359 | fec93aac | Eric Allman | ep_dbg_cprintf(Dbg, 39, " ... skipping locked GOB\n"); |
360 | 42443eab | Eric Allman | return;
|
361 | b8f93c05 | Eric Allman | } |
362 | fec93aac | Eric Allman | istat = ep_thr_mutex_trylock(&gob->mutex); |
363 | 42443eab | Eric Allman | if (istat != 0) |
364 | 9d11c6da | Eric Allman | { |
365 | 42443eab | Eric Allman | if (ep_dbg_test(Dbg, 21)) |
366 | { |
||
367 | fec93aac | Eric Allman | ep_dbg_printf("gob_reclaim_subscriptions: gob already locked:\n ");
|
368 | _gdp_gob_dump(gob, ep_dbg_getfile(), GDP_PR_BASIC, 0);
|
||
369 | 42443eab | Eric Allman | } |
370 | return;
|
||
371 | } |
||
372 | eae1d3ec | Eric Allman | gob->flags |= GOBF_ISLOCKED; // if trylock succeeded
|
373 | 193dfcd3 | Eric Allman | |
374 | fec93aac | Eric Allman | nextreq = LIST_FIRST(&gob->reqs); |
375 | 42443eab | Eric Allman | while ((req = nextreq) != NULL) |
376 | { |
||
377 | b8f93c05 | Eric Allman | if (ep_dbg_test(Dbg, 59)) |
378 | { |
||
379 | fec93aac | Eric Allman | ep_dbg_printf("gob_reclaim_subscriptions: checking ");
|
380 | b8f93c05 | Eric Allman | _gdp_req_dump(req, ep_dbg_getfile(), GDP_PR_BASIC, 0);
|
381 | } |
||
382 | |||
383 | fec93aac | Eric Allman | // now that GOB is locked, we lock the request
|
384 | 193dfcd3 | Eric Allman | istat = ep_thr_mutex_trylock(&req->mutex); |
385 | 42443eab | Eric Allman | if (istat != 0) // checking on status of req lock attempt |
386 | 193dfcd3 | Eric Allman | { |
387 | // already locked
|
||
388 | b8f93c05 | Eric Allman | if (ep_dbg_test(Dbg, 41)) |
389 | 474af7ac | Eric Allman | { |
390 | fec93aac | Eric Allman | ep_dbg_printf("gob_reclaim_subscriptions: req already locked:\n ");
|
391 | 474af7ac | Eric Allman | _gdp_req_dump(req, ep_dbg_getfile(), GDP_PR_BASIC, 0);
|
392 | } |
||
393 | fec93aac | Eric Allman | _gdp_gob_unlock(req->gob); |
394 | 193dfcd3 | Eric Allman | continue;
|
395 | } |
||
396 | 9d11c6da | Eric Allman | |
397 | 42443eab | Eric Allman | // get next request while locked and do sanity checks
|
398 | fec93aac | Eric Allman | nextreq = LIST_NEXT(req, goblist); |
399 | if (!EP_ASSERT(req != nextreq) || !EP_ASSERT(req->gob == gob))
|
||
400 | 42443eab | Eric Allman | { |
401 | fec93aac | Eric Allman | _gdp_gob_unlock(req->gob); |
402 | 42443eab | Eric Allman | break;
|
403 | } |
||
404 | |||
405 | 9d11c6da | Eric Allman | |
406 | if (!EP_UT_BITSET(GDP_REQ_SRV_SUBSCR, req->flags))
|
||
407 | { |
||
408 | ep_dbg_cprintf(Dbg, 59, " ... not a subscription (flags = 0x%x)\n", |
||
409 | req->flags); |
||
410 | } |
||
411 | 94e663bc | Eric Allman | else if (ep_time_before(&req->sub_ts, &sub_timeout)) |
412 | 9d11c6da | Eric Allman | { |
413 | // this subscription seems to be dead
|
||
414 | if (ep_dbg_test(Dbg, 18)) |
||
415 | { |
||
416 | 2f4bea8c | Eric Allman | ep_dbg_printf(" ... subscription timeout: ");
|
417 | fec93aac | Eric Allman | _gdp_gob_dump(req->gob, ep_dbg_getfile(), GDP_PR_BASIC, 0);
|
418 | 9d11c6da | Eric Allman | } |
419 | |||
420 | 8a421c17 | Eric Allman | // have to manually remove req from lists to avoid lock inversion
|
421 | fec93aac | Eric Allman | if (EP_UT_BITSET(GDP_REQ_ON_GOB_LIST, req->flags))
|
422 | 6dfc87d5 | Eric Allman | { |
423 | fec93aac | Eric Allman | // gob is already locked
|
424 | LIST_REMOVE(req, goblist); |
||
425 | 6dfc87d5 | Eric Allman | } |
426 | if (EP_UT_BITSET(GDP_REQ_ON_CHAN_LIST, req->flags))
|
||
427 | { |
||
428 | LIST_REMOVE(req, chanlist); // chan already locked
|
||
429 | } |
||
430 | fec93aac | Eric Allman | req->flags &= ~(GDP_REQ_ON_GOB_LIST | GDP_REQ_ON_CHAN_LIST); |
431 | _gdp_gob_decref(&req->gob, true);
|
||
432 | 9d11c6da | Eric Allman | _gdp_req_free(&req); |
433 | } |
||
434 | 2f4bea8c | Eric Allman | else if (ep_dbg_test(Dbg, 59)) |
435 | { |
||
436 | ep_dbg_printf(" ... not yet time\n");
|
||
437 | } |
||
438 | b8f93c05 | Eric Allman | |
439 | 9d11c6da | Eric Allman | if (req != NULL) |
440 | _gdp_req_unlock(req); |
||
441 | } |
||
442 | b8f93c05 | Eric Allman | |
443 | fec93aac | Eric Allman | if (gob != NULL) |
444 | _gdp_gob_unlock(gob); |
||
445 | 42443eab | Eric Allman | } |
446 | |||
447 | void
|
||
448 | sub_reclaim_resources(gdp_chan_t *chan) |
||
449 | { |
||
450 | fec93aac | Eric Allman | _gdp_gob_cache_foreach(gob_reclaim_subscriptions); |
451 | 9d11c6da | Eric Allman | } |