Compare commits
No commits in common. 'master' and 'zmq3.0' have entirely different histories.
@ -1,68 +0,0 @@
|
|||||||
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
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
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.
|
|
||||||
|
|
||||||
@ -1,108 +0,0 @@
|
|||||||
-- 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()
|
|
||||||
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
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()
|
|
||||||
|
|
||||||
@ -1,177 +0,0 @@
|
|||||||
-- 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})
|
|
||||||
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
-- 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)
|
|
||||||
|
|
||||||
@ -1,121 +0,0 @@
|
|||||||
-- 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,
|
|
||||||
}
|
|
||||||
@ -1,119 +0,0 @@
|
|||||||
-- 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,
|
|
||||||
}
|
|
||||||
@ -1,95 +0,0 @@
|
|||||||
-- 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()
|
|
||||||
|
|
||||||
@ -1,102 +0,0 @@
|
|||||||
-- 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()
|
|
||||||
|
|
||||||
@ -1,96 +0,0 @@
|
|||||||
-- 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()
|
|
||||||
|
|
||||||
@ -1,77 +0,0 @@
|
|||||||
-- 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))
|
|
||||||
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
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",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
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",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
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
@ -1,75 +0,0 @@
|
|||||||
-- 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