aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi.dcr@tutanota.com>2023-08-13 01:53:28 +0200
committerXavier Del Campo Romero <xavi.dcr@tutanota.com>2023-08-13 02:30:06 +0200
commit0e2f46e4887618ce45e979d939d1329312ecaacd (patch)
treee31ce8dd88d0343e4f12837535893a8daf43c13c
parentf6562ddab30feb4bb63d9cda9801dbf607c33d07 (diff)
WIP parallelparallel
-rw-r--r--CMakeLists.txt2
-rw-r--r--handler.c21
-rw-r--r--http.c16
-rw-r--r--include/slweb/handler.h2
-rw-r--r--include/slweb/http.h9
-rw-r--r--include/slweb/server.h1
-rw-r--r--server.c8
7 files changed, 51 insertions, 8 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9127b07..8a00d13 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,7 +9,7 @@ add_library(${PROJECT_NAME}
wildcard_cmp.c)
add_subdirectory(dynstr)
target_include_directories(${PROJECT_NAME} PUBLIC include)
-target_link_libraries(${PROJECT_NAME} PUBLIC dynstr)
+target_link_libraries(${PROJECT_NAME} PUBLIC dynstr PRIVATE pthread)
if(BUILD_EXAMPLES)
add_subdirectory(examples)
diff --git a/handler.c b/handler.c
index f29da15..2c63db8 100644
--- a/handler.c
+++ b/handler.c
@@ -4,6 +4,7 @@
#include "slweb/http.h"
#include "slweb/server.h"
#include "slweb/wildcard_cmp.h"
+#include <pthread.h>
#include <errno.h>
#include <stdbool.h>
#include <stddef.h>
@@ -49,7 +50,8 @@ static int on_write(const void *const buf, const size_t n, void *const user)
}
static int on_payload(const struct http_payload *const p,
- struct http_response *const r, void *const user)
+ struct http_response *const r, struct http_future *const f,
+ void *const user)
{
struct client *const c = user;
struct handler *const h = c->h;
@@ -59,7 +61,7 @@ static int on_payload(const struct http_payload *const p,
const struct elem *const e = &h->elem[i];
if (e->op == p->op && !wildcard_cmp(p->resource, e->url, true))
- return e->f(p, r, e->user);
+ return e->f(p, r, f, e->user);
}
fprintf(stderr, "Not found: %s\n", p->resource);
@@ -72,6 +74,20 @@ static int on_payload(const struct http_payload *const p,
return 0;
}
+static void *async_start(void *const user)
+{
+ /* TOOD: call user callback. */
+ return NULL;
+}
+
+static int on_async(const struct http_future *const f, void *const user)
+{
+ struct client *const c = user;
+ struct handler *const h = c->h;
+
+ return server_async(h->server, f->f, f->user);
+}
+
static int on_length(const unsigned long long len,
const struct http_cookie *const c, struct http_response *const r,
void *const user)
@@ -107,6 +123,7 @@ static struct client *find_or_alloc_client(struct handler *const h,
.read = on_read,
.write = on_write,
.payload = on_payload,
+ .async = on_async,
.length = on_length,
.user = ret,
.tmpdir = h->cfg.tmpdir
diff --git a/http.c b/http.c
index 0960d85..22b45d9 100644
--- a/http.c
+++ b/http.c
@@ -2,6 +2,7 @@
#include "slweb/http.h"
#include <dynstr.h>
+#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>
#include <ctype.h>
@@ -909,12 +910,15 @@ static int process_payload(struct http_ctx *const h, const char *const line)
{
struct ctx *const c = &h->ctx;
const struct http_payload p = ctx_to_payload(c);
- const int ret = h->cfg.payload(&p, &h->wctx.r, h->cfg.user);
+ struct http_future f = {0};
+ const int ret = h->cfg.payload(&p, &h->wctx.r, &f, h->cfg.user);
ctx_free(c);
if (ret)
return ret;
+ else if (f.f)
+ return h->cfg.async(&f, h->cfg.user);
return start_response(h);
}
@@ -950,6 +954,7 @@ static int expect(struct http_ctx *const h, const char *const value)
if (!strcmp(value, "100-continue"))
{
struct ctx *const c = &h->ctx;
+ struct http_future f = {0};
const struct http_payload p =
{
.u.post.expect_continue = true,
@@ -963,10 +968,12 @@ static int expect(struct http_ctx *const h, const char *const value)
.resource = c->resource
};
- const int ret = h->cfg.payload(&p, &h->wctx.r, h->cfg.user);
+ const int ret = h->cfg.payload(&p, &h->wctx.r, &f, h->cfg.user);
if (ret)
return ret;
+ else if (f.f)
+ return h->cfg.async(&f, h->cfg.user);
return start_response(h);
}
@@ -1075,12 +1082,15 @@ static int send_payload(struct http_ctx *const h,
const struct http_payload *const p)
{
struct ctx *const c = &h->ctx;
- const int ret = h->cfg.payload(p, &h->wctx.r, h->cfg.user);
+ struct http_future f = {0};
+ const int ret = h->cfg.payload(p, &h->wctx.r, &f, h->cfg.user);
ctx_free(c);
if (ret)
return ret;
+ else if (f.f)
+ return h->cfg.async(&f, h->cfg.user);
return start_response(h);
}
diff --git a/include/slweb/handler.h b/include/slweb/handler.h
index 4ac7f76..ca221aa 100644
--- a/include/slweb/handler.h
+++ b/include/slweb/handler.h
@@ -5,7 +5,7 @@
#include <stddef.h>
typedef int (*handler_fn)(const struct http_payload *p,
- struct http_response *r, void *user);
+ struct http_response *r, struct http_future *f, void *user);
struct handler_cfg
{
diff --git a/include/slweb/http.h b/include/slweb/http.h
index ac1f51a..8ff1920 100644
--- a/include/slweb/http.h
+++ b/include/slweb/http.h
@@ -81,12 +81,19 @@ struct http_response
void (*free)(void *);
};
+struct http_future
+{
+ void *(*f)(void *);
+ void *user;
+};
+
struct http_cfg
{
int (*read)(void *buf , size_t n, void *user);
int (*write)(const void *buf, size_t n, void *user);
int (*payload)(const struct http_payload *p, struct http_response *r,
- void *user);
+ struct http_future *f, void *user);
+ int (*async)(const struct http_future *f, void *user);
int (*length)(unsigned long long len, const struct http_cookie *c,
struct http_response *r, void *user);
const char *tmpdir;
diff --git a/include/slweb/server.h b/include/slweb/server.h
index 74f06ae..fa7db01 100644
--- a/include/slweb/server.h
+++ b/include/slweb/server.h
@@ -11,5 +11,6 @@ int server_write(const void *buf, size_t n, struct server_client *c);
int server_close(struct server *s);
int server_client_close(struct server *s, struct server_client *c);
void server_client_write_pending(struct server_client *c, bool write);
+int server_async(struct server *s, int (*f)(void *), void *user);
#endif /* SERVER_H */
diff --git a/server.c b/server.c
index 01e82b0..a6d28fa 100644
--- a/server.c
+++ b/server.c
@@ -71,6 +71,14 @@ int server_client_close(struct server *const s, struct server_client *const c)
return ret;
}
+int server_async(struct server *const s, int (*const f)(void *),
+ void *const user)
+{
+ /* TODO: register AF_UNIX socket to server. */
+ pthread_t t;
+ pthread_create(&t, NULL, async_start, NULL);
+}
+
int server_read(void *const buf, const size_t n, struct server_client *const c)
{
const ssize_t r = read(c->fd, buf, n);