jkeys089 / lua-resty-hmac

HMAC functions for ngx_lua and LuaJIT
160 stars 99 forks source link

Singleton buffer being reused? #3

Closed ljwagerfield closed 8 years ago

ljwagerfield commented 8 years ago

Whilst I don't have a specific error case, I noticed what looks like a possible bug:

https://github.com/jkeys089/lua-resty-hmac/blob/b69abb8361e1d8d86eaac77928853b205c7f49f2/lib/resty/hmac.lua#L76

Is this code defining a singleton buffer which is shared by all calls to final across all instances of hmac? That would be dangerous if so, right?

(p.s. I'm new to Lua as of this weekend)

jkeys089 commented 8 years ago

OpenResty creates a new Lua VM per nginx worker thread. So, all Lua code is guaranteed to be executed only by a single thread at a time. However, OpenResty is fully non-blocking and will suspend the current execution context (e.g. during network I/O) to handle another request. In other words, it is not safe to assume globally shared state will be consistent throughout the entire life of a request when using non-blocking API's.

All that being said, this code is safe. Remember, so long as the code avoids the use of non-blocking API's (e.g. cosocket API) it is guaranteed to be single-threaded and execute serially to completion. Since we're not using any non-blocking API's inside the final function it is safe to use/re-use the shared buffer instead of allocating a new one for every operation. It is important to note that the shared buffer is only ever used inside the final function so we have complete control over the execution context at all times (i.e. we know it will not be suspended and therefore we know the buffer can't be used for another operation until we're done with it within the final method).

Hopefully that all makes sense.

ljwagerfield commented 8 years ago

That's excellent, thank you @jkeys089. Knowing that OpenResty creates a new Lua VM per nginx worker thread clarifies a lot of things for me!