readline-release-gvl-4.patch

Akira Tanaka, 10/22/2013 07:47 PM

Download (7.44 KB)

View differences:

ext/readline/readline.c (working copy)
35 35

  
36 36
#include "ruby/ruby.h"
37 37
#include "ruby/io.h"
38
#include "ruby/thread.h"
38 39

  
39 40
#ifdef HAVE_UNISTD_H
40 41
#include <unistd.h>
......
128 129

  
129 130
static VALUE readline_instream;
130 131
static VALUE readline_outstream;
132
static FILE *readline_rl_instream;
133
static FILE *readline_rl_outstream;
131 134

  
132 135
#if defined HAVE_RL_GETC_FUNCTION
133 136

  
......
135 138
#define rl_getc(f) EOF
136 139
#endif
137 140

  
138
static int readline_getc(FILE *);
141
struct getc_struct {
142
  FILE *input;
143
  int ret;
144
  int err;
145
};
146

  
139 147
static int
140
readline_getc(FILE *input)
148
getc_body(FILE *input)
141 149
{
142
    rb_io_t *ifp = 0;
143
    VALUE c;
144
    if (!readline_instream) return rl_getc(input);
145
    GetOpenFile(readline_instream, ifp);
150
    int fd = fileno(input);
151
    char ch;
152
    ssize_t ss;
153

  
146 154
#if defined(_WIN32)
147 155
    {
148 156
        INPUT_RECORD ir;
......
150 158
        static int prior_key = '0';
151 159
        for (;;) {
152 160
            if (prior_key > 0xff) {
153
                prior_key = rl_getc(rl_instream);
161
                prior_key = rl_getc(input);
154 162
                return prior_key;
155 163
            }
156
            if (PeekConsoleInput((HANDLE)_get_osfhandle(ifp->fd), &ir, 1, &n)) {
164
            if (PeekConsoleInput((HANDLE)_get_osfhandle(fd), &ir, 1, &n)) {
157 165
                if (n == 1) {
158 166
                    if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown) {
159
                        prior_key = rl_getc(rl_instream);
167
                        prior_key = rl_getc(input);
160 168
                        return prior_key;
161 169
                    } else {
162
                        ReadConsoleInput((HANDLE)_get_osfhandle(ifp->fd), &ir, 1, &n);
170
                        ReadConsoleInput((HANDLE)_get_osfhandle(fd), &ir, 1, &n);
163 171
                    }
164 172
                } else {
165
                    HANDLE h = (HANDLE)_get_osfhandle(ifp->fd);
173
                    HANDLE h = (HANDLE)_get_osfhandle(fd);
166 174
                    rb_w32_wait_events(&h, 1, INFINITE);
167 175
                }
168 176
            } else {
......
171 179
        }
172 180
    }
173 181
#endif
174
    c = rb_io_getbyte(readline_instream);
175
    if (NIL_P(c)) return EOF;
176
#ifdef ESC
177
    if (c == INT2FIX(ESC) &&
178
        RL_ISSTATE(RL_STATE_ISEARCH) && /* isn't needed in other states? */
179
        rb_io_read_pending(ifp)) {
180
        int meta = 0;
181
        c = rb_io_getbyte(readline_instream);
182
        if (FIXNUM_P(c) && isascii(FIX2INT(c))) meta = 1;
183
        rb_io_ungetbyte(readline_instream, c);
184
        if (meta) rl_execute_next(ESC);
185
        return ESC;
182

  
183
    ss = read(fd, &ch, 1);
184
    if (ss != 1)
185
        return EOF;
186
    return (unsigned char)ch;
187
}
188

  
189
static void *
190
getc_func(void *data1)
191
{
192
    struct getc_struct *p = data1;
193
    FILE *input = p->input;
194
    errno = 0;
195
    p->ret = getc_body(input);
196
    p->err = errno;
197
    return NULL;
198
}
199

  
200
static int
201
readline_getc(FILE *input)
202
{
203
    struct getc_struct data;
204
    data.input = input;
205
  again:
206
    data.ret = -1;
207
    data.err = 0;
208
    rb_thread_call_without_gvl(getc_func, &data, RUBY_UBF_IO, NULL);
209
    if (data.ret == EOF) {
210
        if (data.err == EINTR)
211
            goto again;
212
        if (data.err == EWOULDBLOCK || data.err == EAGAIN) {
213
            int ret;
214
            ret = rb_wait_for_single_fd(fileno(input), RB_WAITFD_IN, NULL);
215
            if (ret != -1 || errno == EINTR)
216
                goto again;
217
        }
186 218
    }
187
#endif
188
    return FIX2INT(c);
219
    return data.ret;
189 220
}
221

  
190 222
#elif defined HAVE_RL_EVENT_HOOK
191 223
#define BUSY_WAIT 0
192 224

  
......
287 319
    return (VALUE)readline((char *)prompt);
288 320
}
289 321

  
322
static void
323
clear_rl_instream(void)
324
{
325
    if (readline_rl_instream) {
326
        fclose(readline_rl_instream);
327
        if (rl_instream == readline_rl_instream)
328
            rl_instream = NULL;
329
        readline_rl_instream = NULL;
330
    }
331
    readline_instream = Qfalse;
332
}
333

  
334
static void
335
clear_rl_outstream(void)
336
{
337
    if (readline_rl_outstream) {
338
        fclose(readline_rl_outstream);
339
        if (rl_outstream == readline_rl_outstream)
340
            rl_outstream = NULL;
341
        readline_rl_outstream = NULL;
342
    }
343
    readline_outstream = Qfalse;
344
}
345

  
290 346
/*
291 347
 * call-seq:
292 348
 *   Readline.readline(prompt = "", add_hist = false) -> string or nil
......
390 446

  
391 447
    if (readline_instream) {
392 448
        rb_io_t *ifp;
393
        GetOpenFile(readline_instream, ifp);
449
        rb_io_check_initialized(ifp = RFILE(rb_io_taint_check(readline_instream))->fptr);
394 450
        if (ifp->fd < 0) {
395
            if (rl_instream) {
396
                fclose(rl_instream);
397
                rl_instream = NULL;
398
            }
399
            readline_instream = Qfalse;
400
            rb_raise(rb_eIOError, "closed stdin");
451
            clear_rl_instream();
452
            rb_raise(rb_eIOError, "closed readline input");
401 453
        }
402 454
    }
403 455

  
404 456
    if (readline_outstream) {
405 457
        rb_io_t *ofp;
406
        GetOpenFile(readline_outstream, ofp);
458
        rb_io_check_initialized(ofp = RFILE(rb_io_taint_check(readline_outstream))->fptr);
407 459
        if (ofp->fd < 0) {
408
            if (rl_outstream) {
409
                fclose(rl_outstream);
410
                rl_outstream = NULL;
411
            }
412
            readline_outstream = Qfalse;
413
            rb_raise(rb_eIOError, "closed stdout");
460
            clear_rl_outstream();
461
            rb_raise(rb_eIOError, "closed readline output");
414 462
        }
415 463
    }
416 464

  
......
453 501
    return result;
454 502
}
455 503

  
456
static void
457
clear_rl_instream(void)
458
{
459
    rb_io_t *ifp;
460
    if (rl_instream) {
461
        if (readline_instream) {
462
            rb_io_check_initialized(ifp = RFILE(rb_io_taint_check(readline_instream))->fptr);
463
            if (ifp->fd < 0 || fileno(rl_instream) == ifp->fd) {
464
                fclose(rl_instream);
465
                rl_instream = NULL;
466
            }
467
        }
468
        readline_instream = Qfalse;
469
        rl_instream = NULL;
470
    }
471
}
472

  
473 504
/*
474 505
 * call-seq:
475 506
 *   Readline.input = input
......
501 532
            errno = save_errno;
502 533
            rb_sys_fail("fdopen");
503 534
        }
504
        rl_instream = f;
535
        rl_instream = readline_rl_instream = f;
505 536
        readline_instream = input;
506 537
    }
507 538
    return input;
508 539
}
509 540

  
510
static void
511
clear_rl_outstream(void)
512
{
513
    rb_io_t *ofp;
514
    if (rl_outstream) {
515
        if (readline_outstream) {
516
            rb_io_check_initialized(ofp = RFILE(rb_io_taint_check(readline_outstream))->fptr);
517
            if (ofp->fd < 0 || fileno(rl_outstream) == ofp->fd) {
518
                fclose(rl_outstream);
519
                rl_outstream = NULL;
520
            }
521
        }
522
        readline_outstream = Qfalse;
523
        rl_outstream = NULL;
524
    }
525
}
526

  
527 541
/*
528 542
 * call-seq:
529 543
 *   Readline.output = output
......
555 569
            errno = save_errno;
556 570
            rb_sys_fail("fdopen");
557 571
        }
558
        rl_outstream = f;
572
        rl_outstream = readline_rl_outstream = f;
559 573
        readline_outstream = output;
560 574
    }
561 575
    return output;
......
1955 1969

  
1956 1970
    rb_gc_register_address(&readline_instream);
1957 1971
    rb_gc_register_address(&readline_outstream);
1958

  
1959
    readline_s_set_input(mReadline, rb_stdin);
1960 1972
}