summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAki <please@ignore.pl>2021-02-24 01:04:57 +0100
committerAki <please@ignore.pl>2021-02-24 01:04:57 +0100
commit4fdf60a4c9ce16dd459e05ad7664010ea45c43db (patch)
treeb826d103c799f9e4b12fe87b1320a4972a8bab33
parenta8bcb7a654691a9a41ba193f16dca38bdd65bfa0 (diff)
downloadplop-4fdf60a4c9ce16dd459e05ad7664010ea45c43db.zip
plop-4fdf60a4c9ce16dd459e05ad7664010ea45c43db.tar.gz
plop-4fdf60a4c9ce16dd459e05ad7664010ea45c43db.tar.bz2
Started progress towards coroutine-based connection handling
-rw-r--r--Makefile11
-rw-r--r--connection.c23
-rw-r--r--connection.h6
-rw-r--r--plop.c51
-rw-r--r--stream.c23
-rw-r--r--stream.h10
6 files changed, 81 insertions, 43 deletions
diff --git a/Makefile b/Makefile
index c1e137f..68c7d65 100644
--- a/Makefile
+++ b/Makefile
@@ -5,13 +5,12 @@ LDLIBS+=-llua5.3
PREFIX?=/usr/local
SHARE?=$(PREFIX)/share
-plop: connection.o main.o plop.o response.o request.o
+plop: connection.o main.o plop.o stream.o
-main.o: plop.h request.h
-plop.o: connection.h plop.h request.h response.h
-request.o: connection.h request.h
-response.o: response.h
-connection.o: connection.h request.h
+main.o: plop.h
+plop.o: connection.h plop.h stream.h
+connection.o: connection.h
+stream.o: stream.h
clean:
rm -f plop *.o
diff --git a/connection.c b/connection.c
index f987d65..055b498 100644
--- a/connection.c
+++ b/connection.c
@@ -15,6 +15,8 @@
/// \return Pointer to connection or NULL if an error occured
struct connection * connection_new(lua_State * L, const int client)
{
+ (void) L; // TODO: Review if lua_State is still needed for connections and server handler.
+
struct connection * c = malloc(sizeof(struct connection));
if (NULL == c)
@@ -25,29 +27,22 @@ struct connection * connection_new(lua_State * L, const int client)
memset(c, 0, sizeof(struct connection));
c->fd = client;
- c->L = lua_newthread(L);
- c->lua_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+ c->ref = LUA_NOREF;
+ c->L = NULL;
return c;
}
-/// Clears the state of connection readying it for new request.
-/// \param c Connection to clear
-void connection_clear(struct connection * c)
-{
- if (NULL != c->request)
- {
- free_request(c->request);
- }
-}
-
/// Frees all resources associated with the connection.
/// \param L Server's Lua state
/// \param c Connection to free
void connection_free(lua_State * L, struct connection * c)
{
- connection_clear(c);
- luaL_unref(L, LUA_REGISTRYINDEX, c->lua_ref);
+ if (LUA_NOREF != c->ref)
+ {
+ luaL_unref(L, LUA_REGISTRYINDEX, c->ref);
+ }
+
close(c->fd); // TODO: Check for errors in close()?
free(c);
}
diff --git a/connection.h b/connection.h
index 3a7b32a..88cd6b8 100644
--- a/connection.h
+++ b/connection.h
@@ -2,16 +2,12 @@
#include <lua.h>
-#include "request.h"
-
struct connection
{
int fd;
- int lua_ref;
+ int ref;
lua_State * L;
- struct request * request;
};
struct connection * connection_new(lua_State *, const int);
-void connection_clear(struct connection *);
void connection_free(lua_State *, struct connection *);
diff --git a/plop.c b/plop.c
index 592fca0..980ce90 100644
--- a/plop.c
+++ b/plop.c
@@ -16,8 +16,7 @@
#include <lualib.h>
#include "connection.h"
-#include "request.h"
-#include "response.h"
+#include "stream.h"
/// Initializes new Lua state for the server.
/// \return Lua state
@@ -139,27 +138,43 @@ int plop_load_handler(lua_State * L, const char * path)
/// \return -1 if an error occured
int plop_handle_client(lua_State * L, struct epoll_event * event)
{
- struct connection * connection = (struct connection *) event->data.ptr;
+ struct connection * c = (struct connection *) event->data.ptr;
+ int nargs = 0;
- if (-1 == parse_request(connection))
+ if (NULL == c->L)
{
- lua_newtable(connection->L);
- lua_pushstring(connection->L, "status");
- lua_pushinteger(connection->L, 400); // TODO: How about a function that generates error responses?
- lua_rawset(connection->L, -3);
- }
- else // TODO: 0 may mean EAGAIN, stuff will be bad very soon from here.
- {
- // TODO: Push the handler to stack earlier to avoid shifting it.
- lua_getglobal(connection->L, "handler");
- lua_insert(connection->L, 1);
- lua_call(connection->L, 5, 1);
+ c->L = lua_newthread(L);
+
+ if (NULL == c->L)
+ {
+ return -1; // TODO: Fail only this connection?
+ }
+
+ c->ref = luaL_ref(L, LUA_REGISTRYINDEX);
+
+ lua_getglobal(c->L, "handler");
+ stream_push_new(c->L, c->fd);
+ nargs = 1;
}
- int result = response_send(connection->L, connection->fd);
- connection_free(L, connection);
+ int result = lua_resume(c->L, NULL, nargs);
+ connection_free(L, c); // TODO: Allow consistent connections?
- return result;
+ switch (result)
+ {
+ case LUA_OK:
+ {
+ return 0;
+ }
+ case LUA_YIELD:
+ {
+ return 0;
+ }
+ default:
+ {
+ return -1;
+ }
+ }
}
/// Accepts awaiting connections if any.
diff --git a/stream.c b/stream.c
new file mode 100644
index 0000000..d6a5254
--- /dev/null
+++ b/stream.c
@@ -0,0 +1,23 @@
+#include "stream.h"
+
+#include <lauxlib.h>
+#include <lua.h>
+
+/// Creates and pushes new Stream into the Lua stack.
+/// \param L Lua state to push to
+/// \param fd File descriptor used by stream
+/// \return TODO
+int stream_push_new(lua_State * L, const int fd)
+{
+ struct stream * s = lua_newuserdata(L, sizeof(struct stream));
+ s->fd = fd;
+
+ if (1 == luaL_newmetatable(L, "stream"))
+ {
+ // TODO: initialize metatable for stream
+ }
+
+ lua_setmetatable(L, -2);
+
+ return LUA_OK;
+}
diff --git a/stream.h b/stream.h
new file mode 100644
index 0000000..5762bc8
--- /dev/null
+++ b/stream.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include <lua.h>
+
+struct stream
+{
+ int fd;
+};
+
+int stream_push_new(lua_State *, const int);