Software /
code /
prosody
Comparison
util/async.lua @ 5796:0b66cb959161
util.async: Add guarder method, to create guards to ensure only a single runner can pass through a section of code at a time
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Tue, 13 Aug 2013 21:26:53 +0100 |
parent | 5794:66c3ad5d29ad |
child | 5797:a493b79cfad0 |
comparison
equal
deleted
inserted
replaced
5795:47c2f71d8314 | 5796:0b66cb959161 |
---|---|
38 if num == 0 and waiting then | 38 if num == 0 and waiting then |
39 runner_continue(thread); | 39 runner_continue(thread); |
40 elseif num < 0 then | 40 elseif num < 0 then |
41 error("done() called too many times"); | 41 error("done() called too many times"); |
42 end | 42 end |
43 end; | |
44 end | |
45 | |
46 function guarder() | |
47 local guards = {}; | |
48 return function (id, func) | |
49 local thread = coroutine.running(); | |
50 if not thread then | |
51 error("Not running in an async context, see http://prosody.im/doc/developers/async"); | |
52 end | |
53 local guard = guards[id]; | |
54 if not guard then | |
55 guard = {}; | |
56 guards[id] = guard; | |
57 log("debug", "New guard!"); | |
58 else | |
59 table.insert(guard, thread); | |
60 log("debug", "Guarded. %d threads waiting.", #guard) | |
61 coroutine.yield("wait"); | |
62 end | |
63 local function exit() | |
64 local next_waiting = table.remove(guard, 1); | |
65 if next_waiting then | |
66 log("debug", "guard: Executing next waiting thread (%d left)", #guard) | |
67 runner_continue(next_waiting); | |
68 else | |
69 log("debug", "Guard off duty.") | |
70 guards[id] = nil; | |
71 end | |
72 end | |
73 if func then | |
74 func(); | |
75 exit(); | |
76 return; | |
77 end | |
78 return exit; | |
43 end; | 79 end; |
44 end | 80 end |
45 | 81 |
46 local runner_mt = {}; | 82 local runner_mt = {}; |
47 runner_mt.__index = runner_mt; | 83 runner_mt.__index = runner_mt; |
117 | 153 |
118 function runner_mt:enqueue(input) | 154 function runner_mt:enqueue(input) |
119 table.insert(self.queue, input); | 155 table.insert(self.queue, input); |
120 end | 156 end |
121 | 157 |
122 return { waiter = waiter, runner = runner }; | 158 return { waiter = waiter, guarder = guarder, runner = runner }; |