Software /
code /
prosody
Changeset
8781:53178b6ba589
net.server: Add watchfd, a simple API for watching file descriptors
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Wed, 09 May 2018 16:15:40 +0200 |
parents | 8780:4cab4ee5dfcc |
children | 8782:daa518a22c34 |
files | doc/net.server.lua net/server_epoll.lua net/server_event.lua net/server_select.lua |
diffstat | 4 files changed, 106 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/net.server.lua Mon May 07 22:10:29 2018 +0200 +++ b/doc/net.server.lua Wed May 09 16:15:40 2018 +0200 @@ -229,6 +229,18 @@ local function hook_signal(signal_id, handler) end +--[[ Adds a low-level FD watcher +Arguments: +- fd_number: A non-negative integer representing a file descriptor or + object with a :getfd() method returning one +- on_readable: Optional callback for when the FD is readable +- on_writable: Optional callback for when the FD is writable + +Returns: +- net.server handle +]] +local function watchfd(fd_number, on_readable, on_writable) +end return { get_backend = get_backend; @@ -240,4 +252,5 @@ addclient = addclient; closeall = closeall; hook_signal = hook_signal; + watchfd = watchfd; }
--- a/net/server_epoll.lua Mon May 07 22:10:29 2018 +0200 +++ b/net/server_epoll.lua Wed May 09 16:15:40 2018 +0200 @@ -15,6 +15,7 @@ local setmetatable = setmetatable; local tostring = tostring; local pcall = pcall; +local type = type; local next = next; local pairs = pairs; local log = require "util.logger".init("server_epoll"); @@ -586,6 +587,25 @@ return client, conn; end +local function watchfd(fd, onreadable, onwriteable) + local conn = setmetatable({ + conn = fd; + onreadable = onreadable; + onwriteable = onwriteable; + close = function (self) + self:setflags(false, false); + end + }, interface_mt); + if type(fd) == "number" then + conn.getfd = function () + return fd; + end; + -- Otherwise it'll need to be something LuaSocket-compatible + end + conn:setflags(onreadable, onwriteable); + return conn; +end; + -- Dump all data from one connection into another local function link(from, to) from.listeners = setmetatable({ @@ -663,6 +683,7 @@ closeall = closeall; setquitting = setquitting; wrapclient = wrapclient; + watchfd = watchfd; link = link; set_config = function (newconfig) cfg = setmetatable(newconfig, default_config);
--- a/net/server_event.lua Mon May 07 22:10:29 2018 +0200 +++ b/net/server_event.lua Wed May 09 16:15:40 2018 +0200 @@ -834,6 +834,34 @@ return event_handle; end +local function watchfd(fd, onreadable, onwriteable) + local handle = {}; + function handle:setflags(r,w) + if r ~= nil then + if r and not self.wantread then + self.wantread = base:addevent(fd, EV_READ, function () + onreadable(self); + end); + elseif not r and self.wantread then + self.wantread:close(); + self.wantread = nil; + end + end + if w ~= nil then + if w and not self.wantwrite then + self.wantwrite = base:addevent(fd, EV_WRITE, function () + onwriteable(self); + end); + elseif not r and self.wantread then + self.wantwrite:close(); + self.wantwrite = nil; + end + end + end + handle:setflags(onreadable, onwriteable); + return handle; +end + return { cfg = cfg, base = base, @@ -850,6 +878,7 @@ get_backend = get_backend, hook_signal = hook_signal, add_task = add_task, + watchfd = watchfd, __NAME = SCRIPT_NAME, __DATE = LAST_MODIFIED,
--- a/net/server_select.lua Mon May 07 22:10:29 2018 +0200 +++ b/net/server_select.lua Wed May 09 16:15:40 2018 +0200 @@ -1034,6 +1034,48 @@ end end +local closewatcher = function (handler) + local socket = handler.conn; + _sendlistlen = removesocket( _sendlist, socket, _sendlistlen ) + _readlistlen = removesocket( _readlist, socket, _readlistlen ) + _socketlist[ socket ] = nil +end; + +local addremove = function (handler, read, send) + local socket = handler.conn + _socketlist[ socket ] = handler + if read ~= nil then + if read then + _readlistlen = addsocket( _readlist, socket, _readlistlen ) + else + _sendlistlen = removesocket( _sendlist, socket, _sendlistlen ) + end + end + if send ~= nil then + if send then + _sendlistlen = addsocket( _sendlist, socket, _sendlistlen ) + else + _readlistlen = removesocket( _readlist, socket, _readlistlen ) + end + end +end + +local watchfd = function ( fd, onreadable, onwriteable ) + local socket = fd + if type(fd) == "number" then + socket = { getfd = function () return fd; end } + end + local handler = { + conn = socket; + readbuffer = onreadable or id; + sendbuffer = onwriteable or id; + close = closewatcher; + setflags = addremove; + }; + addremove( handler, onreadable, onwriteable ) + return handler +end + ----------------------------------// BEGIN //-- use "setmetatable" ( _socketlist, { __mode = "k" } ) @@ -1058,6 +1100,7 @@ addclient = addclient, wrapclient = wrapclient, + watchfd = watchfd, loop = loop, link = link,