net/server_epoll.lua
author Kim Alvefur <zash@zash.se>
Wed, 10 Aug 2016 16:57:16 +0200
changeset 7550 b327322ce2dd
child 7553 8c2bc1b6d84a
permissions -rw-r--r--
net.server_epoll: New experimental server backend
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7550
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     1
-- Prosody IM
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     2
-- Copyright (C) 2016 Kim Alvefur
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     3
--
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     4
-- This project is MIT/X11 licensed. Please see the
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     5
-- COPYING file in the source package for more information.
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     6
--
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     7
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     8
-- server_epoll
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     9
--  Server backend based on https://luarocks.org/modules/zash/lua-epoll
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    10
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    11
local t_sort = table.sort;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    12
local t_insert = table.insert;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    13
local t_remove = table.remove;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    14
local t_concat = table.concat;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    15
local setmetatable = setmetatable;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    16
local tostring = tostring;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    17
local log = require "util.logger".init("server_epoll");
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    18
local epoll = require "epoll";
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    19
local socket = require "socket";
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    20
local luasec = require "ssl";
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    21
local gettime = require "util.time".now;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    22
local createtable = require "util.table".create;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    23
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    24
local _ENV = nil;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    25
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    26
local cfg = {
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    27
	read_timeout = 900;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    28
	write_timeout = 7;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    29
	tcp_backlog = 128;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    30
	accept_retry_interval = 10;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    31
};
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    32
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    33
local fds = createtable(10, 0); -- FD -> conn
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    34
local timers = {};
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    35
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    36
local function noop() end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    37
local function closetimer(t)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    38
	t[1] = 0;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    39
	t[2] = noop;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    40
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    41
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    42
local resort_timers = false;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    43
local function at(time, f)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    44
	local timer = { time, f, close = closetimer };
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    45
	t_insert(timers, timer);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    46
	resort_timers = true;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    47
	return timer;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    48
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    49
local function addtimer(timeout, f)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    50
	return at(gettime() + timeout, f);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    51
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    52
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    53
local function runtimers()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    54
	if resort_timers then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    55
		-- Sort earliest timers to the end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    56
		t_sort(timers, function (a, b) return a[1] > b[1]; end);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    57
		resort_timers = false;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    58
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    59
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    60
	--[[ Is it worth it to skip the noop calls?
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    61
	for i = #timers, 1, -1 do
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    62
		if timers[i][2] == noop then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    63
			timers[i] = nil;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    64
		else
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    65
			break;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    66
		end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    67
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    68
	--]]
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    69
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    70
	local next_delay = 86400;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    71
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    72
	-- Iterate from the end and remove completed timers
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    73
	for i = #timers, 1, -1 do
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    74
		local timer = timers[i];
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    75
		local t, f = timer[1], timer[2];
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    76
		local now = gettime(); -- inside or before the loop?
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    77
		if t > now then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    78
			local diff = t - now;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    79
			if diff < next_delay then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    80
				next_delay = diff;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    81
			end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    82
			return next_delay;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    83
		end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    84
		local new_timeout = f(now);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    85
		if new_timeout then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    86
			local t_diff = t + new_timeout - now;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    87
			if t_diff < 1e-6 then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    88
				t_diff = 1e-6;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    89
			end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    90
			if t_diff < next_delay then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    91
				next_delay = t_diff;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    92
			end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    93
			timer[1] = t + new_timeout;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    94
			resort_timers = true;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    95
		else
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    96
			t_remove(timers, i);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    97
		end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    98
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    99
	if next_delay < 1e-6 then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   100
		next_delay = 1e-6;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   101
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   102
	return next_delay;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   103
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   104
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   105
local interface = {};
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   106
local interface_mt = { __index = interface };
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   107
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   108
function interface_mt:__tostring()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   109
	if self.peer then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   110
		if self.conn then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   111
			return ("%d %s [%s]:%d"):format(self:getfd(), tostring(self.conn), self.peer[1], self.peer[2]);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   112
		else
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   113
			return ("%d [%s]:%d"):format(self:getfd(), self.peer[1], self.peer[2]);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   114
		end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   115
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   116
	return tostring(self:getfd());
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   117
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   118
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   119
function interface:setlistener(listeners)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   120
	self.listeners = listeners;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   121
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   122
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   123
function interface:getfd()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   124
	return self.conn:getfd();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   125
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   126
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   127
function interface:ip()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   128
	return self.peer[1];
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   129
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   130
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   131
function interface:socket()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   132
	return self.conn;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   133
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   134
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   135
function interface:setoption(k, v)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   136
	-- LuaSec doesn't expose setoption :(
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   137
	if self.conn.setoption then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   138
		self.conn:setoption(k, v);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   139
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   140
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   141
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   142
function interface:setreadtimeout(t)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   143
	if t == false then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   144
		if self._readtimeout then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   145
			self._readtimeout:close();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   146
			self._readtimeout = nil;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   147
		end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   148
		return
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   149
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   150
	t = t or cfg.read_timeout;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   151
	if self._readtimeout then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   152
		self._readtimeout[1] = gettime() + t;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   153
		resort_timers = true;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   154
	else
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   155
		self._readtimeout = addtimer(t, function ()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   156
			if self:onreadtimeout() then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   157
				return cfg.read_timeout;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   158
			else
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   159
				self.listeners.ondisconnect(self, "read timeout");
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   160
				self:destroy();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   161
			end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   162
		end);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   163
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   164
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   165
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   166
function interface:onreadtimeout()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   167
	if self.listeners.onreadtimeout then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   168
		return self.listeners.onreadtimeout(self);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   169
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   170
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   171
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   172
function interface:setwritetimeout(t)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   173
	if t == false then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   174
		if self._writetimeout then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   175
			self._writetimeout:close();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   176
			self._writetimeout = nil;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   177
		end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   178
		return
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   179
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   180
	t = t or cfg.write_timeout;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   181
	if self._writetimeout then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   182
		self._writetimeout[1] = gettime() + t;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   183
		resort_timers = true;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   184
	else
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   185
		self._writetimeout = addtimer(t, function ()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   186
			self.listeners.ondisconnect(self, "write timeout");
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   187
			self:destroy();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   188
		end);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   189
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   190
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   191
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   192
function interface:flags()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   193
	if self._wantread then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   194
		if self._wantwrite then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   195
			return "rw";
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   196
		end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   197
		return "r";
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   198
	elseif self._wantwrite then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   199
		return "w";
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   200
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   201
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   202
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   203
function interface:setflags(r, w)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   204
	if r ~= nil then self._wantread = r; end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   205
	if w ~= nil then self._wantwrite = w; end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   206
	local flags = self:flags();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   207
	local currentflags = self._flags;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   208
	if flags == currentflags then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   209
		return true;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   210
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   211
	local fd = self:getfd();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   212
	local op = "mod";
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   213
	if not flags then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   214
		op = "del";
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   215
	elseif not currentflags then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   216
		op = "add";
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   217
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   218
	local ok, err = epoll.ctl(op, fd, flags);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   219
	if not ok then return ok, err end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   220
	self._flags = flags;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   221
	return true;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   222
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   223
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   224
function interface:onreadable()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   225
	local data, err, partial = self.conn:receive(self._pattern);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   226
	if data or partial then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   227
		self.listeners.onincoming(self, data or partial, err);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   228
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   229
	if err == "wantread" then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   230
		self:setflags(true, nil);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   231
	elseif err == "wantwrite" then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   232
		self:setflags(nil, true);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   233
	elseif err ~= "timeout" then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   234
		self.listeners.ondisconnect(self, err);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   235
		self:destroy()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   236
		return;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   237
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   238
	self:setreadtimeout();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   239
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   240
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   241
function interface:onwriteable()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   242
	local buffer = self.writebuffer;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   243
	local data = t_concat(buffer);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   244
	local ok, err, partial = self.conn:send(data);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   245
	if ok then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   246
		for i = #buffer, 1, -1 do
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   247
			buffer[i] = nil;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   248
		end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   249
		self:ondrain();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   250
		if not buffer[1] then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   251
			self:setflags(nil, false);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   252
			self:setwritetimeout(false);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   253
		else
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   254
			self:setwritetimeout();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   255
		end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   256
		self._writable = true;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   257
	elseif partial then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   258
		buffer[1] = data:sub(partial+1)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   259
		for i = #buffer, 2, -1 do
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   260
			buffer[i] = nil;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   261
		end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   262
		self:setwritetimeout();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   263
		self._writable = false;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   264
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   265
	if err == "wantwrite" or err == "timeout" then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   266
		self:setflags(nil, true);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   267
	elseif err == "wantread" then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   268
		self:setflags(true, nil);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   269
	elseif err and err ~= "timeout" then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   270
		self.listeners.ondisconnect(self, err);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   271
		self:destroy();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   272
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   273
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   274
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   275
function interface:ondrain()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   276
	if self.listeners.ondrain then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   277
		self.listeners.ondrain(self);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   278
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   279
	if self._starttls then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   280
		self:starttls();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   281
	elseif self._toclose then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   282
		self:close();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   283
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   284
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   285
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   286
function interface:write(data)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   287
	local buffer = self.writebuffer;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   288
	if buffer then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   289
		t_insert(buffer, data);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   290
	else
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   291
		self.writebuffer = { data };
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   292
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   293
	if self._writable and false then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   294
		self:onwriteable();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   295
	else
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   296
		self:setwritetimeout();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   297
		self:setflags(nil, true);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   298
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   299
	return #data;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   300
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   301
interface.send = interface.write;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   302
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   303
function interface:close()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   304
	if self._wantwrite then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   305
		self._toclose = true;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   306
	else
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   307
		self.close = noop;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   308
		self.listeners.ondisconnect(self);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   309
		self:destroy();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   310
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   311
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   312
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   313
function interface:destroy()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   314
	self:setflags(false, false);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   315
	self:setwritetimeout(false);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   316
	self:setreadtimeout(false);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   317
	fds[self:getfd()] = nil;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   318
	return self.conn:close();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   319
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   320
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   321
function interface:ssl()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   322
	return self._tls;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   323
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   324
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   325
function interface:starttls(ctx)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   326
	if ctx then self.tls = ctx; end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   327
	if self.writebuffer and self.writebuffer[1] then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   328
		self._starttls = true;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   329
	else
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   330
		self:setflags(false, false);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   331
		local conn, err = luasec.wrap(self.conn, ctx or self.tls);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   332
		if not conn then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   333
			self.listeners.ondisconnect(self, err);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   334
			self:destroy();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   335
		end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   336
		conn:settimeout(0);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   337
		self.conn = conn;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   338
		self._starttls = nil;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   339
		self.onwriteable = interface.tlshandskake;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   340
		self.onreadable = interface.tlshandskake;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   341
		self:setflags(true, true);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   342
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   343
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   344
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   345
function interface:tlshandskake()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   346
	local ok, err = self.conn:dohandshake();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   347
	if ok then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   348
		self.onwriteable = nil;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   349
		self.onreadable = nil;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   350
		self:setflags(true, true);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   351
		local old = self._tls;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   352
		self._tls = true;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   353
		self.starttls = false;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   354
		if old == false then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   355
			self:onconnect();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   356
		elseif self.listeners.onstatus then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   357
			self.listeners.onstatus(self, "ssl-handshake-complete");
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   358
		end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   359
	elseif err == "wantread" then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   360
		self:setflags(true, false);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   361
		self:setwritetimeout(false);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   362
		self:setreadtimeout(cfg.handshake_timeout);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   363
	elseif err == "wantwrite" then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   364
		self:setflags(false, true);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   365
		self:setreadtimeout(false);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   366
		self:setwritetimeout(cfg.handshake_timeout);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   367
	else
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   368
		self.listeners.ondisconnect(self, err);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   369
		self:destroy();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   370
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   371
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   372
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   373
local function wrapsocket(client, server, pattern, listeners, tls) -- luasocket object -> interface object
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   374
	client:settimeout(0);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   375
	local conn = setmetatable({
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   376
		conn = client;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   377
		server = server;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   378
		created = gettime();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   379
		listeners = listeners;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   380
		_pattern = pattern or server._pattern;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   381
		writebuffer = {};
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   382
		tls = tls;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   383
	}, interface_mt);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   384
	if client.getpeername then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   385
		conn.peer = {client:getpeername()}
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   386
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   387
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   388
	fds[conn:getfd()] = conn;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   389
	return conn;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   390
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   391
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   392
function interface:onacceptable()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   393
	local conn, err = self.conn:accept();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   394
	if not conn then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   395
		log(debug, "Error accepting new client: %s, server will be paused for %ds", err, cfg.accept_retry_interval);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   396
		self:pausefor(cfg.accept_retry_interval);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   397
		return;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   398
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   399
	local client = wrapsocket(conn, self, nil, self.listeners, self.tls);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   400
	if self.tls then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   401
		client._tls = false;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   402
		client:starttls();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   403
	else
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   404
		self.listeners.onconnect(client);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   405
		client:setflags(true);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   406
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   407
	client:setreadtimeout();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   408
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   409
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   410
function interface:pause()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   411
	self:setflags(false);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   412
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   413
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   414
function interface:resume()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   415
	self:setflags(true);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   416
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   417
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   418
function interface:pausefor(t)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   419
	if self._wantread then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   420
		self:setflags(false);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   421
		addtimer(t, function () self:setflags(true); end);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   422
	end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   423
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   424
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   425
function interface:onconnect()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   426
	self.onreadable = nil;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   427
	self.onwriteable = nil;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   428
	self.listeners.onconnect(self);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   429
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   430
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   431
local function addclient(addr, port, listeners, pattern, tls)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   432
	local conn, err = socket.connect(addr, port);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   433
	if not conn then return conn, err; end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   434
	return wrapsocket(conn, nil, pattern, listeners, tls);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   435
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   436
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   437
local function addserver(addr, port, listeners, pattern, tls)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   438
	local conn, err = socket.bind(addr, port, cfg.tcp_backlog);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   439
	if not conn then return conn, err; end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   440
	conn:settimeout(0);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   441
	local server = setmetatable({
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   442
		conn = conn;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   443
		created = gettime();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   444
		listeners = listeners;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   445
		_pattern = pattern;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   446
		onreadable = interface.onacceptable;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   447
		tls = tls;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   448
		peer = { addr, port };
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   449
	}, interface_mt);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   450
	server:setflags(true, false);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   451
	fds[server:getfd()] = server;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   452
	return server;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   453
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   454
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   455
-- COMPAT
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   456
local function wrapclient(client, addr, port, listeners, mode, tls)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   457
	local conn = setmetatable({
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   458
		conn = client;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   459
		created = gettime();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   460
		listeners = listeners;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   461
		_pattern = mode;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   462
		writebuffer = {};
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   463
		tls = tls;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   464
		onreadable = interface.onconnect;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   465
		onwriteable = interface.onconnect;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   466
		peer = { addr, port };
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   467
	}, interface_mt);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   468
	fds[conn:getfd()] = conn;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   469
	conn:setflags(true, true);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   470
	return conn;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   471
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   472
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   473
local function link(from, to)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   474
	from.listeners = setmetatable({
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   475
		onincoming = function (_, data)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   476
			from:pause();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   477
			to:write(data);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   478
		end,
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   479
	}, {__index=from.listeners});
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   480
	to.listeners = setmetatable({
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   481
		ondrain = function ()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   482
			from:resume();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   483
		end,
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   484
	}, {__index=to.listeners});
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   485
	from:setflags(true, nil);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   486
	to:setflags(nil, true);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   487
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   488
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   489
-- XXX What uses this?
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   490
-- net.adns
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   491
function interface:set_send(new_send)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   492
	self.send = new_send;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   493
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   494
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   495
local quitting = nil;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   496
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   497
local function setquitting()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   498
	quitting = "quitting";
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   499
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   500
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   501
local function loop()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   502
	repeat
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   503
		local t = runtimers();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   504
		local fd, r, w = epoll.wait(t);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   505
		if fd then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   506
			local conn = fds[fd];
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   507
			if conn then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   508
				if r then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   509
					conn:onreadable();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   510
				end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   511
				if w then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   512
					conn:onwriteable();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   513
				end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   514
			else
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   515
				log("debug", "Removing unknown fd %d", fd);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   516
				epoll.ctl("del", fd);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   517
			end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   518
		elseif r ~= "timeout" then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   519
			log("debug", "epoll_wait error: %s", tostring(r));
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   520
		end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   521
	until quitting;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   522
	return quitting;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   523
end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   524
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   525
return {
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   526
	get_backend = function () return "epoll"; end;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   527
	addserver = addserver;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   528
	addclient = addclient;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   529
	add_task = addtimer;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   530
	at = at;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   531
	loop = loop;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   532
	setquitting = setquitting;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   533
	wrapclient = wrapclient;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   534
	link = link;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   535
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   536
	-- libevent emulation
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   537
	event = { EV_READ = "r", EV_WRITE = "w", EV_READWRITE = "rw", EV_LEAVE = -1 };
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   538
	addevent = function (fd, mode, callback)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   539
		local function onevent(self)
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   540
			local ret = self:callback();
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   541
			if ret == -1 then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   542
				epoll.ctl("del", fd);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   543
			elseif ret then
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   544
				epoll.ctl("mod", fd, mode);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   545
			end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   546
		end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   547
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   548
		local conn = {
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   549
			callback = callback;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   550
			onreadable = onevent;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   551
			onwriteable = onevent;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   552
			close = function ()
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   553
				fds[fd] = nil;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   554
				return epoll.ctl("del", fd);
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   555
			end;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   556
		};
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   557
		fds[fd] = conn;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   558
		local ok, err = epoll.ctl("add", fd, mode or "r");
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   559
		if not ok then return ok, err; end
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   560
		return conn;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   561
	end;
b327322ce2dd net.server_epoll: New experimental server backend
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   562
};