lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


I finally have a minimal working version and it has nothing to do with luasql.postgres. It does come down to my little extension:

/*
 * gcc -Wall -shared -fPIC -o time_now.so -llua time_now.c
 *
 * This is an unusual case. I need the current time, down to microseconds,
 * as a string for things like logs. Not something that Lua is good at.
 */

#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"

#include <stdio.h>
#include <sys/time.h>

#define BUFFER_SIZE 64
#define LENGTH_OF_DATE_TIME 19
#define LENGTH_OF_MS 8

static int time_now (lua_State *L) {
  char buffer[BUFFER_SIZE];
  struct tm* tm_info;
  struct timeval tv;
  long int ms;

  gettimeofday(&tv, NULL);

  tm_info = localtime(&tv.tv_sec);

  strftime(buffer, BUFFER_SIZE, "%Y-%m-%dT%H:%M:%S", tm_info);

  ms = (long int)tv.tv_usec % 1000000;

  snprintf(buffer + LENGTH_OF_DATE_TIME, LENGTH_OF_MS, ".%06ld", ms);

  lua_pushstring(L, buffer);

  return 1;
}

int luaopen_time_now(lua_State *L){
  lua_register(L, "time_now", time_now);
  return 0;
}

With the following test program:

require 'time_now'

local function build()
  local t = {}
  for i = 1,10000 do
    t[i] = time_now()
  end
end

local counter = 0

while true do
  counter = counter + 1
  print("Iteration " .. counter)
  build()
end

The program will consistently crash thus:

Iteration 1
Iteration 2
Iteration 3
lua(5965,0x7fff7ab92000) malloc: *** error for object 0x10001f6c0: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6

There are two work arounds, first is to kick the garbage collector:

local function build()
  collectgarbage()
  local t = {}
  for i = 1,10000 do
    t[i] = time_now()
  end
end

or simply force some output:

local function build()
  local t = {}
  for i = 1,10000 do
    print(i)
    t[i] = time_now()
  end
end

​Both of these changes will allow the process to run forever. However it is a pain to say "when using time_now() you need to stick a collectgarbage() somewhere".

Is there something I can do to my extension to avoid this problem as it feels a little to voodoo to have to stick a collectgarbage() at some random point in the program or end up calling it every time I call time_now()

A good place to insert collectgarbage() today may not be a good place tomorrow :(