History

Fix leaking vm_fd_t instances.

arr committed 9 years ago

Commit 1da323b1 parent cb38bc41 file · +21 −11Browse files

Showing the changes to src/vm/sys/Sysmod.cpp (1 of 1 file). Show all

Unified · Split

src/vm/sys/Sysmod.cpp+21−11
@@ -118,22 +118,27 @@ namespace · 117 unmodified lines
118118 }
119119 }
120120
121− static vm_alloc_t * create(vm_fd_t *f)
121+ // The ref count of the supplied vm_fd_t instance is updated.
122+ static vm_alloc_t * create_new(vm_fd_t *vm_fd)
122123 {
124+ assert(vm_fd != nullptr);
125+ assert(vm_fd->get_ref_count() == 1 && "Should be a new FD");
126+
123127 auto alloc = vm_alloc_t::allocate(T_FD);
124128 auto fd_impl = ::new(alloc->get_allocation())Sys_FD_Impl{};
125129
126− fd_impl->fd = disvm::runtime::sys::create_fd_record(f);
127− fd_impl->impl = f;
130+ fd_impl->fd = disvm::runtime::sys::create_fd_record(vm_fd);
131+ fd_impl->impl = vm_fd;
132+ vm_fd->add_ref();
128133
129134 return alloc;
130135 }
131136
132− static vm_alloc_t * try_create(word_t fd)
137+ // The ref count of the supplied vm_fd_t instance is _not_ altered.
138+ static vm_alloc_t * create_existing(word_t fd, vm_fd_t *vm_fd)
133139 {
134− auto vm_fd = disvm::runtime::sys::fetch_fd_record(fd);
135− if (vm_fd == nullptr)
136− return nullptr;
140+ assert(vm_fd != nullptr);
141+ assert(fd >= 0);
137142
138143 auto alloc = vm_alloc_t::allocate(T_FD);
139144 auto fd_impl = ::new(alloc->get_allocation())Sys_FD_Impl{};
@@ -148,6 +153,7 @@ namespace · 8 unmodified lines
148153 ~Sys_FD_Impl()
149154 {
150155 disvm::runtime::sys::drop_fd_record(fd);
156+ disvm::runtime::dec_ref_count_and_free(impl);
151157 disvm::debug::assign_debug_pointer(&impl);
152158 }
153159
@@ -381,7 +387,7 @@ Sys_create(vm_registers_t &r, vm_t &vm) · 227 unmodified lines
381387 if (vm_fd == nullptr)
382388 return;
383389
384− auto fd_alloc = Sys_FD_Impl::create(vm_fd);
390+ auto fd_alloc = Sys_FD_Impl::create_new(vm_fd);
385391 *fp.ret = fd_alloc->get_allocation();
386392
387393 if (disvm::debug::is_component_tracing_enabled<component_trace_t::builtin>())
@@ -480,9 +486,12 @@ Sys_fildes(vm_registers_t &r, vm_t &vm) · 92 unmodified lines
480486 dec_ref_count_and_free(vm_alloc_t::from_allocation(*fp.ret));
481487 *fp.ret = nullptr;
482488
483− auto fd_alloc = Sys_FD_Impl::try_create(fp.fd);
484− if (fd_alloc != nullptr)
489+ auto vm_fd = disvm::runtime::sys::fetch_fd_record(fp.fd);
490+ if (vm_fd != nullptr)
491+ {
492+ auto fd_alloc = Sys_FD_Impl::create_existing(fp.fd, vm_fd);
485493 *fp.ret = fd_alloc->get_allocation();
494+ }
486495 }
487496
488497 void
@@ -580,7 +589,7 @@ Sys_open(vm_registers_t &r, vm_t &vm) · 91 unmodified lines
580589 if (vm_fd == nullptr)
581590 return;
582591
583− auto fd_alloc = Sys_FD_Impl::create(vm_fd);
592+ auto fd_alloc = Sys_FD_Impl::create_new(vm_fd);
584593 *fp.ret = fd_alloc->get_allocation();
585594
586595 if (disvm::debug::is_component_tracing_enabled<component_trace_t::builtin>())
@@ -631,6 +640,7 @@ Sys_print(vm_registers_t &r, vm_t &vm) · 44 unmodified lines
631640 throw vm_system_exception{ "stdout not available" };
632641
633642 *fp.ret = printf_to_fd(vm, *std_output, *str, &fp.vargs, fp_base);
643+ disvm::runtime::dec_ref_count_and_free(std_output);
634644 }
635645
636646 void