Compare commits
103 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
84d7d0812e | 7 months ago |
|
|
b171f13fe9 | 7 months ago |
|
|
fafe11f9c8 | 7 months ago |
|
|
d7812eabad | 2 years ago |
|
|
9588c05348 | 2 years ago |
|
|
fba94951bc | 2 years ago |
|
|
b9d5000b9d | 10 years ago |
|
|
33326d61e4 | 10 years ago |
|
|
79d0c5f9fd | 10 years ago |
|
|
4db6fc29aa | 10 years ago |
|
|
0052cbd0dc | 10 years ago |
|
|
818a28e202 | 10 years ago |
|
|
9bb3bd4bf4 | 10 years ago |
|
|
8d8be64a01 | 10 years ago |
|
|
dbe3acabcf | 10 years ago |
|
|
19c277008e | 10 years ago |
|
|
601ea38a91 | 10 years ago |
|
|
226976543c | 10 years ago |
|
|
7f9e341773 | 10 years ago |
|
|
8063d6dc63 | 10 years ago |
|
|
d5ef59d67c | 10 years ago |
|
|
0be2975f7a | 10 years ago |
|
|
b861158ec6 | 12 years ago |
|
|
a335ef0625 | 12 years ago |
|
|
327583c0f6 | 12 years ago |
|
|
e47f0a9a31 | 12 years ago |
|
|
66ef76c795 | 12 years ago |
|
|
1d6ed5cc3f | 13 years ago |
|
|
ca95905b7a | 13 years ago |
|
|
417ffd7f46 | 13 years ago |
|
|
325b5874d1 | 13 years ago |
|
|
def9da8920 | 13 years ago |
|
|
18101b0f05 | 13 years ago |
|
|
8f7dda3147 | 13 years ago |
|
|
3499ee79ae | 13 years ago |
|
|
b0413d4e75 | 13 years ago |
|
|
16505b546f | 13 years ago |
|
|
d934a9cbb1 | 13 years ago |
|
|
0708142d72 | 13 years ago |
|
|
24e50ebd04 | 13 years ago |
|
|
4038c4f92f | 13 years ago |
|
|
070e985098 | 13 years ago |
|
|
bf0c221ac0 | 13 years ago |
|
|
37960ae7c6 | 13 years ago |
|
|
b9e2ad3ea1 | 13 years ago |
|
|
8d962b4ac9 | 13 years ago |
|
|
214e2601cf | 13 years ago |
|
|
8f239ff6f5 | 13 years ago |
|
|
cbfaecd38c | 13 years ago |
|
|
f83cacde52 | 13 years ago |
|
|
58f6c5db3c | 14 years ago |
|
|
6845eba8d2 | 14 years ago |
|
|
8eaceefab3 | 14 years ago |
|
|
9841573893 | 14 years ago |
|
|
4642135e12 | 14 years ago |
|
|
32ea196579 | 14 years ago |
|
|
466e78aad1 | 14 years ago |
|
|
b5e03e5d16 | 14 years ago |
|
|
ce2d1c7c5a | 14 years ago |
|
|
dc1e7b80d0 | 14 years ago |
|
|
46ae68fe9e | 14 years ago |
|
|
b043c7631f | 14 years ago |
|
|
8411d346c9 | 14 years ago |
|
|
2785eda10e | 14 years ago |
|
|
211a569a15 | 14 years ago |
|
|
4d23290e3a | 14 years ago |
|
|
a9630265f1 | 14 years ago |
|
|
105925e3d0 | 14 years ago |
|
|
c5087a2d91 | 14 years ago |
|
|
78ac082f62 | 14 years ago |
|
|
df6157eb37 | 14 years ago |
|
|
2adc7dfbc2 | 14 years ago |
|
|
a74cf52c11 | 14 years ago |
|
|
5e6a7b5363 | 14 years ago |
|
|
3b93a80233 | 14 years ago |
|
|
a598995e33 | 14 years ago |
|
|
0697debefb | 14 years ago |
|
|
caba791908 | 14 years ago |
|
|
bbaa86a552 | 14 years ago |
|
|
5f8ae64393 | 14 years ago |
|
|
81f1182507 | 14 years ago |
|
|
421101376e | 14 years ago |
|
|
6ee18ea74d | 14 years ago |
|
|
3058dce215 | 14 years ago |
|
|
0aa2ed8e3f | 14 years ago |
|
|
36374c33fe | 14 years ago |
|
|
36fa3226ef | 14 years ago |
|
|
b2aec4654e | 14 years ago |
|
|
715f531f52 | 14 years ago |
|
|
779a406957 | 14 years ago |
|
|
8d780628a0 | 14 years ago |
|
|
7de39bd409 | 14 years ago |
|
|
7adc63d089 | 14 years ago |
|
|
38a3f21ba5 | 14 years ago |
|
|
a58d7ad389 | 14 years ago |
|
|
04208f1059 | 14 years ago |
|
|
f50970f7a1 | 14 years ago |
|
|
a9b9ca278a | 14 years ago |
|
|
e8229c5b55 | 15 years ago |
|
|
34e19cb65c | 15 years ago |
|
|
8200e8f54a | 15 years ago |
|
|
f0fd8edddc | 15 years ago |
|
|
a264b26c48 | 15 years ago |
@ -0,0 +1,68 @@
|
||||
language: c
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- LUA=lua5.1 LIBLUA=liblua5.1-dev LUA_INCDIR=/usr/include/lua5.1 LUA_LIB=lua5.1
|
||||
- LUA=lua5.2 LIBLUA=liblua5.2-dev LUA_INCDIR=/usr/include/lua5.2 LUA_LIB=lua5.2
|
||||
- LUA=luajit LIBLUA=libluajit-5.1-dev LUA_INCDIR=/usr/include/luajit-2.0 LUA_LIB=luajit-5.1
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
|
||||
before_install:
|
||||
- if [ $LUA = "luajit" ]; then
|
||||
sudo add-apt-repository ppa:mwild1/ppa -y && sudo apt-get update -y;
|
||||
fi
|
||||
|
||||
install:
|
||||
- sudo apt-get install libzmq3-dev -y
|
||||
- sudo apt-get install $LUA -y
|
||||
- sudo apt-get install $LIBLUA -y
|
||||
- LUA_LIBDIR=`pkg-config $LUA --variable=libdir`
|
||||
- INSTALL_LMOD=`pkg-config $LUA --variable=INSTALL_LMOD`
|
||||
- INSTALL_CMOD=`pkg-config $LUA --variable=INSTALL_CMOD`
|
||||
## make sure there is a 'lua' command.
|
||||
- if [ ! -x /usr/bin/lua ]; then
|
||||
sudo ln -s `which $LUA` /usr/bin/lua;
|
||||
fi
|
||||
## install lua-llthreads
|
||||
- git clone git://github.com/Neopallium/lua-llthreads.git
|
||||
- cd lua-llthreads ; mkdir build ; cd build
|
||||
- cmake .. -DLUA_LIBRARIES=$LUA_LIBDIR -DLUA_INCLUDE_DIR=$LUA_INCDIR
|
||||
-DINSTALL_LMOD=$INSTALL_LMOD -DINSTALL_CMOD=$INSTALL_CMOD
|
||||
- make
|
||||
- sudo make install
|
||||
- cd ../..
|
||||
|
||||
script:
|
||||
#### build using pre-generated bindings.
|
||||
- mkdir build; cd build
|
||||
- cmake .. -DLUA_LIBRARIES=$LUA_LIBDIR -DLUA_INCLUDE_DIR=$LUA_INCDIR
|
||||
-DINSTALL_LMOD=$INSTALL_LMOD -DINSTALL_CMOD=$INSTALL_CMOD
|
||||
- make
|
||||
- sudo make install
|
||||
# Run tests.
|
||||
- $LUA ../tests/test_inproc.lua
|
||||
- $LUA ../perf/thread_lat.lua 1 1000
|
||||
- cd .. ; rm -rf build
|
||||
#### Re-Generate bindings.
|
||||
- git clone git://github.com/Neopallium/LuaNativeObjects.git;
|
||||
- mkdir build; cd build
|
||||
- cmake .. -DLUA_LIBRARIES=$LUA_LIBDIR -DLUA_INCLUDE_DIR=$LUA_INCDIR
|
||||
-DLUA_NATIVE_OBJECTS_PATH=$TRAVIS_BUILD_DIR/LuaNativeObjects
|
||||
-DUSE_PRE_GENERATED_BINDINGS=OFF -DGENERATE_LUADOCS=OFF
|
||||
-DINSTALL_LMOD=$INSTALL_LMOD -DINSTALL_CMOD=$INSTALL_CMOD
|
||||
- make
|
||||
- sudo make install
|
||||
# Run tests.
|
||||
- $LUA ../tests/test_inproc.lua
|
||||
- $LUA ../perf/thread_lat.lua 1 1000
|
||||
|
||||
notifications:
|
||||
email:
|
||||
on_failure: always
|
||||
on_success: change
|
||||
@ -0,0 +1,13 @@
|
||||
To re-generating the bindings
|
||||
-----------------------------
|
||||
|
||||
You will need to install LuaNativeObjects and set the CMake variable `USE_PRE_GENERATED_BINDINGS` to FALSE.
|
||||
By default CMake will use the pre-generated bindings that are include in the project.
|
||||
|
||||
Build Dependencies
|
||||
------------------
|
||||
|
||||
Optional dependency for re-generating Lua bindings from `*.nobj.lua` files:
|
||||
|
||||
* [LuaNativeObjects](https://github.com/Neopallium/LuaNativeObjects), this is the bindings generator used to convert the `*.nobj.lua` files into a native Lua module.
|
||||
|
||||
@ -0,0 +1,108 @@
|
||||
-- Copyright (c) 2012 Robert G. Jakabosky <bobby@sharedrealm.com>
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
|
||||
local poller = require"examples.poller"
|
||||
local poll = poller.new()
|
||||
|
||||
local zmq = require"zmq"
|
||||
local z_NOBLOCK = zmq.NOBLOCK
|
||||
local z_EVENTS = zmq.EVENTS
|
||||
local z_POLLIN = zmq.POLLIN
|
||||
local z_POLLOUT = zmq.POLLOUT
|
||||
local z_POLLIN_OUT = z_POLLIN + z_POLLOUT
|
||||
|
||||
local N=tonumber(arg[1] or 100)
|
||||
|
||||
local ctx = zmq.init()
|
||||
local s = ctx:socket(zmq.REQ)
|
||||
local s_FD = s:getopt(zmq.FD)
|
||||
|
||||
s:connect("tcp://localhost:5555")
|
||||
|
||||
-- current socket state
|
||||
local blocked_state
|
||||
local blocked_event
|
||||
local on_sock_recv
|
||||
local on_sock_send
|
||||
|
||||
-- IO event callback when socket was blocked
|
||||
local function on_sock_io()
|
||||
local events = s:getopt(z_EVENTS)
|
||||
local unblocked = false
|
||||
if events == blocked_event then
|
||||
-- got the event the socket was blocked on.
|
||||
unblocked = true
|
||||
elseif events == z_POLLIN_OUT then
|
||||
-- got both in & out events
|
||||
unblocked = true
|
||||
end
|
||||
if unblocked then
|
||||
-- got the event we are blocked on resume.
|
||||
blocked_event = nil
|
||||
blocked_state()
|
||||
-- check if blocked event was processed.
|
||||
if not blocked_event then
|
||||
poll:remove_read(s_FD)
|
||||
end
|
||||
end
|
||||
end
|
||||
local function sock_blocked(state, event)
|
||||
if not blocked_event then
|
||||
-- need to register socket's fd with event loop
|
||||
poll:add_read(s_FD, on_sock_io)
|
||||
end
|
||||
blocked_state = state
|
||||
blocked_event = event
|
||||
end
|
||||
|
||||
-- sock state functions
|
||||
function on_sock_send()
|
||||
N = N - 1
|
||||
if N == 0 then
|
||||
return poll:stop()
|
||||
end
|
||||
local sent, err = s:send("SELECT * FROM mytable", z_NOBLOCK)
|
||||
if not sent then
|
||||
assert(err == 'timeout', "Bad error on zmq socket.")
|
||||
return sock_blocked(on_sock_send, z_POLLOUT)
|
||||
end
|
||||
-- yield back to event loop
|
||||
poll:add_work(on_sock_recv)
|
||||
end
|
||||
|
||||
function on_sock_recv()
|
||||
local data, err = s:recv(z_NOBLOCK)
|
||||
if not data then
|
||||
assert(err == 'timeout', "Bad error on zmq socket.")
|
||||
return sock_blocked(on_sock_recv, z_POLLIN)
|
||||
end
|
||||
print(data)
|
||||
return on_sock_send()
|
||||
end
|
||||
|
||||
-- start processing of the socket.
|
||||
poll:add_work(on_sock_send)
|
||||
|
||||
-- start event loop
|
||||
poll:start()
|
||||
|
||||
s:close()
|
||||
ctx:term()
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
local zmq = require'zmq'
|
||||
local poller = require"examples.poller"
|
||||
local poll_zsock = require"examples.poll_zsock"
|
||||
|
||||
local poll = poller.new()
|
||||
poll_zsock.set_poller(poll)
|
||||
|
||||
local c = zmq.init(1)
|
||||
local xreq = poll_zsock(c:socket(zmq.XREQ))
|
||||
xreq:bind('tcp://127.0.0.1:13333')
|
||||
local xrep = poll_zsock(c:socket(zmq.XREP))
|
||||
xrep:bind('tcp://127.0.0.1:13334')
|
||||
|
||||
local max_recv = 10
|
||||
|
||||
local function forward_io(src,dst)
|
||||
src.on_data = function()
|
||||
for i=1,max_recv do
|
||||
repeat
|
||||
local data, err = src:recv(zmq.NOBLOCK)
|
||||
if not data then
|
||||
if err == 'timeout' then
|
||||
return
|
||||
else
|
||||
error("socket recv error:" .. err)
|
||||
end
|
||||
end
|
||||
local more = src:getopt(zmq.RCVMORE) > 0
|
||||
dst:send(data,more and zmq.SNDMORE or 0)
|
||||
until not more
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
forward_io(xrep,xreq)
|
||||
forward_io(xreq,xrep)
|
||||
|
||||
poll:start()
|
||||
|
||||
@ -0,0 +1,177 @@
|
||||
-- Copyright (c) 2012 Robert G. Jakabosky <bobby@sharedrealm.com>
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
|
||||
local zmq = require"zmq"
|
||||
|
||||
local z_EVENTS = zmq.EVENTS
|
||||
|
||||
local z_POLLIN = zmq.POLLIN
|
||||
local z_POLLOUT = zmq.POLLOUT
|
||||
local z_POLLIN_OUT = z_POLLIN + z_POLLOUT
|
||||
|
||||
local poll
|
||||
|
||||
local meths = {}
|
||||
local zsock_mt = { __index=meths }
|
||||
|
||||
local function zsock_check_events(self)
|
||||
if not self.check_enabled then
|
||||
-- enable 'on_work' callback to handle checking for socket events.
|
||||
self.check_enabled = true
|
||||
poll:add_work(self.on_work)
|
||||
end
|
||||
end
|
||||
|
||||
function meths:events()
|
||||
zsock_check_events(self)
|
||||
return self.sock:events()
|
||||
end
|
||||
|
||||
function meths:getopt(opt)
|
||||
if (opt == z_EVENTS) then
|
||||
zsock_check_events(self)
|
||||
end
|
||||
return self.sock:getopt(opt)
|
||||
end
|
||||
|
||||
function meths:setopt(opt,val)
|
||||
return self.sock:setopt(opt,val)
|
||||
end
|
||||
|
||||
function meths:sub(topic)
|
||||
return self.sock:sub(topic)
|
||||
end
|
||||
|
||||
function meths:unsub(topic)
|
||||
return self.sock:unsub(topic)
|
||||
end
|
||||
|
||||
function meths:identity(id)
|
||||
return self.sock:identity(id)
|
||||
end
|
||||
|
||||
function meths:bind(addr)
|
||||
return self.sock:bind(addr)
|
||||
end
|
||||
|
||||
function meths:connect(addr)
|
||||
return self.sock:connect(addr)
|
||||
end
|
||||
|
||||
function meths:close()
|
||||
return self.sock:close()
|
||||
end
|
||||
|
||||
function meths:send(msg, flags)
|
||||
zsock_check_events(self)
|
||||
local sent, err = self.sock:send(msg, flags)
|
||||
if not sent and err == 'timeout' then
|
||||
self.send_blocked = true
|
||||
end
|
||||
return sent, err
|
||||
end
|
||||
|
||||
function meths:send_msg(msg, flags)
|
||||
zsock_check_events(self)
|
||||
local sent, err = self.sock:send_msg(msg, flags)
|
||||
if not sent and err == 'timeout' then
|
||||
self.send_blocked = true
|
||||
end
|
||||
return sent, err
|
||||
end
|
||||
|
||||
function meths:recv(flags)
|
||||
zsock_check_events(self)
|
||||
local msg, err = self.sock:recv(flags)
|
||||
if not msg and err == 'timeout' then
|
||||
self.recv_blocked = true
|
||||
end
|
||||
return msg, err
|
||||
end
|
||||
|
||||
function meths:recv_msg(msg, flags)
|
||||
zsock_check_events(self)
|
||||
local stat, err = self.sock:recv_msg(msg, flags)
|
||||
if not stat and err == 'timeout' then
|
||||
self.recv_blocked = true
|
||||
end
|
||||
return stat, err
|
||||
end
|
||||
|
||||
local function nil_cb()
|
||||
end
|
||||
|
||||
local function wrap_zsock(sock, on_data, on_drain)
|
||||
local self = setmetatable({
|
||||
sock = sock,
|
||||
on_data = on_data or nil_cb,
|
||||
on_drain = on_drain or nil_cb,
|
||||
recv_blocked = false,
|
||||
send_blocked = false,
|
||||
check_enabled = false,
|
||||
}, zsock_mt)
|
||||
|
||||
local function on_work()
|
||||
self.check_enabled = false
|
||||
local events = sock:events()
|
||||
local read = false
|
||||
local write = false
|
||||
if events == z_POLLIN_OUT then
|
||||
read = true
|
||||
write = true
|
||||
elseif events == z_POLLIN then
|
||||
read = true
|
||||
elseif events == z_POLLOUT then
|
||||
write = true
|
||||
else
|
||||
return
|
||||
end
|
||||
if read then
|
||||
self.recv_blocked = false
|
||||
self:on_data(sock)
|
||||
-- there might be more messages to read.
|
||||
if not self.recv_blocked then
|
||||
zsock_check_events(self)
|
||||
end
|
||||
end
|
||||
if write and self.send_blocked then
|
||||
self:on_drain(sock)
|
||||
end
|
||||
end
|
||||
self.on_work = on_work
|
||||
|
||||
-- listen for read events to enable socket.
|
||||
poll:add_read(sock:fd(), function()
|
||||
on_work()
|
||||
end)
|
||||
|
||||
zsock_check_events(self)
|
||||
return self
|
||||
end
|
||||
|
||||
return setmetatable({
|
||||
set_poller = function(poller)
|
||||
local old = poll
|
||||
poll = poller
|
||||
return old
|
||||
end,
|
||||
wrap_zsock = wrap_zsock,
|
||||
}, { __call = function(tab, ...) return wrap_zsock(...) end})
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
-- Copyright (c) 2012 Robert G. Jakabosky <bobby@sharedrealm.com>
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
|
||||
-- safe require.
|
||||
local require = require
|
||||
local function safe_require(...)
|
||||
return pcall(require, ...)
|
||||
end
|
||||
|
||||
local mod_name = ...
|
||||
|
||||
local backends = {
|
||||
"epoll",
|
||||
"ev",
|
||||
}
|
||||
|
||||
for i=1,#backends do
|
||||
local backend = backends[i]
|
||||
local name = mod_name .. '.' .. backend
|
||||
local status, mod = safe_require(name)
|
||||
if status then
|
||||
--print("Loaded backend:", name)
|
||||
return mod
|
||||
end
|
||||
end
|
||||
|
||||
error("Failed to load backend for: " .. mod_name)
|
||||
|
||||
@ -0,0 +1,121 @@
|
||||
-- Copyright (c) 2012 Robert G. Jakabosky <bobby@sharedrealm.com>
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
|
||||
local epoll = require"epoll"
|
||||
local EPOLLIN = epoll.EPOLLIN
|
||||
local EPOLLOUT = epoll.EPOLLOUT
|
||||
|
||||
local poller_meths = {}
|
||||
local poller_mt = {__index = poller_meths}
|
||||
|
||||
local function poller_new()
|
||||
local reads = {}
|
||||
-- create closure for epoll io_event callback.
|
||||
local function do_io_event(fd, ev)
|
||||
local cb = reads[fd]
|
||||
return cb(fd, ev)
|
||||
end
|
||||
|
||||
return setmetatable({
|
||||
work_cur = {},
|
||||
work_last = {},
|
||||
reads = reads,
|
||||
io_events = 0,
|
||||
do_io_event = do_io_event,
|
||||
poller = epoll.new(),
|
||||
}, poller_mt)
|
||||
end
|
||||
|
||||
function poller_meths:add_work(task)
|
||||
-- add task to current work queue.
|
||||
self.work_cur[#self.work_cur + 1] = task
|
||||
end
|
||||
|
||||
function poller_meths:add_read(fd, cb)
|
||||
-- make sure read event hasn't been registered yet.
|
||||
if not self.reads[fd] then
|
||||
self.io_events = self.io_events + 1
|
||||
self.reads[fd] = cb
|
||||
return self.poller:add(fd, EPOLLIN, fd)
|
||||
else
|
||||
-- update read callback?
|
||||
self.reads[fd] = cb
|
||||
end
|
||||
end
|
||||
|
||||
function poller_meths:remove_read(fd)
|
||||
-- make sure there was a read event registered.
|
||||
if self.reads[fd] then
|
||||
self.io_events = self.io_events - 1
|
||||
self.reads[fd] = nil
|
||||
return self.poller:del(fd)
|
||||
end
|
||||
end
|
||||
|
||||
local function poller_do_work(self)
|
||||
local tasks = #self.work_cur
|
||||
-- check if there is any work
|
||||
if tasks > 0 then
|
||||
-- swap work queues.
|
||||
local last, cur = self.work_cur, self.work_last
|
||||
self.work_cur, self.work_last = cur, last
|
||||
for i=1,tasks do
|
||||
local task = last[i]
|
||||
last[i] = nil
|
||||
task()
|
||||
end
|
||||
-- return new work queue length.
|
||||
return #cur
|
||||
end
|
||||
return tasks
|
||||
end
|
||||
|
||||
function poller_meths:start()
|
||||
local do_io_event = self.do_io_event
|
||||
local poller = self.poller
|
||||
self.is_running = true
|
||||
while self.is_running do
|
||||
-- run work task
|
||||
local new_work = poller_do_work(self)
|
||||
-- wait == 0, if there is work to do, else wait == -1
|
||||
local wait = (new_work > 0) and 0 or -1
|
||||
-- poll for fd events, if there are events to poll for.
|
||||
--print("poller:step()", new_work, self.io_events)
|
||||
if self.io_events > 0 then
|
||||
assert(poller:wait_callback(do_io_event, wait))
|
||||
else
|
||||
-- no io events to poll, do we still have work?
|
||||
if #self.work_cur == 0 then
|
||||
-- nothing to do, exit event loop
|
||||
self.is_running = false
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function poller_meths:stop()
|
||||
self.is_running = false
|
||||
end
|
||||
|
||||
-- module only exports a 'new' function.
|
||||
return {
|
||||
new = poller_new,
|
||||
}
|
||||
@ -0,0 +1,119 @@
|
||||
-- Copyright (c) 2012 Robert G. Jakabosky <bobby@sharedrealm.com>
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
|
||||
local ev = require'ev'
|
||||
local ev_READ = ev.READ
|
||||
local ev_WRITE = ev.WRITE
|
||||
local loop = ev.Loop.default
|
||||
|
||||
assert(ev.Idle,"Need version > 1.3 of lua-ev that supports Idle watchers.")
|
||||
|
||||
local poller_meths = {}
|
||||
local poller_mt = {__index = poller_meths}
|
||||
|
||||
local function poller_new()
|
||||
local self = {
|
||||
work_cur = {},
|
||||
work_last = {},
|
||||
io_events = 0,
|
||||
reads = {},
|
||||
idle_enabled = false,
|
||||
}
|
||||
|
||||
self.idle = ev.Idle.new(function()
|
||||
local tasks = #self.work_cur
|
||||
-- check if there is any work
|
||||
if tasks > 0 then
|
||||
-- swap work queues.
|
||||
local last, cur = self.work_cur, self.work_last
|
||||
self.work_cur, self.work_last = cur, last
|
||||
for i=1,tasks do
|
||||
local task = last[i]
|
||||
last[i] = nil
|
||||
task()
|
||||
end
|
||||
-- check if there is more work.
|
||||
if #cur > 0 then
|
||||
return -- don't disable idle watcher, when we have work.
|
||||
end
|
||||
end
|
||||
--print("STOP IDLE:", #self.work_cur, #self.work_last)
|
||||
-- stop idle watcher, no work.
|
||||
self.idle_enabled = false
|
||||
self.idle:stop(loop)
|
||||
end)
|
||||
-- set priority to max, to make sure the work queue is processed on each loop.
|
||||
self.idle:priority(ev.MAXPRI)
|
||||
|
||||
return setmetatable(self, poller_mt)
|
||||
end
|
||||
|
||||
function poller_meths:add_work(task)
|
||||
local idx = #self.work_cur + 1
|
||||
-- add task to current work queue.
|
||||
self.work_cur[idx] = task
|
||||
-- make sure the idle watcher is enabled.
|
||||
if not self.idle_enabled then
|
||||
self.idle_enabled = true
|
||||
self.idle:start(loop)
|
||||
end
|
||||
end
|
||||
|
||||
function poller_meths:add_read(fd, cb)
|
||||
local io_read = self.reads[fd]
|
||||
-- make sure read event hasn't been registered yet.
|
||||
if not io_read then
|
||||
self.io_events = self.io_events + 1
|
||||
io_read = ev.IO.new(function()
|
||||
cb(fd)
|
||||
end, fd, ev_READ)
|
||||
self.reads[fd] = io_read
|
||||
io_read:start(loop)
|
||||
else
|
||||
-- update read callback?
|
||||
io_read:callback(cb)
|
||||
-- need to re-start watcher?
|
||||
if not io_read:is_active() then
|
||||
io_read:start(loop)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function poller_meths:remove_read(fd)
|
||||
local io_read = self.reads[fd]
|
||||
-- make sure there was a read event registered.
|
||||
if io_read then
|
||||
self.io_events = self.io_events - 1
|
||||
io_read:stop(loop)
|
||||
end
|
||||
end
|
||||
|
||||
function poller_meths:start()
|
||||
return loop:loop()
|
||||
end
|
||||
|
||||
function poller_meths:stop()
|
||||
return loop:unloop()
|
||||
end
|
||||
|
||||
-- module only exports a 'new' function.
|
||||
return {
|
||||
new = poller_new,
|
||||
}
|
||||
@ -0,0 +1,95 @@
|
||||
-- Copyright (c) 2012 Robert G. Jakabosky <bobby@sharedrealm.com>
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
|
||||
local poller = require"examples.poller"
|
||||
local poll = poller.new()
|
||||
|
||||
local zmq = require"zmq"
|
||||
local z_NOBLOCK = zmq.NOBLOCK
|
||||
local z_EVENTS = zmq.EVENTS
|
||||
local z_POLLIN = zmq.POLLIN
|
||||
local z_POLLOUT = zmq.POLLOUT
|
||||
local z_POLLIN_OUT = z_POLLIN + z_POLLOUT
|
||||
|
||||
local ctx = zmq.init()
|
||||
local s = ctx:socket(zmq.PUB)
|
||||
local s_FD = s:getopt(zmq.FD)
|
||||
|
||||
s:bind("tcp://lo:5555")
|
||||
|
||||
-- current socket state
|
||||
local blocked_state
|
||||
local blocked_event
|
||||
local on_sock_recv
|
||||
local on_sock_send
|
||||
|
||||
-- IO event callback when socket was blocked
|
||||
local function on_sock_io()
|
||||
local events = s:getopt(z_EVENTS)
|
||||
local unblocked = false
|
||||
if events == blocked_event then
|
||||
-- got the event the socket was blocked on.
|
||||
unblocked = true
|
||||
elseif events == z_POLLIN_OUT then
|
||||
-- got both in & out events
|
||||
unblocked = true
|
||||
end
|
||||
if unblocked then
|
||||
-- got the event we are blocked on resume.
|
||||
blocked_event = nil
|
||||
blocked_state()
|
||||
-- check if blocked event was processed.
|
||||
if not blocked_event then
|
||||
poll:remove_read(s_FD)
|
||||
end
|
||||
end
|
||||
end
|
||||
local function sock_blocked(state, event)
|
||||
if not blocked_event then
|
||||
-- need to register socket's fd with event loop
|
||||
poll:add_read(s_FD, on_sock_io)
|
||||
end
|
||||
blocked_state = state
|
||||
blocked_event = event
|
||||
end
|
||||
|
||||
-- sock state functions
|
||||
local msg_id = 1
|
||||
function on_sock_send()
|
||||
local sent, err = s:send(tostring(msg_id), z_NOBLOCK)
|
||||
if not sent then
|
||||
assert(err == 'timeout', "Bad error on zmq socket.")
|
||||
return sock_blocked(on_sock_send, z_POLLOUT)
|
||||
end
|
||||
-- message sent, inc. id
|
||||
msg_id = msg_id + 1
|
||||
-- yield back to event loop
|
||||
poll:add_work(on_sock_send)
|
||||
end
|
||||
|
||||
-- start processing of the socket.
|
||||
poll:add_work(on_sock_send)
|
||||
|
||||
-- start event loop
|
||||
poll:start()
|
||||
|
||||
s:close()
|
||||
ctx:term()
|
||||
|
||||
@ -0,0 +1,102 @@
|
||||
-- Copyright (c) 2012 Robert G. Jakabosky <bobby@sharedrealm.com>
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
|
||||
local poller = require"examples.poller"
|
||||
local poll = poller.new()
|
||||
|
||||
local zmq = require"zmq"
|
||||
local z_NOBLOCK = zmq.NOBLOCK
|
||||
local z_EVENTS = zmq.EVENTS
|
||||
local z_POLLIN = zmq.POLLIN
|
||||
local z_POLLOUT = zmq.POLLOUT
|
||||
local z_POLLIN_OUT = z_POLLIN + z_POLLOUT
|
||||
|
||||
local ctx = zmq.init()
|
||||
local s = ctx:socket(zmq.REP)
|
||||
local s_FD = s:getopt(zmq.FD)
|
||||
|
||||
s:bind("tcp://lo:5555")
|
||||
|
||||
-- current socket state
|
||||
local blocked_state
|
||||
local blocked_event
|
||||
local on_sock_recv
|
||||
local on_sock_send
|
||||
|
||||
-- IO event callback when socket was blocked
|
||||
local function on_sock_io()
|
||||
local events = s:getopt(z_EVENTS)
|
||||
local unblocked = false
|
||||
if events == blocked_event then
|
||||
-- got the event the socket was blocked on.
|
||||
unblocked = true
|
||||
elseif events == z_POLLIN_OUT then
|
||||
-- got both in & out events
|
||||
unblocked = true
|
||||
end
|
||||
if unblocked then
|
||||
-- got the event we are blocked on resume.
|
||||
blocked_event = nil
|
||||
blocked_state()
|
||||
-- check if blocked event was processed.
|
||||
if not blocked_event then
|
||||
poll:remove_read(s_FD)
|
||||
end
|
||||
end
|
||||
end
|
||||
local function sock_blocked(state, event)
|
||||
if not blocked_event then
|
||||
-- need to register socket's fd with event loop
|
||||
poll:add_read(s_FD, on_sock_io)
|
||||
end
|
||||
blocked_state = state
|
||||
blocked_event = event
|
||||
end
|
||||
|
||||
-- sock state functions
|
||||
function on_sock_recv()
|
||||
local data, err = s:recv(z_NOBLOCK)
|
||||
if not data then
|
||||
assert(err == 'timeout', "Bad error on zmq socket.")
|
||||
return sock_blocked(on_sock_recv, z_POLLIN)
|
||||
end
|
||||
print(string.format("Received query: '%s'", data))
|
||||
return on_sock_send()
|
||||
end
|
||||
|
||||
function on_sock_send()
|
||||
local sent, err = s:send("OK", z_NOBLOCK)
|
||||
if not sent then
|
||||
assert(err == 'timeout', "Bad error on zmq socket.")
|
||||
return sock_blocked(on_sock_send, z_POLLOUT)
|
||||
end
|
||||
-- yield back to event loop
|
||||
poll:add_work(on_sock_recv)
|
||||
end
|
||||
|
||||
-- start processing of the socket.
|
||||
poll:add_work(on_sock_recv)
|
||||
|
||||
-- start event loop
|
||||
poll:start()
|
||||
|
||||
s:close()
|
||||
ctx:term()
|
||||
|
||||
@ -0,0 +1,96 @@
|
||||
-- Copyright (c) 2012 Robert G. Jakabosky <bobby@sharedrealm.com>
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
|
||||
local poller = require"examples.poller"
|
||||
local poll = poller.new()
|
||||
|
||||
local zmq = require"zmq"
|
||||
local z_NOBLOCK = zmq.NOBLOCK
|
||||
local z_EVENTS = zmq.EVENTS
|
||||
local z_POLLIN = zmq.POLLIN
|
||||
local z_POLLOUT = zmq.POLLOUT
|
||||
local z_POLLIN_OUT = z_POLLIN + z_POLLOUT
|
||||
|
||||
local N=tonumber(arg[1] or 100)
|
||||
|
||||
local ctx = zmq.init()
|
||||
local s = ctx:socket(zmq.SUB)
|
||||
local s_FD = s:getopt(zmq.FD)
|
||||
|
||||
s:setopt(zmq.SUBSCRIBE, "")
|
||||
s:connect("tcp://localhost:5555")
|
||||
|
||||
-- current socket state
|
||||
local blocked_state
|
||||
local blocked_event
|
||||
local on_sock_recv
|
||||
local on_sock_send
|
||||
|
||||
-- IO event callback when socket was blocked
|
||||
local function on_sock_io()
|
||||
local events = s:getopt(z_EVENTS)
|
||||
local unblocked = false
|
||||
if events == blocked_event then
|
||||
-- got the event the socket was blocked on.
|
||||
unblocked = true
|
||||
elseif events == z_POLLIN_OUT then
|
||||
-- got both in & out events
|
||||
unblocked = true
|
||||
end
|
||||
if unblocked then
|
||||
-- got the event we are blocked on resume.
|
||||
blocked_event = nil
|
||||
blocked_state()
|
||||
-- check if blocked event was processed.
|
||||
if not blocked_event then
|
||||
poll:remove_read(s_FD)
|
||||
end
|
||||
end
|
||||
end
|
||||
local function sock_blocked(state, event)
|
||||
if not blocked_event then
|
||||
-- need to register socket's fd with event loop
|
||||
poll:add_read(s_FD, on_sock_io)
|
||||
end
|
||||
blocked_state = state
|
||||
blocked_event = event
|
||||
end
|
||||
|
||||
-- sock state functions
|
||||
function on_sock_recv()
|
||||
local data, err = s:recv(z_NOBLOCK)
|
||||
if not data then
|
||||
assert(err == 'timeout', "Bad error on zmq socket.")
|
||||
return sock_blocked(on_sock_recv, z_POLLIN)
|
||||
end
|
||||
local msg_id = tonumber(data)
|
||||
if (msg_id % 10000) == 0 then print(data) end
|
||||
return on_sock_recv()
|
||||
end
|
||||
|
||||
-- start processing of the socket.
|
||||
poll:add_work(on_sock_recv)
|
||||
|
||||
-- start event loop
|
||||
poll:start()
|
||||
|
||||
s:close()
|
||||
ctx:term()
|
||||
|
||||
@ -0,0 +1,77 @@
|
||||
-- Copyright (c) 2010 Aleksey Yeschenko <aleksey@yeschenko.com>
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
|
||||
if not arg[3] then
|
||||
print("usage: lua local_thr.lua <bind-to> <message-size> <message-count>")
|
||||
os.exit()
|
||||
end
|
||||
|
||||
local bind_to = arg[1]
|
||||
local message_size = tonumber(arg[2])
|
||||
local message_count = tonumber(arg[3])
|
||||
|
||||
local zmq = require"zmq"
|
||||
local z_poller = require"zmq.poller"
|
||||
local z_NOBLOCK = zmq.NOBLOCK
|
||||
|
||||
local poller = z_poller(64)
|
||||
|
||||
local ctx = zmq.init(1)
|
||||
local s = assert(ctx:socket(zmq.SUB))
|
||||
assert(s:setopt(zmq.SUBSCRIBE, ""))
|
||||
assert(s:bind(bind_to))
|
||||
|
||||
print(string.format("message size: %i [B]", message_size))
|
||||
print(string.format("message count: %i", message_count))
|
||||
|
||||
local msg
|
||||
msg = zmq.zmq_msg_t()
|
||||
|
||||
local cnt = 0
|
||||
|
||||
poller:add(s, zmq.POLLIN, function(sock)
|
||||
while s:recv_msg(msg, z_NOBLOCK) do
|
||||
--assert(msg:size() == message_size, "Invalid message size")
|
||||
cnt = cnt + 1
|
||||
if cnt == message_count then
|
||||
poller:stop()
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- wait for first message
|
||||
assert(s:recv_msg(msg))
|
||||
cnt = 1
|
||||
|
||||
local timer = zmq.stopwatch_start()
|
||||
poller:start()
|
||||
local elapsed = timer:stop()
|
||||
|
||||
s:close()
|
||||
ctx:term()
|
||||
|
||||
if elapsed == 0 then elapsed = 1 end
|
||||
|
||||
local throughput = message_count / (elapsed / 1000000)
|
||||
local megabits = throughput * message_size * 8 / 1000000
|
||||
|
||||
print(string.format("mean throughput: %i [msg/s]", throughput))
|
||||
print(string.format("mean throughput: %.3f [Mb/s]", megabits))
|
||||
|
||||
@ -0,0 +1,36 @@
|
||||
package = "lua-zmq"
|
||||
version = "1.2-1"
|
||||
source = {
|
||||
url = "git://github.com/Neopallium/lua-zmq.git",
|
||||
branch = "v1.2",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua bindings to zeromq2, with LuaJIT2 FFI support.",
|
||||
homepage = "http://github.com/Neopallium/lua-zmq",
|
||||
license = "MIT/X11",
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1, < 5.5",
|
||||
}
|
||||
external_dependencies = {
|
||||
ZEROMQ = {
|
||||
header = "zmq.h",
|
||||
library = "zmq",
|
||||
}
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
zmq = {
|
||||
sources = {"src/pre_generated-zmq.nobj.c"},
|
||||
incdirs = "$(ZEROMQ_INCDIR)",
|
||||
libdirs = "$(ZEROMQ_LIBDIR)",
|
||||
libraries = {"zmq"},
|
||||
},
|
||||
},
|
||||
install = {
|
||||
lua = {
|
||||
['zmq.poller'] = "src/poller.lua",
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
package = "lua-zmq"
|
||||
version = "scm-2"
|
||||
source = {
|
||||
url = "git://github.com/Neopallium/lua-zmq.git",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua bindings to zeromq2, with LuaJIT2 FFI support.",
|
||||
homepage = "http://github.com/Neopallium/lua-zmq",
|
||||
license = "MIT/X11",
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1, < 5.5",
|
||||
}
|
||||
external_dependencies = {
|
||||
platforms = {
|
||||
windows = {
|
||||
ZEROMQ = {
|
||||
library = "libzmq",
|
||||
}
|
||||
},
|
||||
},
|
||||
ZEROMQ = {
|
||||
header = "zmq.h",
|
||||
library = "zmq",
|
||||
}
|
||||
}
|
||||
build = {
|
||||
platforms = {
|
||||
windows = {
|
||||
modules = {
|
||||
zmq = {
|
||||
libraries = {"libzmq"},
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
type = "builtin",
|
||||
modules = {
|
||||
zmq = {
|
||||
sources = {"src/pre_generated-zmq.nobj.c"},
|
||||
incdirs = "$(ZEROMQ_INCDIR)",
|
||||
libdirs = "$(ZEROMQ_LIBDIR)",
|
||||
libraries = {"zmq"},
|
||||
},
|
||||
},
|
||||
install = {
|
||||
lua = {
|
||||
['zmq.poller'] = "src/poller.lua",
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package = "lua-zmq-threads"
|
||||
version = "1.2-1"
|
||||
source = {
|
||||
url = "git://github.com/Neopallium/lua-zmq.git",
|
||||
branch = "v1.2",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua bindings to zeromq2, with LuaJIT2 FFI support.",
|
||||
homepage = "http://github.com/Neopallium/lua-zmq",
|
||||
license = "MIT/X11"
|
||||
}
|
||||
dependencies = {
|
||||
"lua-zmq >= 1.2-1",
|
||||
"lua-llthreads >= 1.3-1",
|
||||
}
|
||||
build = {
|
||||
type = "none",
|
||||
install = {
|
||||
lua = {
|
||||
['zmq.threads'] = "src/threads.lua",
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,75 @@
|
||||
-- Copyright (c) 2011 Robert G. Jakabosky <bobby@sharedrealm.com>
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
-- THE SOFTWARE.
|
||||
|
||||
if #arg < 1 then
|
||||
print("usage: lua " .. arg[0] .. " [message-size] [roundtrip-count] [bind-to] [connect-to]")
|
||||
end
|
||||
|
||||
local message_size = tonumber(arg[1] or 1)
|
||||
local roundtrip_count = tonumber(arg[2] or 100)
|
||||
local bind_to = arg[3] or 'inproc://thread_lat_test'
|
||||
local connect_to = arg[4] or 'inproc://thread_lat_test'
|
||||
|
||||
local zmq = require"zmq"
|
||||
|
||||
local ctx = zmq.init(1)
|
||||
local server = assert(ctx:socket(zmq.REQ))
|
||||
assert(server:bind(bind_to))
|
||||
|
||||
local client = ctx:socket(zmq.REP)
|
||||
client:connect(connect_to)
|
||||
|
||||
local data = ("0"):rep(message_size)
|
||||
local msg = zmq.zmq_msg_t.init_size(message_size)
|
||||
local client_msg = zmq.zmq_msg_t()
|
||||
|
||||
print(string.format("message size: %i [B]", message_size))
|
||||
print(string.format("roundtrip count: %i", roundtrip_count))
|
||||
|
||||
local timer = zmq.stopwatch_start()
|
||||
|
||||
for i = 1, roundtrip_count do
|
||||
-- server send
|
||||
assert(server:send_msg(msg))
|
||||
|
||||
-- client recv
|
||||
assert(client:recv_msg(client_msg))
|
||||
assert(client_msg:size() == message_size, "Invalid message size")
|
||||
-- client send
|
||||
assert(client:send_msg(client_msg))
|
||||
|
||||
-- server recv
|
||||
assert(server:recv_msg(msg))
|
||||
assert(msg:size() == message_size, "Invalid message size")
|
||||
end
|
||||
|
||||
local elapsed = timer:stop()
|
||||
|
||||
server:close()
|
||||
client:close()
|
||||
ctx:term()
|
||||
|
||||
local latency = elapsed / roundtrip_count / 2
|
||||
|
||||
print(string.format("mean latency: %.3f [us]", latency))
|
||||
local secs = elapsed / (1000 * 1000)
|
||||
print(string.format("elapsed = %f", secs))
|
||||
print(string.format("msg/sec = %f", roundtrip_count / secs))
|
||||
|
||||
Loading…
Reference in New Issue