140 {
143
145
146 int one = 1;
147 int sock = socket(AF_INET, SOCK_STREAM, 0);
148 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int));
149
150 int port = 8080;
151 struct sockaddr_in a = {
152 .sin_family = AF_INET,
153 .sin_addr = {INADDR_ANY},
154 .sin_port = htons(port),
155 };
156
157 if (sock < 0 || bind(sock, (struct sockaddr *)&a, sizeof(a)) != 0 || listen(sock, 128) != 0) {
158 perror("listener setup");
159 return 1;
160 }
161
163 socklen_t al = sizeof(a);
164 if (getsockname(sock, (struct sockaddr *)&a, &al) != 0) {
165 perror("getsockname");
166 return 1;
167 }
168
169 printf("Running the webserver on 0.0.0.0:%d\n", port);
173
175 close(sock);
176
179 return 0;
180}
static srn_fiber_result_t server(srn_context_t *ctx, void *arg)
static void set_nonblock(int fd)
static atomic_uint counter
srn_context_t * srn_context_make(srn_engine_t *engine)
Make an empty context, by allocating a new memory block.
int srn_context_release(srn_context_t *ctx)
srn_fiber_t * srn_fiber_spawn(srn_context_t *ctx, srn_fiber_entry_t entry, void *arg)
Make and schedule a fiber with every default, the engine's scheduler, the configured stack size,...
#define SERENE_RUNTIME_SHUTDOWN(engine)
Tear down what SERENE_RUNTIME_INIT brought up, in reverse order, the engine (reactor,...
#define SERENE_RUNTIME_INIT_WITH_SCHED(engine, sched, config)
SERENE_RUNTIME_INIT plus a sched variable bound to the engine's scheduler, which every run and fiber ...
void srn_sched_run(srn_scheduler_t *sched, size_t nworkers)
Run the scheduler with nworkers os threads draining it, returning once the pool goes quiescent (every...
#define SRN_TRACEPOINT(name,...)
Placement matters.