Search code examples
nginxlualuajitluasocketluarocks

Luasocket + nginx error - lua entry thread aborted: runtime error: attempt to yield across C-call boundary


When I use the following script:

local smtp = require("socket.smtp")
local from = "from@host"
local rcpt = "rcpt@host"
local msg = {
  headers = {
    to = rcpt,
    subject = "Hi"
  },
  body = "Hello"
}
smtp.send{from = from,rcpt = rcpt,source = smtp.message(msg)}

I'm getting an error message: lua entry thread aborted: runtime error: attempt to yield across C-call boundary.

I'm using the newest luasocket installed from luarocks with Lua 5.1 using nginx compiled with LuaJIT 2.1. What is causing this error message and how do I fix it?


Solution

  • smtp.send uses LuaSocket's socket.protect function for handling internal errors. This function is implemented in C and doesn't allow yielding in the current releases (the version in git HEAD now allows yielding on Lua 5.2+, see discussion here). Apparently someone tries to yield from within it. In etc/dispatch.lua in the LuaSocket package (better use the git HEAD version) there is a replacement function for socket.protect that should allow yielding on all Lua versions (at the cost of an extra temporary coroutine). You can try replacing the C function with that Lua function like so:

    local socket = require("socket")
    local base = _G
    -- paste modified socket.protect function here
    
    -- continue with your own code:
    local smtp = require("socket.smtp")
    -- ...