Skip to content

Commit 6990604

Browse files
committed
lib+driver+common: Tidy up signal handling & move it to driver
Another old remnant of when c-ray was a standalone program, the renderer was hooking SIGINT internally. Now we do that in the driver, and use the public API to tell the renderer to stop when ^C is invoked. Also removed the useless wrapper around signal(3).
1 parent 0250d1a commit 6990604

File tree

7 files changed

+53
-95
lines changed

7 files changed

+53
-95
lines changed

include/c-ray/c-ray.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ struct cr_renderer_cb_info {
9393
size_t finished_passes;
9494
double completion;
9595
bool paused;
96-
bool aborted;
9796
};
9897

9998
enum cr_renderer_callback {

src/common/platform/signal.c

Lines changed: 0 additions & 43 deletions
This file was deleted.

src/common/platform/signal.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,17 @@
88

99
#pragma once
1010

11-
enum sigtype {
12-
sigint,
13-
sigabrt,
14-
};
15-
16-
int registerHandler(enum sigtype, void (*handler)(int));
11+
#if !defined(WINDOWS) && !defined(__APPLE__)
12+
#include <signal.h>
13+
#endif
1714

1815
// By default, signals may be delivered to any running thread
1916
// so block them in background threads.
2017
// Thanks to jart for this TIL, I saw it in cosmo turfwar.c
21-
void block_signals(void);
18+
static inline void block_signals(void) {
19+
#if !defined(WINDOWS) && !defined(__APPLE__)
20+
sigset_t mask;
21+
sigfillset(&mask);
22+
sigprocmask(SIG_SETMASK, &mask, 0);
23+
#endif
24+
}

src/common/platform/terminal.c

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@
1818
#include <unistd.h>
1919
#endif
2020

21-
#include "signal.h"
22-
#include "../logging.h"
23-
2421
bool isTeleType(void) {
2522
#ifdef WINDOWS
2623
return _isatty(_fileno(stdout));
@@ -36,20 +33,7 @@ static void show_cursor(bool show) {
3633
#endif
3734
}
3835

39-
//FIXME: This doesn't perform cleanup
40-
static void handler(int sig) {
41-
if (sig == 2) { //SIGINT
42-
printf("\n");
43-
logr(info, "Aborting initialization.\n");
44-
term_restore();
45-
exit(0);
46-
}
47-
}
48-
4936
void term_init(void) {
50-
if (registerHandler(sigint, handler)) {
51-
logr(warning, "Unable to catch SIGINT\n");
52-
}
5337
//If we're on a reasonable (non-windows) terminal, hide the cursor.
5438
#ifndef WINDOWS
5539
//Disable output buffering

src/driver/main.c

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
//
88

99
#include <c-ray/c-ray.h>
10+
#include <errno.h>
11+
#include <signal.h>
1012
#include <v.h>
1113

1214
#include <imagefile.h>
@@ -21,8 +23,30 @@
2123
#include <args.h>
2224
#include <sdl.h>
2325

26+
// Before render, just exit without cleaning up
27+
// FIXME: Consider performing cleanup here too
28+
static void s_sigint_init(int sig) {
29+
if (sig != SIGINT)
30+
return;
31+
logr(plain, "\n");
32+
logr(info, "Aborting initialization.\n");
33+
term_restore();
34+
exit(0);
35+
}
36+
37+
static int g_sigint_flag = 0;
38+
39+
// Set flag to allow renderer to exit gracefully
40+
static void s_sigint_flag(int sig) {
41+
if (sig == SIGINT && !g_sigint_flag) {
42+
logr(plain, "\n");
43+
logr(info, "Received ^C, aborting render without saving\n");
44+
g_sigint_flag = 1;
45+
}
46+
}
47+
2448
struct cb_context {
25-
struct cr_renderer *r;
49+
struct cr_renderer *r; // TODO: Pass in cr_renderer_cb_info directly
2650
struct sdl_window *w;
2751
bool skip_save;
2852

@@ -69,15 +93,18 @@ static void on_stop(struct cr_renderer_cb_info *info, void *user_data) {
6993
struct cb_context *d = user_data;
7094
if (d->w)
7195
win_destroy(d->w);
72-
if (info->aborted)
73-
d->skip_save = true;
7496
}
7597

7698
static void status(struct cr_renderer_cb_info *state, void *user_data) {
7799
static int pauser = 0;
78100
struct cb_context *d = user_data;
79101
if (!d)
80102
return;
103+
if (g_sigint_flag) {
104+
d->skip_save = true;
105+
cr_renderer_stop(d->r);
106+
g_sigint_flag = 0;
107+
}
81108
if (d->w) {
82109
enum input_event e = win_update(d->w, state->tiles, state->tiles_count);
83110
switch (e) {
@@ -114,6 +141,8 @@ static void status(struct cr_renderer_cb_info *state, void *user_data) {
114141
int main(int argc, char *argv[]) {
115142
term_init();
116143
atexit(term_restore);
144+
if (signal(SIGINT, s_sigint_init) == SIG_ERR)
145+
logr(error, "signal(SIGINT, s_sigint_init) == SIG_ERR: %s", strerror(errno));
117146
logr(info, "c-ray v%s [%.8s], © 2015-2025 Valtteri Koskivuori\n", cr_get_version(), cr_get_git_hash());
118147

119148
struct driver_args *opts = args_parse(argc, argv);
@@ -285,6 +314,10 @@ int main(int argc, char *argv[]) {
285314
KNRM,
286315
PLURAL(threads));
287316

317+
// FIXME: There is a gap between this call and when the renderer will
318+
// actually respond to a renderer_stop() call, maybe do something about that.
319+
if (signal(SIGINT, s_sigint_flag) == SIG_ERR)
320+
logr(error, "signal(SIGINT, s_sigint_flag) == SIG_ERR: %s", strerror(errno));
288321
v_timer timer = v_timer_start();
289322
cr_renderer_render(renderer);
290323
long ms = v_timer_get_ms(timer);

src/lib/protocol/worker.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ void exitHandler(int sig) {
375375

376376
int worker_start(int port, size_t thread_limit) {
377377
signal(SIGPIPE, SIG_IGN);
378-
if (registerHandler(sigint, exitHandler) < 0) {
378+
if (signal(SIGINT, exitHandler) == SIG_ERR) {
379379
logr(error, "registerHandler failed\n");
380380
}
381381
int receivingSocket, connectionSocket;

src/lib/renderer/renderer.c

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,6 @@
3030
#define paused_msec 100
3131
#define active_msec 16
3232

33-
static bool g_aborted = false;
34-
35-
// FIXME: c-ray is a library now, so just setting upa global handler like this
36-
// is a bit ugly.
37-
void sigHandler(int sig) {
38-
if (sig == 2) { //SIGINT
39-
logr(plain, "\n");
40-
logr(info, "Received ^C, aborting render without saving\n");
41-
g_aborted = true;
42-
}
43-
}
44-
4533
static void print_stats(const struct world *scene) {
4634
uint64_t polys = 0;
4735
uint64_t vertices = 0;
@@ -145,12 +133,6 @@ void update_toplevel_bvh(struct world *s) {
145133

146134
// TODO: Clean this up, it's ugly.
147135
void renderer_render(struct renderer *r) {
148-
//Check for CTRL-C
149-
// TODO: Move signal to driver
150-
if (registerHandler(sigint, sigHandler)) {
151-
logr(warning, "Unable to catch SIGINT\n");
152-
}
153-
154136
struct camera *camera = &r->scene->cameras[r->prefs.selected_camera];
155137
if (r->prefs.override_width && r->prefs.override_height) {
156138
camera->width = r->prefs.override_width ? (int)r->prefs.override_width : camera->width;
@@ -292,7 +274,7 @@ void renderer_render(struct renderer *r) {
292274
w->thread_ctx.thread_fn = render_single_iteration;
293275
while (r->state.s == r_rendering) {
294276
w->thread_ctx.thread_fn(w->thread_ctx.ctx);
295-
if (g_aborted || w->thread_complete)
277+
if (w->thread_complete)
296278
break;
297279
struct callback status = r->state.callbacks[cr_cb_status_update];
298280
if (status.fn) {
@@ -306,9 +288,10 @@ void renderer_render(struct renderer *r) {
306288
while (r->state.s == r_rendering) {
307289
size_t inactive = 0;
308290
for (size_t w = 0; w < v_arr_len(r->state.workers); ++w) {
309-
if (r->state.workers[w].thread_complete) inactive++;
291+
if (r->state.workers[w].thread_complete)
292+
inactive++;
310293
}
311-
if (g_aborted || inactive == v_arr_len(r->state.workers))
294+
if (inactive == v_arr_len(r->state.workers))
312295
break;
313296

314297
struct callback status = r->state.callbacks[cr_cb_status_update];
@@ -332,11 +315,10 @@ void renderer_render(struct renderer *r) {
332315
struct callback stop = r->state.callbacks[cr_cb_on_stop];
333316
if (stop.fn) {
334317
update_cb_info(r, &set, &cb_info);
335-
if (g_aborted)
336-
cb_info.aborted = true;
337318
stop.fn(&cb_info, stop.user_data);
338319
}
339-
if (info_tiles) free(info_tiles);
320+
if (info_tiles)
321+
free(info_tiles);
340322
tile_set_free(&set);
341323
logr(info, "Renderer exiting\n");
342324
r->state.s = r_idle;

0 commit comments

Comments
 (0)