mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-13 22:49:11 +00:00
Add shared memory hit counter example to redbean
This commit is contained in:
parent
38e3ab57a6
commit
8aca94f951
6 changed files with 114 additions and 29 deletions
|
@ -20,35 +20,73 @@ db:exec[[
|
|||
INSERT INTO test (content) VALUES ('Hello Sqlite3');
|
||||
]]
|
||||
|
||||
-- shared memory hit counter
|
||||
SHM_LOCK = 0 -- index zero (first eight bytes) will hold mutex
|
||||
SHM_JSON = 8 -- store json payload starting at the index eight
|
||||
shm = unix.mapshared(65520)
|
||||
function Lock()
|
||||
local ok, old = shm:cmpxchg(SHM_LOCK, 0, 1)
|
||||
if not ok then
|
||||
if old == 1 then
|
||||
old = shm:xchg(SHM_LOCK, 2)
|
||||
end
|
||||
while old > 0 do
|
||||
shm:wait(SHM_LOCK, 2)
|
||||
old = shm:xchg(SHM_LOCK, 2)
|
||||
end
|
||||
end
|
||||
end
|
||||
function Unlock()
|
||||
old = shm:fetch_add(SHM_LOCK, -1)
|
||||
if old == 2 then
|
||||
shm:store(SHM_LOCK, 0)
|
||||
shm:wake(SHM_LOCK, 1)
|
||||
end
|
||||
end
|
||||
|
||||
function OnServerListen(fd, ip, port)
|
||||
unix.setsockopt(fd, unix.SOL_TCP, unix.TCP_SAVE_SYN, true)
|
||||
return false
|
||||
unix.setsockopt(fd, unix.SOL_TCP, unix.TCP_SAVE_SYN, true)
|
||||
return false
|
||||
end
|
||||
|
||||
function OnClientConnection(ip, port, serverip, serverport)
|
||||
syn, synerr = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_SAVED_SYN)
|
||||
syn, synerr = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_SAVED_SYN)
|
||||
end
|
||||
|
||||
function UpdateHitCounter()
|
||||
local s, t, k
|
||||
Lock()
|
||||
s = shm:read(SHM_JSON)
|
||||
if s == '' then s = '{}' end
|
||||
t = DecodeJson(s)
|
||||
k = GetPath()
|
||||
if not t[k] then t[k] = 0 end
|
||||
t[k] = t[k] + 1
|
||||
shm:write(SHM_JSON, EncodeJson(t))
|
||||
Unlock()
|
||||
end
|
||||
|
||||
-- this intercepts all requests if it's defined
|
||||
function OnHttpRequest()
|
||||
if GetHeader('User-Agent') then
|
||||
Log(kLogInfo, "client is running %s and reports %s" % {
|
||||
finger.GetSynFingerOs(finger.FingerSyn(syn)),
|
||||
VisualizeControlCodes(GetHeader('User-Agent'))})
|
||||
end
|
||||
if HasParam('magic') then
|
||||
Write('<p>\r\n')
|
||||
Write('OnHttpRequest() has intercepted your request<br>\r\n')
|
||||
Write('because you specified the magic parameter\r\n')
|
||||
Write('<pre>\r\n')
|
||||
Write(EscapeHtml(LoadAsset('/.init.lua')))
|
||||
Write('</pre>\r\n')
|
||||
else
|
||||
Route() -- this asks redbean to do the default thing
|
||||
end
|
||||
SetHeader('Server', 'redbean!')
|
||||
UpdateHitCounter()
|
||||
if GetHeader('User-Agent') then
|
||||
Log(kLogInfo, "client is running %s and reports %s" % {
|
||||
finger.GetSynFingerOs(finger.FingerSyn(syn)),
|
||||
VisualizeControlCodes(GetHeader('User-Agent'))})
|
||||
end
|
||||
if HasParam('magic') then
|
||||
Write('<p>\r\n')
|
||||
Write('OnHttpRequest() has intercepted your request<br>\r\n')
|
||||
Write('because you specified the magic parameter\r\n')
|
||||
Write('<pre>\r\n')
|
||||
Write(EscapeHtml(LoadAsset('/.init.lua')))
|
||||
Write('</pre>\r\n')
|
||||
else
|
||||
Route() -- this asks redbean to do the default thing
|
||||
end
|
||||
SetHeader('Server', 'redbean!')
|
||||
end
|
||||
|
||||
function Adder(x, y)
|
||||
return x + y
|
||||
return x + y
|
||||
end
|
||||
|
|
35
tool/net/demo/hitcounter.lua
Normal file
35
tool/net/demo/hitcounter.lua
Normal file
|
@ -0,0 +1,35 @@
|
|||
Write([[<!doctype html>
|
||||
<title>redbean mapshared demo</title>
|
||||
<style>
|
||||
body { padding: 1em; }
|
||||
h1 a { color: inherit; text-decoration: none; }
|
||||
h1 img { border: none; vertical-align: middle; }
|
||||
input { margin: 1em; padding: .5em; }
|
||||
pre { margin-left: 2em; }
|
||||
p { word-break: break-word; max-width: 650px; }
|
||||
dt { font-weight: bold; }
|
||||
dd { margin-top: 1em; margin-bottom: 1em; }
|
||||
.hdr { text-indent: -1em; padding-left: 1em; }
|
||||
</style>
|
||||
<h1>
|
||||
<a href="/"><img src="/redbean.png"></a>
|
||||
<a href="fetch.lua">redbean mapshared demo</a>
|
||||
</h1>
|
||||
<p>
|
||||
This page displays a <code>unix.mapshared()</code> hit counter of
|
||||
the <code>GetPath()</code>.
|
||||
</p>
|
||||
<dl>
|
||||
]])
|
||||
|
||||
Lock()
|
||||
s = shm:read(SHM_JSON)
|
||||
if s == '' then s = '{}' end
|
||||
t = DecodeJson(s)
|
||||
Unlock()
|
||||
|
||||
for k,v in pairs(t) do
|
||||
Write('<dt>%s<dd>%d\n' % {EscapeHtml(k), v})
|
||||
end
|
||||
|
||||
Write('</dl>')
|
Loading…
Add table
Add a link
Reference in a new issue