@velox0/cerver 0.6.2-nightly.20260531.8 → 0.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Makefile CHANGED
@@ -1,5 +1,8 @@
1
1
  CC ?= cc
2
- CFLAGS ?= -std=c11 -Wall -Wextra -O2 -D_GNU_SOURCE
2
+ CFLAGS ?= -std=c11 -Wall -Wextra -O2
3
+ WIN_CC ?= x86_64-w64-mingw32-gcc
4
+ WIN_CFLAGS ?= -std=c11 -Wall -Wextra -O2 -D_WIN32_WINNT=0x0601 -DWIN32_LEAN_AND_MEAN -DCERVER_NO_CURL
5
+ WIN_LDFLAGS ?= -lws2_32 -lmswsock -ladvapi32
3
6
 
4
7
  RUNTIME_SRCS = \
5
8
  runtime/http_parser.c \
@@ -13,8 +16,14 @@ RUNTIME_SRCS = \
13
16
  TEST_SRCS = runtime/tests/runtime_tests.c \
14
17
  runtime/tests/minunit.c
15
18
  TEST_BIN = build/runtime_tests
19
+ WIN_TEST_BIN = build/runtime_tests.exe
20
+ WIN_OBJ = build/server.win.o
16
21
 
17
- .PHONY: test-runtime clean
22
+ .PHONY: test tests test-runtime test-windows clean
23
+
24
+ test: test-runtime test-windows
25
+
26
+ tests: test
18
27
 
19
28
  test-runtime: $(TEST_BIN)
20
29
  ./$(TEST_BIN)
@@ -23,5 +32,15 @@ $(TEST_BIN): $(RUNTIME_SRCS) $(TEST_SRCS) runtime/cerver.h
23
32
  mkdir -p build
24
33
  $(CC) $(CFLAGS) -Iruntime -o $(TEST_BIN) $(RUNTIME_SRCS) $(TEST_SRCS) -pthread -lcurl
25
34
 
35
+ test-windows: $(WIN_TEST_BIN) $(WIN_OBJ)
36
+
37
+ $(WIN_TEST_BIN): $(RUNTIME_SRCS) $(TEST_SRCS) runtime/cerver.h
38
+ mkdir -p build
39
+ $(WIN_CC) $(WIN_CFLAGS) -Iruntime -o $(WIN_TEST_BIN) $(RUNTIME_SRCS) $(TEST_SRCS) $(WIN_LDFLAGS)
40
+
41
+ $(WIN_OBJ): runtime/server.c runtime/cerver.h
42
+ mkdir -p build
43
+ $(WIN_CC) $(WIN_CFLAGS) -Iruntime -c runtime/server.c -o $(WIN_OBJ)
44
+
26
45
  clean:
27
46
  rm -rf build
package/WINDOWS.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Cerver on Windows
2
2
 
3
- Cerver compiles your routes to native C and links against pthreads and (optionally) libcurl.
4
- On Windows you need a C toolchain that provides these. Two easy options:
3
+ Cerver compiles your routes to native C and links against Winsock2 and (optionally) libcurl.
4
+ On Windows you need a C toolchain that can build a console executable. Two easy options:
5
5
 
6
6
  ---
7
7
 
@@ -13,7 +13,7 @@ On Windows you need a C toolchain that provides these. Two easy options:
13
13
 
14
14
  ```bash
15
15
  # MinGW-w64 (recommended for standalone .exe)
16
- pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-pthreads
16
+ pacman -S mingw-w64-x86_64-gcc
17
17
 
18
18
  # If you want fetch() support (outbound HTTP):
19
19
  pacman -S mingw-w64-x86_64-curl
@@ -28,17 +28,11 @@ On Windows you need a C toolchain that provides these. Two easy options:
28
28
 
29
29
  ---
30
30
 
31
- ## Option B — LLVM/Clang for Windows + pthreads4w
31
+ ## Option B — LLVM/Clang for Windows
32
32
 
33
33
  1. Install Clang from https://releases.llvm.org/ (choose the Windows installer).
34
34
 
35
- 2. Download and install **pthreads4w** from https://sourceforge.net/projects/pthreads4w/
36
- (or clone + build from https://github.com/jwinarske/pthreads4w).
37
-
38
- 3. Place the pthreads4w headers and `.a` / `.lib` somewhere on your PATH / in a standard
39
- location (e.g. `C:\pthreads4w`). Cerver's compiler probe will find them automatically.
40
-
41
- 4. If you want `fetch()` support, install libcurl for Windows from https://curl.se/windows/
35
+ 2. If you want `fetch()` support, install libcurl for Windows from https://curl.se/windows/
42
36
  and add it to PATH / link path.
43
37
 
44
38
  ---
@@ -61,7 +55,7 @@ The `build` command produces `dist\server.exe`. The `run` command executes it d
61
55
  | Symptom | Fix |
62
56
  |---|---|
63
57
  | `no C compiler found` | Add `gcc` or `clang` to `PATH`; see Option A/B above |
64
- | `undefined reference to pthread_*` | Install pthreads-win32 (MSYS2: `pacman -S mingw-w64-x86_64-pthreads`) |
58
+ | thread runtime compiler errors | Make sure you are using the bundled runtime headers from the same Cerver version |
65
59
  | `undefined reference to curl_*` | Install libcurl and ensure `libcurl.a` / `libcurl.dll.a` are findable |
66
60
  | `WSAStartup failed` | Should not happen; report a bug |
67
61
  | `cerver build` passes but binary crashes | Run from the project root, not from `dist\` |
@@ -155,7 +155,7 @@ async function build(opts) {
155
155
  /* ---- 7. Compile ---- */
156
156
  console.log(" → compiling...");
157
157
  if (process.platform === "win32") {
158
- console.log(" Windows target — ensure gcc/clang + pthreads-win32 are on PATH");
158
+ console.log(" Windows target — ensure gcc/clang is on PATH");
159
159
  }
160
160
 
161
161
  /* Detect if any route uses fetch() — only link libcurl when needed */
@@ -61,38 +61,6 @@ function supportsFlag(cc, flag) {
61
61
  }
62
62
  }
63
63
 
64
- /* ------------------------------------------------------------------ */
65
- /* Windows: locate pthreads-win32 / pthreads4w */
66
- /* ------------------------------------------------------------------ */
67
-
68
- function findPthreadsWin(cc) {
69
- // Try common install locations for pthreads-win32/pthreads4w.
70
- // MSYS2/MinGW installs it to the mingw64 tree; standalone
71
- // pthreads4w may be in C:\pthreads4w or C:\pthreads-win32.
72
- const candidates = [
73
- // MSYS2 MinGW-w64
74
- "C:\\msys64\\mingw64",
75
- "C:\\msys64\\ucrt64",
76
- "C:\\msys2\\mingw64",
77
- // WinLibs / standalone
78
- "C:\\mingw64",
79
- "C:\\mingw-w64",
80
- // pthreads4w default install
81
- "C:\\pthreads4w",
82
- "C:\\pthreads-win32",
83
- ];
84
-
85
- for (const base of candidates) {
86
- const inc = path.join(base, "include");
87
- const lib = path.join(base, "lib");
88
- const h = path.join(inc, "pthread.h");
89
- // Accept if header exists
90
- if (fs.existsSync(h)) return { inc, lib };
91
- }
92
-
93
- return null; // caller will warn and continue without explicit -I/-L
94
- }
95
-
96
64
  /* ------------------------------------------------------------------ */
97
65
  /* Main compile function */
98
66
  /* ------------------------------------------------------------------ */
@@ -158,13 +126,6 @@ function compile(distDir, runtimeDir, opts) {
158
126
  /* Windows: link Winsock2, ws2_32 required for socket API */
159
127
  args.push("-lws2_32");
160
128
 
161
- /* pthreads — try to point the compiler at a local install */
162
- const pt = findPthreadsWin(cc);
163
- if (pt) {
164
- args.push(`-I${pt.inc}`, `-L${pt.lib}`);
165
- }
166
- args.push("-lpthread");
167
-
168
129
  /* libcurl for fetch() */
169
130
  if (opts && opts.usesFetch) {
170
131
  args.push("-lcurl");
@@ -177,7 +138,7 @@ function compile(distDir, runtimeDir, opts) {
177
138
  /* Produce a console binary (not a GUI window) */
178
139
  args.push("-mconsole");
179
140
  } else {
180
- /* POSIX: pthreads + optional libcurl */
141
+ /* POSIX: thread support + optional libcurl */
181
142
  args.push("-lpthread");
182
143
  if (opts && opts.usesFetch) {
183
144
  args.push("-lcurl");
@@ -234,7 +195,7 @@ function compile(distDir, runtimeDir, opts) {
234
195
  throw new Error(
235
196
  `cerver: compilation failed (exit code ${err.status})\n` +
236
197
  (IS_WINDOWS
237
- ? " Tip: ensure gcc/clang, pthreads-win32, and (if using fetch) libcurl are installed."
198
+ ? " Tip: ensure gcc/clang and (if using fetch) libcurl are installed."
238
199
  : "")
239
200
  );
240
201
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@velox0/cerver",
3
- "version": "0.6.2-nightly.20260531.8",
3
+ "version": "0.6.3",
4
4
  "description": "Compile restricted JavaScript server logic into optimized native C binaries (cross-platform: Linux, macOS, Windows)",
5
5
  "main": "bin/cerver.js",
6
6
  "bin": {
package/runtime/cerver.h CHANGED
@@ -13,7 +13,6 @@
13
13
 
14
14
  #include <stddef.h>
15
15
  #include <stdint.h>
16
- #include <pthread.h>
17
16
 
18
17
  /* ------------------------------------------------------------------ */
19
18
  /* Limits */
@@ -36,9 +35,9 @@
36
35
  #define CERVER_MAX_EVENTS 256
37
36
  #define CERVER_LISTEN_BACKLOG 4096
38
37
 
39
- /* Worker architecture */
40
- #define CERVER_THREAD_POOL_DEFAULT 4
41
- #define CERVER_TASK_QUEUE_SIZE 1024
38
+ /* Connection worker architecture */
39
+ #define CERVER_CONNECTION_WORKER_DEFAULT 4
40
+ #define CERVER_TASK_QUEUE_SIZE 1024
42
41
 
43
42
  /* Stat cache for filesystem serving */
44
43
  #define CERVER_STAT_CACHE_SIZE 256
@@ -180,7 +179,7 @@ typedef struct {
180
179
 
181
180
  typedef struct {
182
181
  cerver_stat_entry_t entries[CERVER_STAT_CACHE_SIZE];
183
- pthread_mutex_t lock;
182
+ cerver_mutex_t lock;
184
183
  } cerver_stat_cache_t;
185
184
 
186
185
  /* ------------------------------------------------------------------ */
@@ -190,18 +189,18 @@ typedef struct {
190
189
  typedef cerver_handler_fn (*cerver_dispatch_fn)(cerver_request_t* req);
191
190
 
192
191
  /* ------------------------------------------------------------------ */
193
- /* Worker state (per-core event loop) */
192
+ /* Acceptor state (per-core event loop) */
194
193
  /* ------------------------------------------------------------------ */
195
194
 
196
195
  typedef struct cerver_server cerver_server_t;
197
196
 
198
197
  typedef struct {
199
- int id;
200
- int event_fd; /* kqueue or epoll fd */
201
- int listen_fd; /* per-worker on Linux, shared on macOS */
202
- cerver_server_t* srv;
203
- pthread_t thread;
204
- } cerver_worker_t;
198
+ int id;
199
+ int event_fd; /* kqueue or epoll fd */
200
+ cerver_sock_t listen_fd; /* per-acceptor on Linux, shared on macOS */
201
+ cerver_server_t* srv;
202
+ cerver_acceptor_thread_t thread;
203
+ } cerver_acceptor_t;
205
204
 
206
205
  /* ------------------------------------------------------------------ */
207
206
  /* Server */
@@ -209,7 +208,7 @@ typedef struct {
209
208
 
210
209
  struct cerver_server {
211
210
  int port;
212
- int sock_fd;
211
+ cerver_sock_t sock_fd;
213
212
  cerver_route_t* routes;
214
213
  int route_count;
215
214
  cerver_asset_t* assets;
@@ -223,10 +222,10 @@ struct cerver_server {
223
222
  /* Stat cache for filesystem serving */
224
223
  cerver_stat_cache_t stat_cache;
225
224
 
226
- /* Worker pool */
227
- int worker_count; /* configured connection worker count */
228
- int acceptor_count; /* actual acceptor thread count */
229
- cerver_worker_t* workers;
225
+ /* Connection worker pool */
226
+ int connection_worker_count; /* configured connection worker count */
227
+ int acceptor_count; /* actual acceptor thread count */
228
+ cerver_acceptor_t* acceptors;
230
229
 
231
230
  /* Route trie for radix/trie-based routing */
232
231
  void* route_trie;
package/runtime/fetch.c CHANGED
@@ -10,10 +10,25 @@
10
10
 
11
11
  #include "cerver.h"
12
12
 
13
- #include <curl/curl.h>
13
+ #include <stdio.h>
14
14
  #include <stdlib.h>
15
15
  #include <string.h>
16
- #include <stdio.h>
16
+
17
+ #if defined(CERVER_NO_CURL)
18
+ char* cerver_fetch(const char* url, const char* method, const char* body, const char** headers) {
19
+ (void)url;
20
+ (void)method;
21
+ (void)body;
22
+ (void)headers;
23
+
24
+ char* empty = malloc(1);
25
+ if (empty) empty[0] = '\0';
26
+ return empty;
27
+ }
28
+
29
+ #else
30
+
31
+ #include <curl/curl.h>
17
32
 
18
33
  /* ------------------------------------------------------------------ */
19
34
  /* Internal write callback for curl */
@@ -50,9 +65,10 @@ static size_t fetch_write_cb(void* contents, size_t size, size_t nmemb, void* us
50
65
  /* Global curl init (thread-safe, called once) */
51
66
  /* ------------------------------------------------------------------ */
52
67
 
53
- static pthread_once_t curl_init_once = PTHREAD_ONCE_INIT;
68
+ static cerver_fetch_global_init_guard_t curl_global_init_guard =
69
+ CERVER_FETCH_GLOBAL_INIT_GUARD_INITIALIZER;
54
70
 
55
- static void curl_global_init_once(void) { curl_global_init(CURL_GLOBAL_DEFAULT); }
71
+ static void init_curl_global_state(void) { curl_global_init(CURL_GLOBAL_DEFAULT); }
56
72
 
57
73
  /* ------------------------------------------------------------------ */
58
74
  /* Public API */
@@ -77,7 +93,7 @@ char* cerver_fetch(const char* url, const char* method, const char* body, const
77
93
  }
78
94
 
79
95
  /* Ensure global curl init */
80
- pthread_once(&curl_init_once, curl_global_init_once);
96
+ cerver_fetch_global_init_guard_run(&curl_global_init_guard, init_curl_global_state);
81
97
 
82
98
  CURL* curl = curl_easy_init();
83
99
  if (!curl) {
@@ -156,3 +172,4 @@ char* cerver_fetch(const char* url, const char* method, const char* body, const
156
172
 
157
173
  return buf.data;
158
174
  }
175
+ #endif // CERVER_NO_CURL
@@ -12,7 +12,11 @@
12
12
  #include <stdio.h>
13
13
  #include <stdlib.h>
14
14
  #include <string.h>
15
+
16
+ #if !CERVER_PLATFORM_WINDOWS
15
17
  #include <strings.h>
18
+ #endif // !CERVER_PLATFORM_WINDOWS
19
+
16
20
  #include <ctype.h>
17
21
 
18
22
  /* ------------------------------------------------------------------ */
@@ -13,6 +13,8 @@
13
13
  #include <string.h>
14
14
  #include <errno.h>
15
15
 
16
+ /* Size formatting uses %zu with unsigned long long cast to avoid MinGW warnings */
17
+
16
18
  #if !CERVER_PLATFORM_WINDOWS
17
19
  #include <unistd.h>
18
20
  #include <sys/uio.h>
package/runtime/mime.c CHANGED
@@ -6,7 +6,11 @@
6
6
  #include "cerver.h"
7
7
 
8
8
  #include <string.h>
9
+
10
+ #if !CERVER_PLATFORM_WINDOWS
9
11
  #include <strings.h>
12
+ #endif // !CERVER_PLATFORM_WINDOWS
13
+
10
14
  #include <ctype.h>
11
15
 
12
16
  typedef struct {
package/runtime/router.c CHANGED
@@ -12,7 +12,10 @@
12
12
  #include <stdio.h>
13
13
  #include <stdlib.h>
14
14
  #include <string.h>
15
+
16
+ #if !CERVER_PLATFORM_WINDOWS
15
17
  #include <strings.h>
18
+ #endif // !CERVER_PLATFORM_WINDOWS
16
19
 
17
20
  /* ------------------------------------------------------------------ */
18
21
  /* Request accessor helpers */