summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2010-11-14 19:06:41 +0000
committerChristian Pointner <equinox@spreadspace.org>2010-11-14 19:06:41 +0000
commitc3b827d710f62be79837dc581c93db9a2f091d15 (patch)
tree29f68f4a3f1a6a72ba6a589dfbe505e2c9b5c907
parentchanged module configuration syntax (diff)
added command queue
git-svn-id: https://svn.spreadspace.org/gcsd/trunk@27 ac14a137-c7f1-4531-abe0-07747231d213
-rw-r--r--src/Makefile1
-rw-r--r--src/command_queue.lua77
-rw-r--r--src/main_loop.lua17
-rw-r--r--src/module_list.lua34
-rw-r--r--src/modules/debug_shell.lua7
5 files changed, 116 insertions, 20 deletions
diff --git a/src/Makefile b/src/Makefile
index abad7a5..91461fd 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -53,6 +53,7 @@ C_SRCS := $(C_OBJS:%.o=%.c)
LUA_SRCS := client_list.lua \
module_list.lua \
+ command_queue.lua \
main_loop.lua
LUA_BYTECODE := $(EXECUTABLE).lc
diff --git a/src/command_queue.lua b/src/command_queue.lua
new file mode 100644
index 0000000..a7ed70b
--- /dev/null
+++ b/src/command_queue.lua
@@ -0,0 +1,77 @@
+--
+-- gcsd
+--
+-- gcsd the generic command sequencer daemon can be used to serialize
+-- commands sent over various paralell communication channels to a
+-- single command output. It can be seen as a multiplexer for any
+-- kind of communication between a single resource and various clients
+-- which want to submit commands to it or query information from it.
+-- gcsd is written in C and Lua. The goal is to provide an easy to
+-- understand high level API based on Lua which can be used to
+-- implement the business logic of the so formed multiplexer daemon.
+--
+--
+-- Copyright (C) 2009-2010 Markus Grueneis <gimpf@spreadspace.org>
+-- Christian Pointner <equinox@spreadspace.org>
+--
+-- This file is part of gcsd.
+--
+-- gcsd is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- any later version.
+--
+-- gcsd is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with gcsd. If not, see <http://www.gnu.org/licenses/>.
+--
+
+local defines = require("defines")
+
+command_queue = {}
+
+command_queue.commands = {}
+command_queue.current = nil
+
+function command_queue:enqueue(command, expected_response, timeout)
+ local new_cmd = {}
+ new_cmd.command = command
+ new_cmd.sent = false
+ new_cmd.expected_response = expected_response
+ new_cmd.timeout = timeout
+
+ table.insert(self.commands, new_cmd)
+end
+
+function command_queue:command_pending()
+ return (self.current == nil and #self.commands > 0)
+end
+
+function command_queue:get_current_command()
+ return self.current
+end
+
+function command_queue:get_next_command()
+ if(self.current ~= nil) then return nil end
+
+ self.current = self.commands[1]
+ return self.current.command
+end
+
+function command_queue:command_sent()
+ if(self.current == nil) then return end
+
+ self.current.sent = true
+ return self.current.expected_response
+end
+
+function command_queue:command_completed()
+ if(self.current == nil) then return end
+
+ table.remove(self.commands, 1)
+ self.current = nil
+end
diff --git a/src/main_loop.lua b/src/main_loop.lua
index 5540dee..ebe42fa 100644
--- a/src/main_loop.lua
+++ b/src/main_loop.lua
@@ -35,7 +35,7 @@ local defines = require("defines")
function get_readables()
local readables = {}
- for _, module in ipairs(module_list.modules) do
+ for _, module in ipairs(module_list.inputs) do
for _, fd in ipairs(module:get_read_handles()) do
table.insert(readables, fd)
end
@@ -45,13 +45,13 @@ function get_readables()
table.insert(readables, fd)
end
end
-
+
return readables
end
function get_writeables()
local writeables = { }
- for _, module in ipairs(module_list.modules) do
+ for _, module in ipairs(module_list.inputs) do
for _, fd in ipairs(module:get_write_handles()) do
table.insert(writeables, fd)
end
@@ -61,11 +61,11 @@ function get_writeables()
table.insert(writeables, fd)
end
end
-
+
return writeables
end
-function main_loop(opt)
+function main_loop(opt)
log.printf(log.NOTICE, "main_loop started")
local sig = signal.init()
@@ -85,7 +85,7 @@ function main_loop(opt)
if(return_value == 1) then break end
else
local ret = reader:read()
- if(ret == defines.KILL_DAEMON) then
+ if(ret == defines.KILL_DAEMON) then
return_value = 2
break
elseif(ret == defines.KILL_MODULE_CLASS) then
@@ -103,6 +103,11 @@ function main_loop(opt)
client_list:unregister(writer.client_instance)
end
end
+ if(command_queue:command_pending()) then
+ log.printf(log.DEBUG, "sending pending command: %s", command_queue:get_next_command())
+ command_queue:command_sent()
+ command_queue:command_completed()
+ end
end
end
diff --git a/src/module_list.lua b/src/module_list.lua
index 7c1feae..7683e27 100644
--- a/src/module_list.lua
+++ b/src/module_list.lua
@@ -32,7 +32,8 @@
module_list = {}
-module_list.modules = {}
+module_list.inputs = {}
+module_list.output = nil
function module_list:init(opt)
log.printf(log.DEBUG, "gcsd output = %s", opt.cmd_out)
@@ -50,19 +51,20 @@ function module_list:init(opt)
end
package.path = old_path
- table.insert(self.modules, dummy:new({}))
+ self.output = dummy:new({})
+ table.insert(self.inputs, dummy:new({}))
if(opt.debug) then
- table.insert(self.modules, debug_shell:new({["host"]="127.0.0.1", ["port"]="9000"}))
- table.insert(self.modules, debug_shell:new({["host"]="127.0.0.1", ["port"]="9001"}))
+ table.insert(self.inputs, debug_shell:new({["host"]="127.0.0.1", ["port"]="9000"}))
+ table.insert(self.inputs, debug_shell:new({["host"]="127.0.0.1", ["port"]="9001"}))
end
end
function module_list:unregister(module)
- for i, m in ipairs(self.modules) do
+ for i, m in ipairs(self.inputs) do
if(m == module) then
- log.printf(log.INFO, "removing module: " .. module.name)
+ log.printf(log.INFO, "removing input module: " .. module.name)
module:cleanup()
- table.remove(self.modules, i)
+ table.remove(self.inputs, i)
break
end
end
@@ -71,23 +73,27 @@ end
function module_list:unregister_by_class(class)
local free_list = {}
- for i, m in ipairs(self.modules) do
+ for i, m in ipairs(self.inputs) do
if(m.class == class) then
table.insert(free_list, 1, i)
end
end
for _, i in ipairs(free_list) do
- log.printf(log.INFO, "removing module: " .. self.modules[i].name)
- self.modules[i]:cleanup()
- table.remove(self.modules, i)
+ log.printf(log.INFO, "removing input module: " .. self.inputs[i].name)
+ self.inputs[i]:cleanup()
+ table.remove(self.inputs, i)
end
end
function module_list:cleanup()
- for _, module in ipairs(self.modules) do
- log.printf(log.INFO, "removing module: " .. module.name)
+ for _, module in ipairs(self.inputs) do
+ log.printf(log.INFO, "removing input module: " .. module.name)
module:cleanup()
end
- self.modules = {}
+ if(self.output ~= nil) then
+ log.printf(log.INFO, "removing output module: " .. self.output.name)
+ self.output:cleanup()
+ end
+ self.inputs = {}
end
diff --git a/src/modules/debug_shell.lua b/src/modules/debug_shell.lua
index 72be4e7..291fc0f 100644
--- a/src/modules/debug_shell.lua
+++ b/src/modules/debug_shell.lua
@@ -232,6 +232,7 @@ function debug_shell:exec_cmd(socket)
elseif(cmd == 'help') then
if(sep and sep ~= "") then socket.out_buffer = socket.out_buffer .. "unknown command\n" end
socket.out_buffer = socket.out_buffer .. "!<lua code> execute lua code\n" ..
+ "cmd <cmd> add the command to the command queue\n" ..
"quit quit this debug session\n" ..
"ping[ <data>] echo request (response will be 'pong[ <data>]')\n" ..
"disable close this debug shell instance and close all connections\n" ..
@@ -240,6 +241,12 @@ function debug_shell:exec_cmd(socket)
elseif(cmd == 'ping') then
if(sep == ' ') then socket.out_buffer = socket.out_buffer .. "pong " .. (param or "") .. "\n"
else socket.out_buffer = socket.out_buffer .. "pong\n" end
+ elseif(cmd == 'cmd') then
+ if(not param or param == '') then socket.out_buffer = socket.out_buffer .. "Error: please specify a command\n"
+ else
+ socket.out_buffer = socket.out_buffer .. "enqueing command: " .. param .. "\n"
+ command_queue:enqueue(param, nil, nil)
+ end
else
socket.out_buffer = socket.out_buffer .. "unknown command\n"
end