Skip to content

Commit b48e08b

Browse files
committed
Rewrite to be safer
1 parent 2bc70d9 commit b48e08b

File tree

3 files changed

+14
-13
lines changed

3 files changed

+14
-13
lines changed

NEWS

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
0.8.3.1
1+
0.8.6
22
- save_gif() now properly closes graphics device when expr errors
3+
- safer C code to prevent segfaults on write errors

src/Makevars.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ PKG_CFLAGS = -pthread
44
PKG_LIBS = -L$(LIBDIR) -lmyrustlib -lresolv -pthread
55
CARGO = @cargobin@
66

7-
all: clean
7+
#all: clean
88

99
$(SHLIB): $(STATLIB)
1010

src/wrapper.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,15 @@
88

99
/* data to pass to encoder thread */
1010
typedef struct {
11-
int complete;
1211
const char * path;
12+
GifskiError err;
1313
gifski * g;
1414
} gifski_encoder_thread_info;
1515

1616
/* gifski_write() blocks until main thread calls gifski_end_adding_frames() */
1717
void * gifski_encoder_thread(void * data){
1818
gifski_encoder_thread_info * info = data;
19-
if(gifski_write(info->g, info->path) != GIFSKI_OK)
20-
REprintf("Failure writing to '%s'\n", info->path);
21-
gifski_drop(info->g);
22-
info->complete = 1;
19+
info->err = gifski_write(info->g, info->path);
2320
return NULL;
2421
}
2522

@@ -39,20 +36,18 @@ SEXP R_png_to_gif(SEXP png_files, SEXP gif_file, SEXP width, SEXP height, SEXP d
3936

4037
/* create encoder thread; TODO: maybe we can use multiple encoder threads? */
4138
pthread_t encoder_thread;
42-
gifski_encoder_thread_info info = {0, CHAR(STRING_ELT(gif_file, 0)), g};
39+
gifski_encoder_thread_info info = {CHAR(STRING_ELT(gif_file, 0)), GIFSKI_OK, g};
4340
if(pthread_create(&encoder_thread, NULL, gifski_encoder_thread, &info))
4441
Rf_error("Failed to create encoder thread");
4542

4643
/* add png frames in main thread */
4744
for(size_t i = 0; i < Rf_length(png_files); i++){
48-
if(info.complete){
49-
gifski_drop(g);
50-
Rf_error("Writer thread has died");
51-
}
45+
if(info.err != GIFSKI_OK)
46+
goto cleanup;
5247
if(gifski_add_frame_png_file(g, i, CHAR(STRING_ELT(png_files, i)), Rf_asInteger(delay)) != GIFSKI_OK)
5348
Rprintf("Failed to add frame %d\n", i);
5449
if(Rf_asLogical(progress))
55-
Rprintf("\rFrame %d (%d%%)", i, (i+1) * 100 / Rf_length(png_files));
50+
Rprintf("\rFrame %d (%d%%)", (i+1), (i+1) * 100 / Rf_length(png_files));
5651
}
5752

5853
/* This will finalize the encoder thread as well */
@@ -65,6 +60,11 @@ SEXP R_png_to_gif(SEXP png_files, SEXP gif_file, SEXP width, SEXP height, SEXP d
6560
/* wait for the encoder thread to finish */
6661
if(pthread_join(encoder_thread, NULL))
6762
Rf_error("Failed to join encoder_thread");
63+
64+
cleanup:
65+
gifski_drop(g);
66+
if(info.err != GIFSKI_OK)
67+
Rf_error("Failure writing image %s", info.path);
6868
return gif_file;
6969
}
7070

0 commit comments

Comments
 (0)