--- a/luaevent.lua Fri Aug 31 23:21:09 2007 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,157 +0,0 @@ ---[[ - LuaEvent - Copyright (C) 2007 Thomas Harning <harningt@gmail.com> - Licensed as LGPL - See doc/COPYING for details. -]] -module("luaevent", package.seeall) -require("luaevent.core") - -local EV_READ = luaevent.core.EV_READ -local EV_WRITE = luaevent.core.EV_WRITE -local fair = false -- Not recommended for most cases... -local base = luaevent.core.new() -local sockMap = setmetatable({}, {'__mode', 'kv'}) -local function addevent(sock, ...) - local item = base:addevent(sock, ...) - if not item then print("FAILED TO SETUP ITEM") return item end - local fd = sock:getfd() - sockMap[item] = fd - print("SETUP ITEM FOR: ", fd) - if not hookedObjectMt then - hookedObjectMt = true - --[[ - local mt = debug.getmetatable(item) - local oldGC = mt.__gc - mt.__gc = function(...) - print("RELEASING ITEM FOR: ", sockMap[(...)]) - return oldGC(...) - end]] - end - return item -end --- Weak keys.. the keys are the client sockets -local clientTable = setmetatable({}, {'__mode', 'kv'}) - -local function getWrapper() - local running = coroutine.running() - return function(...) - if coroutine.running() == running then return end - return select(2, coroutine.resume(running, ...)) - end -end - -function send(sock, data, start, stop) - local s, err - local from = start or 1 - local sent = 0 - repeat - from = from + sent - s, err, sent = sock:send(data, from, stop) - -- Add extra coro swap for fairness - -- CURRENTLY DISABLED FOR TESTING...... - if fair and math.random(100) > 90 then - if not clientTable[sock] then clientTable[sock] = addevent(sock, EV_WRITE, getWrapper()) end - coroutine.yield(EV_WRITE) - end - if s or err ~= "timeout" then return s, err, sent end - if not clientTable[sock] then clientTable[sock] = addevent(sock, EV_WRITE, getWrapper()) end - coroutine.yield(EV_WRITE) - until false -end -function receive(sock, pattern, part) - local s, err - pattern = pattern or '*l' - repeat - s, err, part = sock:receive(pattern, part) - if s or err ~= "timeout" then return s, err, part end - if not clientTable[sock] then clientTable[sock] = addevent(sock, EV_READ, getWrapper()) end - coroutine.yield(EV_READ) - until false -end --- same as above but with special treatment when reading chunks, --- unblocks on any data received. -function receivePartial(client, pattern) - local s, err, part - pattern = pattern or "*l" - repeat - s, err, part = client:receive(pattern) - if s or ( (type(pattern)=="number") and part~="" and part ~=nil ) or - err ~= "timeout" then return s, err, part end - if not clientTable[sock] then clientTable[sock] = addevent(sock, EV_READ, getWrapper()) end - coroutine.yield(EV_READ) - until false -end -function connect(sock, ...) - sock:settimeout(0) - local ret, err = sock:connect(...) - if ret or err ~= "timeout" then return ret, err end - if not clientTable[sock] then clientTable[sock] = addevent(sock, EV_WRITE, getWrapper()) end - coroutine.yield(EV_WRITE) - ret, err = sock:connect(...) - if err == "already connected" then - return 1 - end - return ret, err -end --- Deprecated.. -function flush(sock) -end -local function clientCoroutine(sock, handler) - -- Figure out what to do ...... - return handler(sock) -end -local function handleClient(co, client, handler) - local ok, res, event = coroutine.resume(co, client, handler) -end -local function serverCoroutine(sock, callback) - local listenItem = addevent(sock, EV_READ, getWrapper()) - repeat - local event = coroutine.yield(EV_READ) - -- Get new socket - local client = sock:accept() - if client then - client:settimeout(0) - local co = coroutine.create(clientCoroutine) - handleClient(co, client, callback) - end - until false -end -function addserver(sock, callback) - local coro = coroutine.create(serverCoroutine) - assert(coroutine.resume(coro, sock, callback)) -end -function addthread(func, ...) - return coroutine.resume(coroutine.create(func), ...) -end -local _skt_mt = {__index = { - connect = function(self, ...) - return connect(self.socket, ...) - end, - send = function (self, data) - return send(self.socket, data) - end, - - receive = function (self, pattern) - if (self.timeout==0) then - return receivePartial(self.socket, pattern) - end - return receive(self.socket, pattern) - end, - - flush = function (self) - return flush(self.socket) - end, - - settimeout = function (self,time) - self.timeout=time - return - end, - - close = function(self) - clientTable[self.socket]:close() - self.socket:close() - end -}} -function wrap(sock) - return setmetatable({socket = sock}, _skt_mt) -end -loop = function(...) base:loop(...) end \ No newline at end of file