Parcourir la source

Revise fifo{,sock} (#2671)

Fixes to #2650:

- Convert fifosock to returning tables containing ctors
- Improve docs
- Add a missed :on("sent", nil) in the http server
Nathaniel Wesley Filardo il y a 5 ans
Parent
commit
1070466feb

+ 20 - 8
docs/lua-modules/fifosock.md

@@ -3,23 +3,35 @@
 | :----- | :-------------------- | :---------- | :------ |
 | 2019-02-10 | [TerryE](https://github.com/TerryE) | [nwf](https://github.com/nwf) | [fifosock.lua](../../lua_modules/fifo/fifosock.lua) |
 
-This module provides a convenient, efficient wrapper around the `net.socket`
-`send` method.  It ensures in-order transmission while striving to minimize
-memory footprint and packet count by coalescing queued strings.  It also serves
-as a detailed, worked example of the `fifo` module.
+This module provides a moderately convenient, efficient wrapper around the
+`net.socket` `send` method.  It ensures in-order transmission while striving to
+minimize memory footprint and packet count by coalescing queued strings.  It
+also serves as a detailed, worked example of the `fifo` module.
 
 ## Use
 ```lua
-ssend = (require "fifosock")(sock)
-
+ssend = (require "fifosock").wrap(sock)
 ssend("hello, ") ssend("world\n")
+
+-- when finished
+ssend = nil
+sock:on("sent", nil)
 ```
 
 Once the `sock`et has been wrapped, one should use only the resulting `ssend`
 function in lieu of `sock:send`, and one should not change the
-`sock:on("sent")` callback.
+`sock:on("sent")` callback for the duration of the connection.
+
+Use of this module creates a circular reference through the Lua registry: the
+socket points at the fifosock wrapper, which points back at the socket.  As
+such, it is vitally important to break this cycle when the socket has outlived
+its use.  **The usual garbage collection will not be able to reclaim abandoned
+wrapped sockets**.  The user of `fifosock` must, when disposing of the socket,
+unwire the wrapper, by calling `sock:on("sent", nil)` and should drop all
+references to `ssend`; a convenient place to do this is in the
+`sock:on("disconnect")` callback.
 
-### Advanced Use
+## Advanced Use
 
 In addition to passing strings representing part of the stream to be sent, it
 is possible to pass the resulting `ssend` function *functions*.  These

+ 1 - 1
lua_examples/telnet/telnet.lua

@@ -31,7 +31,7 @@ local node, table, tmr, wifi, uwrite,     tostring =
       node, table, tmr, wifi, uart.write, tostring
 
 local function telnet_listener(socket) 
-  local queueLine = (require "fifosock")(socket)
+  local queueLine = (require "fifosock").wrap(socket)
 
   local function receiveLine(s, line)
     node.input(line)

+ 4 - 4
lua_modules/fifo/fifosock.lua

@@ -15,11 +15,9 @@ local concat = table.concat
 local insert = table.insert
 local gc     = collectgarbage
 
-local fifo = require "fifo"
-
-return function(sock)
+local function wrap(sock)
   -- the two fifos
-  local fsmall, lsmall, fbig = {}, 0, fifo.new()
+  local fsmall, lsmall, fbig = {}, 0, (require "fifo").new()
 
   -- ssend last aggregation string and aggregate count
   local ssla, sslan = nil, 0
@@ -132,3 +130,5 @@ return function(sock)
     end
   end
 end
+
+return { wrap = wrap }

+ 1 - 1
lua_modules/fifo/fifosocktest.lua

@@ -33,7 +33,7 @@ local fakesock = {
 local function sent() vprint("SENT") fakesock.cb() end
 
 -- And wrap a fifosock around this fake socket
-local fsend = require "fifosock" (fakesock)
+local fsend = (require "fifosock").wrap(fakesock)
 
 -- Verify that the next unconsumed output is as indicated
 local function fcheck(x)

+ 2 - 1
lua_modules/http/httpserver.lua

@@ -79,7 +79,7 @@ do
   ------------------------------------------------------------------------------
   local http_handler = function(handler)
     return function(conn)
-      local csend = (require "fifosock")(conn)
+      local csend = (require "fifosock").wrap(conn)
       local cfini = function()
         conn:on("receive", nil)
         conn:on("disconnection", nil)
@@ -89,6 +89,7 @@ do
       local buf = ""
       local method, url
       local ondisconnect = function(conn)
+	conn.on("sent", nil)
         collectgarbage("collect")
       end
       -- header parser