diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2023-08-13 01:53:28 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2023-08-13 02:30:06 +0200 |
| commit | 0e2f46e4887618ce45e979d939d1329312ecaacd (patch) | |
| tree | e31ce8dd88d0343e4f12837535893a8daf43c13c | |
| parent | f6562ddab30feb4bb63d9cda9801dbf607c33d07 (diff) | |
WIP parallelparallel
| -rw-r--r-- | CMakeLists.txt | 2 | ||||
| -rw-r--r-- | handler.c | 21 | ||||
| -rw-r--r-- | http.c | 16 | ||||
| -rw-r--r-- | include/slweb/handler.h | 2 | ||||
| -rw-r--r-- | include/slweb/http.h | 9 | ||||
| -rw-r--r-- | include/slweb/server.h | 1 | ||||
| -rw-r--r-- | server.c | 8 |
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) @@ -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 @@ -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 */ @@ -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); |
