zlib.release_gvl.patch

Eric Hodel, 06/21/2012 09:20 AM

Download (2.32 KB)

View differences:

ext/zlib/zlib.c (working copy)
72 72

  
73 73
struct zstream;
74 74
struct zstream_funcs;
75
struct zstream_run_args;
75 76
static void zstream_init(struct zstream*, const struct zstream_funcs*);
76 77
static void zstream_expand_buffer(struct zstream*);
77 78
static void zstream_expand_buffer_into(struct zstream*, unsigned long);
......
557 558
#define ZSTREAM_AVAIL_OUT_STEP_MIN    2048
558 559

  
559 560
static const struct zstream_funcs deflate_funcs = {
560
    deflateReset, deflateEnd, deflate,
561
    deflateReset, deflateEnd, deflate
561 562
};
562 563

  
563 564
static const struct zstream_funcs inflate_funcs = {
564
    inflateReset, inflateEnd, inflate,
565
    inflateReset, inflateEnd, inflate
565 566
};
566 567

  
568
struct zstream_run_args {
569
    struct zstream * z;
570
    int flush;
571
};
567 572

  
568 573
static voidpf
569 574
zlib_mem_alloc(voidpf opaque, uInt items, uInt size)
......
871 876
    return Qnil;
872 877
}
873 878

  
879
static VALUE
880
zstream_run_func(void *ptr) {
881
    struct zstream_run_args *args = (struct zstream_run_args *)ptr;
882
    int err, flush = args->flush;
883
    struct zstream *z = args->z;
884
    uInt n;
885

  
886
    n = z->stream.avail_out;
887
    err = z->func->run(&z->stream, flush);
888
    z->buf_filled += n - z->stream.avail_out;
889

  
890
    return (VALUE)err;
891
}
892

  
893
/*
894
 * There is no safe way to interrupt z->run->func().
895
 */
896
static void
897
zstream_unblock_func(void *ptr) {
898
}
899

  
874 900
static void
875 901
zstream_run(struct zstream *z, Bytef *src, long len, int flush)
876 902
{
877
    uInt n;
903
    struct zstream_run_args args;
878 904
    int err;
879 905
    volatile VALUE guard = Qnil;
880 906

  
907
    args.z = z;
908
    args.flush = flush;
909

  
881 910
    if (NIL_P(z->input) && len == 0) {
882 911
	z->stream.next_in = (Bytef*)"";
883 912
	z->stream.avail_in = 0;
......
900 929
	/* VC allocates err and guard to same address.  accessing err and guard
901 930
	   in same scope prevents it. */
902 931
	RB_GC_GUARD(guard);
903
	n = z->stream.avail_out;
904
	err = z->func->run(&z->stream, flush);
905
	z->buf_filled += n - z->stream.avail_out;
906
	rb_thread_schedule();
932

  
933
	err = (int)rb_thread_blocking_region(
934
		zstream_run_func, (void *)&args,
935
		zstream_unblock_func, NULL);
907 936

  
908 937
	if (err == Z_STREAM_END) {
909 938
	    z->flags &= ~ZSTREAM_FLAG_IN_STREAM;