Browse 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 5 years ago
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) |
 | 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
 ## Use
 ```lua
 ```lua
-ssend = (require "fifosock")(sock)
-
+ssend = (require "fifosock").wrap(sock)
 ssend("hello, ") ssend("world\n")
 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`
 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
 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
 In addition to passing strings representing part of the stream to be sent, it
 is possible to pass the resulting `ssend` function *functions*.  These
 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
       node, table, tmr, wifi, uart.write, tostring
 
 
 local function telnet_listener(socket) 
 local function telnet_listener(socket) 
-  local queueLine = (require "fifosock")(socket)
+  local queueLine = (require "fifosock").wrap(socket)
 
 
   local function receiveLine(s, line)
   local function receiveLine(s, line)
     node.input(line)
     node.input(line)

+ 4 - 4
lua_modules/fifo/fifosock.lua

@@ -15,11 +15,9 @@ local concat = table.concat
 local insert = table.insert
 local insert = table.insert
 local gc     = collectgarbage
 local gc     = collectgarbage
 
 
-local fifo = require "fifo"
-
-return function(sock)
+local function wrap(sock)
   -- the two fifos
   -- 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
   -- ssend last aggregation string and aggregate count
   local ssla, sslan = nil, 0
   local ssla, sslan = nil, 0
@@ -132,3 +130,5 @@ return function(sock)
     end
     end
   end
   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
 local function sent() vprint("SENT") fakesock.cb() end
 
 
 -- And wrap a fifosock around this fake socket
 -- 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
 -- Verify that the next unconsumed output is as indicated
 local function fcheck(x)
 local function fcheck(x)

+ 2 - 1
lua_modules/http/httpserver.lua

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