fix: redirect
@cipher1024 I modified your fix. It would produce memory leaks if the code executed by #eval modifies the stdout. Here is the problem. - Your replaces the handler with some new handler `H` and stores the old handler `O` in a `flet`. - Code is executed and replaces the stdout handler with `H'`. The `H`s RC is decremented and `H'`s RC is incremeneted. So far, so good. - Now, the destructor of your `flet` is executed, and it replaces `H'` with `O`, but `H'` RC is not decremented.
This commit is contained in:
parent
123577126c
commit
addbb8dd67
2 changed files with 17 additions and 6 deletions
|
|
@ -336,10 +336,20 @@ struct stream_buffer_delete {
|
|||
}
|
||||
};
|
||||
|
||||
flet<object *> lean_redirect_stdout(object * new_stdout);
|
||||
obj_res lean_redirect_stdout(obj_arg new_stdout);
|
||||
lean_object * lean_io_wrap_handle(FILE *hfile);
|
||||
lean_object *& get_handle_current_stdout();
|
||||
|
||||
struct redirect_helper {
|
||||
object_ref m_old_fp;
|
||||
redirect_helper(object_ref const & new_fp):
|
||||
m_old_fp(lean_redirect_stdout(new_fp.to_obj_arg())) {
|
||||
}
|
||||
~redirect_helper() {
|
||||
lean_dec(lean_redirect_stdout(m_old_fp.to_obj_arg()));
|
||||
}
|
||||
};
|
||||
|
||||
static environment eval_cmd(parser & p) {
|
||||
transient_cmd_scope cmd_scope(p);
|
||||
auto pos = p.pos();
|
||||
|
|
@ -399,8 +409,8 @@ static environment eval_cmd(parser & p) {
|
|||
object_ref r;
|
||||
|
||||
try {
|
||||
object_ref newFP(lean_io_wrap_handle(fp));
|
||||
flet<object *> oldFP(lean_redirect_stdout(newFP.raw()));
|
||||
object_ref new_fp(lean_io_wrap_handle(fp));
|
||||
redirect_helper helper(new_fp);
|
||||
if (p.profiling()) {
|
||||
timeit timer(out.get_text_stream().get_stream(), "eval time");
|
||||
r = object_ref(ir::run_boxed(new_env, fn_name, args.size(), &args[0]));
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ Author: Leonardo de Moura
|
|||
#include <cctype>
|
||||
#include <sys/stat.h>
|
||||
#include "util/io.h"
|
||||
#include "runtime/flet.h"
|
||||
#include "runtime/utf8.h"
|
||||
#include "runtime/object.h"
|
||||
#include "runtime/thread.h"
|
||||
|
|
@ -145,8 +144,10 @@ MK_THREAD_LOCAL_GET(object *, get_handle_current_stdout, g_handle_stdout);
|
|||
MK_THREAD_LOCAL_GET(object *, get_handle_current_stderr, g_handle_stderr);
|
||||
MK_THREAD_LOCAL_GET(object *, get_handle_current_stdin, g_handle_stdin);
|
||||
|
||||
flet<object *> lean_redirect_stdout(object * new_stdout) {
|
||||
return flet<object *>(get_handle_current_stdout(), new_stdout);
|
||||
obj_res lean_redirect_stdout(obj_arg new_stdout) {
|
||||
obj_res r = get_handle_current_stdout();
|
||||
get_handle_current_stdout() = new_stdout;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* getStdout : IO FS.Handle */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue