Skip to content
This repository was archived by the owner on Mar 21, 2025. It is now read-only.

Commit f1e9792

Browse files
committed
Remove all callback global roots.
1 parent a6093f5 commit f1e9792

File tree

6 files changed

+48
-39
lines changed

6 files changed

+48
-39
lines changed

examples/decode.ml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
let () = Printexc.record_backtrace true
2+
13
let output_int chan n =
24
output_char chan (char_of_int ((n lsr 0) land 0xff));
35
output_char chan (char_of_int ((n lsr 8) land 0xff));
@@ -100,11 +102,13 @@ let process () =
100102
try
101103
Flac.Decoder.process dec;
102104
Flac.Decoder.state dec
103-
with Ogg.Not_enough_data -> (
104-
try
105-
fill ();
106-
process ()
107-
with Ogg.End_of_stream | Ogg.Not_enough_data -> `End_of_stream)
105+
with
106+
| Ogg.End_of_stream -> `End_of_stream
107+
| Ogg.Not_enough_data -> (
108+
try
109+
fill ();
110+
process ()
111+
with Ogg.End_of_stream | Ogg.Not_enough_data -> `End_of_stream)
108112
in
109113
(process, info, meta)
110114
in

src/flac.ml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ module Decoder = struct
103103
external init : t -> unit = "ocaml_flac_decoder_init"
104104

105105
let create ?seek ?tell ?length ?eof ~read ~write () =
106+
let write pcm = write (Array.copy pcm) in
106107
let dec = alloc ~seek ~tell ~length ~eof ~read ~write () in
107108
Gc.finalise cleanup dec;
108109
init dec;
@@ -183,7 +184,7 @@ module Encoder = struct
183184
(string * string) array ->
184185
seek:(int64 -> unit) option ->
185186
tell:(unit -> int64) option ->
186-
write:(bytes -> unit) ->
187+
write:(bytes -> int -> unit) ->
187188
params ->
188189
priv = "ocaml_flac_encoder_alloc"
189190

@@ -193,6 +194,7 @@ module Encoder = struct
193194
let create ?(comments = []) ?seek ?tell ~write p =
194195
if p.channels <= 0 then raise Invalid_data;
195196
let comments = Array.of_list comments in
197+
let write b len = write (Bytes.sub b 0 len) in
196198
let enc = alloc comments ~seek ~tell ~write p in
197199
Gc.finalise cleanup enc;
198200
init enc;

src/flac_ogg.ml

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,16 @@ module Encoder = struct
6767
type priv
6868
type t = { encoder : Flac.Encoder.t; first_pages : Ogg.Page.t list }
6969

70-
external create :
70+
external alloc :
7171
(string * string) array ->
72+
seek:(int64 -> unit) option ->
73+
tell:(unit -> int64) option ->
74+
write:(bytes -> int -> unit) ->
7275
Flac.Encoder.params ->
73-
nativeint ->
74-
(bytes -> unit) ->
75-
priv = "ocaml_flac_encoder_ogg_create"
76+
priv = "ocaml_flac_encoder_alloc"
77+
78+
external cleanup : priv -> unit = "ocaml_flac_cleanup_encoder"
79+
external init : priv -> nativeint -> unit = "ocaml_flac_encoder_ogg_init"
7680

7781
let create ?(comments = []) ~serialno ~write params =
7882
if params.Flac.Encoder.channels <= 0 then raise Flac.Encoder.Invalid_data;
@@ -84,15 +88,18 @@ module Encoder = struct
8488
match !header with
8589
| Some h ->
8690
header := None;
87-
write (Bytes.unsafe_to_string h, Bytes.unsafe_to_string p)
91+
write (h, p)
8892
| None -> header := Some p
8993
in
9094
let write_first_page p = first_pages := p :: !first_pages in
9195
let write =
9296
write_wrap (fun p ->
9397
if !first_pages_parsed then write p else write_first_page p)
9498
in
95-
let enc = create comments params serialno write in
99+
let write b len = write (Bytes.sub_string b 0 len) in
100+
let enc = alloc comments ~seek:None ~tell:None ~write params in
101+
Gc.finalise cleanup enc;
102+
init enc serialno;
96103
first_pages_parsed := true;
97104
assert (!header = None);
98105
{ encoder = Obj.magic (enc, params); first_pages = List.rev !first_pages }

src/flac_ogg_stubs.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,12 @@ CAMLprim value ocaml_flac_decoder_packet_data(value v) {
5959

6060
/* Encoder */
6161

62-
CAMLprim value ocaml_flac_encoder_ogg_create(value comments, value params,
63-
value _serialno, value _write_cb) {
64-
CAMLparam4(comments, params, _serialno, _write_cb);
65-
CAMLlocal2(tmp, ret);
62+
CAMLprim value ocaml_flac_encoder_ogg_init(value _enc, value _serialno) {
63+
CAMLparam2(_enc, _serialno);
6664

6765
intnat serialno = Nativeint_val(_serialno);
6866

69-
ret =
70-
ocaml_flac_encoder_alloc(comments, Val_none, Val_none, _write_cb, params);
71-
ocaml_flac_encoder *enc = Encoder_val(ret);
67+
ocaml_flac_encoder *enc = Encoder_val(_enc);
7268

7369
caml_release_runtime_system();
7470
FLAC__stream_encoder_set_ogg_serial_number(enc->encoder, serialno);
@@ -77,7 +73,7 @@ CAMLprim value ocaml_flac_encoder_ogg_create(value comments, value params,
7773
(void *)&enc->callbacks);
7874
caml_acquire_runtime_system();
7975

80-
CAMLreturn(ret);
76+
CAMLreturn(Val_unit);
8177
}
8278

8379
/* Ogg skeleton interface */

src/flac_stubs.c

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ CAMLprim value ocaml_flac_cleanup_decoder(value e) {
195195
caml_remove_generational_global_root(&dec->callbacks.length_cb);
196196
caml_remove_generational_global_root(&dec->callbacks.write_cb);
197197
caml_remove_generational_global_root(&dec->callbacks.buffer);
198+
caml_remove_generational_global_root(&dec->callbacks.output);
198199

199200
return Val_unit;
200201
}
@@ -328,7 +329,10 @@ static FLAC__bool dec_eof_callback(const FLAC__StreamDecoder *decoder,
328329
value ret = caml_callback(callbacks->eof_cb, Val_unit);
329330
caml_release_runtime_system();
330331

331-
return ret == Val_true;
332+
if (ret == Val_true)
333+
return true;
334+
335+
return false;
332336
}
333337

334338
FLAC__StreamDecoderReadStatus static dec_read_callback(
@@ -383,27 +387,16 @@ dec_write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame,
383387
ocaml_flac_register_thread();
384388
caml_acquire_runtime_system();
385389

386-
value data = caml_alloc_tuple(channels);
387-
caml_register_generational_global_root(&data);
388-
389390
int c, i;
390391
for (c = 0; c < channels; c++) {
391-
Store_field(data, c, caml_alloc(samples * Double_wosize, Double_array_tag));
392+
Store_field(callbacks->output, c,
393+
caml_alloc(samples * Double_wosize, Double_array_tag));
392394
for (i = 0; i < samples; i++)
393-
Store_double_field(Field(data, c), i,
395+
Store_double_field(Field(callbacks->output, c), i,
394396
sample_to_double(buffer[c][i], bps));
395397
}
396398

397-
value ret = caml_callback_exn(callbacks->write_cb, data);
398-
caml_remove_generational_global_root(&data);
399-
400-
if (Is_exception_result(ret)) {
401-
ret = Extract_exception(ret);
402-
caml_remove_generational_global_root(&data);
403-
caml_raise(ret);
404-
}
405-
406-
caml_remove_generational_global_root(&data);
399+
caml_callback(callbacks->write_cb, callbacks->output);
407400

408401
caml_release_runtime_system();
409402

@@ -449,6 +442,9 @@ CAMLprim value ocaml_flac_decoder_alloc_native(value seek, value tell,
449442
dec->callbacks.buffer = caml_alloc_string(dec->callbacks.buflen);
450443
caml_register_generational_global_root(&dec->callbacks.buffer);
451444

445+
dec->callbacks.output = Val_none;
446+
caml_register_generational_global_root(&dec->callbacks.output);
447+
452448
dec->callbacks.info = NULL;
453449
dec->callbacks.meta = NULL;
454450

@@ -471,7 +467,7 @@ CAMLprim value ocaml_flac_decoder_alloc_bytecode(value *argv, int argn) {
471467
CAMLprim value ocaml_flac_decoder_init(value _dec) {
472468
CAMLparam1(_dec);
473469

474-
ocaml_flac_decoder *dec = Decoder_val(dec);
470+
ocaml_flac_decoder *dec = Decoder_val(_dec);
475471

476472
// Intialize decoder
477473
caml_release_runtime_system();
@@ -482,6 +478,9 @@ CAMLprim value ocaml_flac_decoder_init(value _dec) {
482478
FLAC__stream_decoder_process_until_end_of_metadata(dec->decoder);
483479
caml_acquire_runtime_system();
484480

481+
caml_modify_generational_global_root(
482+
&dec->callbacks.output, caml_alloc_tuple(dec->callbacks.info->channels));
483+
485484
CAMLreturn(Val_unit);
486485
}
487486

@@ -656,8 +655,8 @@ enc_write_callback(const FLAC__StreamEncoder *encoder,
656655
if (callbacks->buflen < len)
657656
len = callbacks->buflen;
658657

659-
memcpy(Bytes_val(callbacks->buffer), buffer, len);
660-
caml_callback(callbacks->write_cb, callbacks->buffer);
658+
memcpy(Bytes_val(callbacks->buffer), buffer + pos, len);
659+
caml_callback2(callbacks->write_cb, callbacks->buffer, Val_int(len));
661660

662661
pos += len;
663662
}

src/flac_stubs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ typedef struct ocaml_flac_decoder_callbacks {
4040
value length_cb;
4141
value eof_cb;
4242
value write_cb;
43+
value output;
4344
value buffer;
4445
int buflen;
4546
FLAC__StreamMetadata_StreamInfo *info;

0 commit comments

Comments
 (0)