Skip to content

Commit

Permalink
Merge pull request #72 from jelu/opt-n-thr
Browse files Browse the repository at this point in the history
Getopt and Threads
  • Loading branch information
jelu authored Jun 12, 2018
2 parents 7911e8c + d60804c commit 926783d
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 16 deletions.
68 changes: 58 additions & 10 deletions src/core/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,24 @@ int core_thread_stop(core_thread_t* self)
return 0;
}

inline void _push(core_thread_t* self, core_thread_item_t* item)
{
if (pthread_mutex_lock(&self->lock)) {
lfatal("mutex lock failed");
}
if (!self->last) {
self->stack = self->last = item;
} else {
self->last->next = item;
}
if (pthread_cond_signal(&self->cond)) {
lfatal("cond signal failed");
}
if (pthread_mutex_unlock(&self->lock)) {
lfatal("mutex unlock failed");
}
}

int core_thread_push(core_thread_t* self, void* ptr, const char* type, size_t type_len, const char* module, size_t module_len)
{
core_thread_item_t* item;
Expand All @@ -154,20 +172,50 @@ int core_thread_push(core_thread_t* self, void* ptr, const char* type, size_t ty
memcpy(item->module, module, module_len);
item->module[module_len] = 0;

if (pthread_mutex_lock(&self->lock)) {
lfatal("mutex lock failed");
_push(self, item);

return 0;
}

int core_thread_push_string(core_thread_t* self, const char* str, size_t len)
{
core_thread_item_t* item;

if (!self || !str || !len) {
return 1;
}
if (!self->last) {
self->stack = self->last = item;
} else {
self->last->next = item;

if (!(item = malloc(sizeof(core_thread_item_t) + len + 1))) {
return 1;
}
if (pthread_cond_signal(&self->cond)) {
lfatal("cond signal failed");
item->next = 0;
item->ptr = 0;
item->str = ((void*)item) + sizeof(core_thread_item_t);
memcpy(item->str, str, len);
item->str[len] = 0;

_push(self, item);

return 0;
}

int core_thread_push_int64(core_thread_t* self, int64_t i64)
{
core_thread_item_t* item;

if (!self) {
return 1;
}
if (pthread_mutex_unlock(&self->lock)) {
lfatal("mutex unlock failed");

if (!(item = malloc(sizeof(core_thread_item_t)))) {
return 1;
}
item->next = 0;
item->ptr = 0;
item->str = 0;
item->i64 = i64;

_push(self, item);

return 0;
}
Expand Down
5 changes: 5 additions & 0 deletions src/core/thread.hh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ struct core_thread_item {
core_thread_item_t* next;
void* ptr;
char * type, *module;

char* str;
int64_t i64;
};

typedef struct core_thread {
Expand All @@ -48,4 +51,6 @@ int core_thread_destroy(core_thread_t* self);
int core_thread_start(core_thread_t* self, const char* bytecode, size_t len);
int core_thread_stop(core_thread_t* self);
int core_thread_push(core_thread_t* self, void* ptr, const char* type, size_t type_len, const char* module, size_t module_len);
int core_thread_push_string(core_thread_t* self, const char* str, size_t len);
int core_thread_push_int64(core_thread_t* self, int64_t i64);
const core_thread_item_t* core_thread_pop(core_thread_t* self);
24 changes: 19 additions & 5 deletions src/core/thread.lua
Original file line number Diff line number Diff line change
Expand Up @@ -74,23 +74,37 @@ function Thread:stop()
return C.core_thread_stop(self)
end

-- Push a sharable object onto the thread stack so it can be retrieved inside
-- the thread using
-- Push a string, number or sharable object onto the thread stack so it can
-- be retrieved inside the thread using
-- .IR pop() .
-- The object needs to be kept alive as long as the thread is running.
-- The object needs to be kept alive as long as the thread is running, strings
-- and numbers are copied.
-- Returns 0 on success.
function Thread:push(obj)
local t = type(obj)
if t == "string" then
return C.core_thread_push_string(self, obj, #obj)
elseif t == "number" then
return C.core_thread_push_int64(self, obj)
end
local ptr, type, module = obj:share()
return C.core_thread_push(self, ptr, type, #type, module, #module)
end

-- Pop an object off the thread stack, should only be called within the thread.
-- Returns nil on failure or if no objects are left on the stack.
-- Pop a shared value off the thread stack, should only be called within the
-- thread.
-- Returns nil on failure or if no shared values are left on the stack.
function Thread:pop()
local item = C.core_thread_pop(self)
if item == nil then
return
end
if item.ptr == nil then
if item.str == nil then
return tonumber(item.i64)
end
return ffi.string(item.str)
end
require(ffi.string(item.module))
return ffi.cast(ffi.string(item.type), item.ptr)
end
Expand Down
13 changes: 12 additions & 1 deletion src/lib/getopt.lua
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,18 @@ end
-- Print the usage.
function Getopt:usage()
print("Usage:")
for k, v in pairs(self.opt) do

local opts = {}
for k, _ in pairs(self.opt) do
if k ~= "help" then
table.insert(opts, k)
end
end
table.sort(opts)
table.insert(opts, "help")

for _, k in pairs(opts) do
local v = self.opt[k]
local arg
if v.type == "string" then
arg = " \""..v.default.."\""
Expand Down

0 comments on commit 926783d

Please sign in to comment.