1 ---------------------------------
 
    2 --- @file namespaces.lua
 
    3 --- @brief Namespaces ...
 
    5 ---------------------------------
 
    9 local 
ffi       = require 
"ffi" 
   10 local serpent   = require 
"Serpent" 
   11 local stp       = require 
"StackTracePlus" 
   12 local lock      = require 
"lock" 
   16     struct namespace* create_or_get_namespace(
const char* name);
 
   17     void namespace_store(
struct namespace* ns, 
const char* key, 
const char* value);
 
   18     void namespace_delete(
struct namespace* ns, 
const char* key);
 
   19     const char* namespace_retrieve(
struct namespace* ns, 
const char* key);
 
   20     void namespace_iterate(
struct namespace* ns, 
void (*func)(
const char* key, 
const char* val));
 
   21     struct lock* namespace_get_lock(
struct namespace* ns);
 
   23 local cbType = 
ffi.typeof(
"void (*)(const char* key, const char* val)")
 
   28 namespace.__index = 
namespace 
   30 local 
function getNameFromTrace()
 
   31     return debug.traceback():match("\
n.-\
n.-\
n(.-)\
n")
 
   34 --- Get a namespace by its name creating it if necessary.
 
   35 --- @param name the name, defaults to an auto-generated 
string consisting of the caller's filename and line number
 
   37     name = name or getNameFromTrace()
 
   38     return C.create_or_get_namespace(name)
 
   41 --- Retrieve a *copy* of a value in the namespace.
 
   42 --- @param key the key, must be a 
string 
   44     if type(key) ~= "
string" then
 
   45         error("table index must be a 
string")
 
   49     elseif key == "lock" then
 
   50         return C.namespace_get_lock(self)
 
   52     local val = C.namespace_retrieve(self, key)
 
   53     return val ~= nil and loadstring(
ffi.
string(val))() or nil
 
   56 --- Store a value in the namespace.
 
   57 --- @param key the key, must be a 
string 
   58 --- @param val the value to store, will be serialized
 
   60     if type(key) ~= "
string" then
 
   61         error("table index must be a 
string")
 
   63     if key == "
forEach" or key == "lock" then
 
   64         error(key .. " is reserved", 2)
 
   67         C.namespace_delete(self, key)
 
   69         C.namespace_store(self, key, serpent.
dump(val))
 
   74 --- Iterate over all keys/values in a namespace
 
   75 --- Note: namespaces do not offer a 'normal' iterator (e.g. through a __pair metamethod) due to locking.
 
   76 --- Iterating over a table requires a lock on the whole table; ensuring that the lock is released is
 
   77 --- easier with a 
forEach method than with a regular iterator.
 
   78 --- @param func function to call, receives (key, value) as arguments
 
   79 function namespace:
forEach(func)
 
   81     local cb = 
ffi.cast(cbType, function(key, val)
 
   85         -- avoid throwing an error across the C++ frame unnecessarily
 
   86         -- not sure if this would work properly when compiled with clang instead of gcc
 
   87         local ok, err = xpcall(func, function(err)
 
   88             return stp.stacktrace(err)
 
   89         end, 
ffi.
string(key), loadstring(
ffi.
string(val))())
 
   94     C.namespace_iterate(self, cb)
 
   97         -- this is gonna be an ugly error message, but at least we 
get the full call stack
 
   98         error("error while calling callback, inner error: " .. caughtError)
 
  102 ffi.metatype("struct namespace", namespace)
 
local ffi
low-level dpdk wrapper 
 
namespace __newindex(key, val)
Store a value in the namespace. 
 
function mod free(buf)
Free off-heap allocated object. 
 
function pkt dump(bytes)
Dumps the packet data cast to the best fitting packet struct. 
 
namespace __index(key)
Retrieve a copy of a value in the namespace. 
 
local mod
high-level dpdk wrapper 
 
function mod get(name)
Get a namespace by its name creating it if necessary. 
 
n
Create a new array of memory buffers (initialized to nil). 
 
namespace forEach(func)
Iterate over all keys/values in a namespace Note: namespaces do not offer a 'normal' iterator (e...