[DRE-commits] [ruby-eventmachine] 01/03: Fix memory leak caused when fixing crash
Balint Reczey
rbalint at moszumanska.debian.org
Wed Jun 29 22:10:46 UTC 2016
This is an automated email from the git hooks/post-receive script.
rbalint pushed a commit to branch wheezy-security
in repository ruby-eventmachine.
commit 60e2fef888ec62d5d239d8c5e5b15688a24f9787
Author: Balint Reczey <balint at balintreczey.hu>
Date: Wed Jun 29 18:47:17 2016 +0200
Fix memory leak caused when fixing crash
---
...ll-raw-select-from-thread_blocking_region.patch | 20 +++
...e-on-older-rubies-without-rb_wait_for_sin.patch | 30 ++++
...o-clean-up-rb_fd_init-memory-during-shutd.patch | 35 +++++
.../patches/0009-keep-BUILD_FOR_RUBY-compat.patch | 27 ++++
...use-rb_thread_fd_select-whenever-possible.patch | 35 +++++
debian/patches/0011-fix-build-on-ruby-1.9.1.patch | 68 +++++++++
...e-SelectData_t-per-reactor-to-avoid-heap-.patch | 158 +++++++++++++++++++++
debian/patches/series | 7 +
8 files changed, 380 insertions(+)
diff --git a/debian/patches/0006-must-call-raw-select-from-thread_blocking_region.patch b/debian/patches/0006-must-call-raw-select-from-thread_blocking_region.patch
new file mode 100644
index 0000000..37c149c
--- /dev/null
+++ b/debian/patches/0006-must-call-raw-select-from-thread_blocking_region.patch
@@ -0,0 +1,20 @@
+From a648e7a8e10b3c3fe7331568af3044834614a781 Mon Sep 17 00:00:00 2001
+From: Aman Gupta <aman at tmm1.net>
+Date: Mon, 9 Feb 2015 22:29:00 -0800
+Subject: [PATCH 06/12] must call raw select() from thread_blocking_region
+
+---
+ ext/em.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/ext/em.cpp
++++ b/ext/em.cpp
+@@ -789,7 +789,7 @@
+ static VALUE _SelectDataSelect (void *v)
+ {
+ SelectData_t *sd = (SelectData_t*)v;
+- sd->nSockets = rb_fd_select (sd->maxsocket+1, &(sd->fdreads), &(sd->fdwrites), &(sd->fderrors), &(sd->tv));
++ sd->nSockets = select (sd->maxsocket+1, &(sd->fdreads), &(sd->fdwrites), &(sd->fderrors), &(sd->tv));
+ return Qnil;
+ }
+ #endif
diff --git a/debian/patches/0007-epoll-kqueue-on-older-rubies-without-rb_wait_for_sin.patch b/debian/patches/0007-epoll-kqueue-on-older-rubies-without-rb_wait_for_sin.patch
new file mode 100644
index 0000000..f509ac5
--- /dev/null
+++ b/debian/patches/0007-epoll-kqueue-on-older-rubies-without-rb_wait_for_sin.patch
@@ -0,0 +1,30 @@
+From 82d690c972281df959762b814db02d2a5b6f7f4b Mon Sep 17 00:00:00 2001
+From: Aman Gupta <aman at tmm1.net>
+Date: Mon, 9 Feb 2015 22:31:25 -0800
+Subject: [PATCH 07/12] epoll/kqueue on older rubies (without
+ rb_wait_for_single_fd) should use rb_thread_select with regular fdset
+
+epoll/kqueue fds are created early during ruby boot, so it is highly
+unlikely that they will ever overflow FD_SETSIZE
+
+Conflicts:
+ ext/em.cpp
+---
+ ext/em.cpp | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/ext/em.cpp
++++ b/ext/em.cpp
+@@ -850,9 +850,9 @@
+
+ SelectData_t SelectData;
+ /*
+- rb_fdset_t fdreads, fdwrites;
+- rb_fd_init (&fdreads);
+- rb_fd_init (&fdwrites);
++ fd_set fdreads, fdwrites;
++ FD_ZERO (&fdreads);
++ FD_ZERO (&fdwrites);
+
+ int maxsocket = 0;
+ */
diff --git a/debian/patches/0008-make-sure-to-clean-up-rb_fd_init-memory-during-shutd.patch b/debian/patches/0008-make-sure-to-clean-up-rb_fd_init-memory-during-shutd.patch
new file mode 100644
index 0000000..a84aea0
--- /dev/null
+++ b/debian/patches/0008-make-sure-to-clean-up-rb_fd_init-memory-during-shutd.patch
@@ -0,0 +1,35 @@
+From 8cc177a151f77f07ce7fb32aab746b972d0d74cc Mon Sep 17 00:00:00 2001
+From: Aman Gupta <aman at tmm1.net>
+Date: Mon, 9 Feb 2015 22:32:19 -0800
+Subject: [PATCH 08/12] make sure to clean up rb_fd_init memory during shutdown
+
+---
+ ext/em.cpp | 6 ++++++
+ ext/em.h | 1 +
+ 2 files changed, 7 insertions(+)
+
+--- a/ext/em.cpp
++++ b/ext/em.cpp
+@@ -779,6 +779,12 @@
+ rb_fd_init (&fderrors);
+ }
+
++SelectData_t::~SelectData_t()
++{
++ rb_fd_term (&fdreads);
++ rb_fd_term (&fdwrites);
++ rb_fd_term (&fderrors);
++}
+
+ #ifdef BUILD_FOR_RUBY
+ /*****************
+--- a/ext/em.h
++++ b/ext/em.h
+@@ -246,6 +246,7 @@
+ struct SelectData_t
+ {
+ SelectData_t();
++ ~SelectData_t();
+
+ int _Select();
+
diff --git a/debian/patches/0009-keep-BUILD_FOR_RUBY-compat.patch b/debian/patches/0009-keep-BUILD_FOR_RUBY-compat.patch
new file mode 100644
index 0000000..deb6f5a
--- /dev/null
+++ b/debian/patches/0009-keep-BUILD_FOR_RUBY-compat.patch
@@ -0,0 +1,27 @@
+From e95f0f5e21d5620b9b0429677fbd0b949222f2d1 Mon Sep 17 00:00:00 2001
+From: Aman Gupta <aman at tmm1.net>
+Date: Mon, 9 Feb 2015 22:40:10 -0800
+Subject: [PATCH 09/12] keep BUILD_FOR_RUBY compat
+
+---
+ ext/em.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/ext/em.h
++++ b/ext/em.h
+@@ -54,13 +54,13 @@
+ #define RUBY_UBF_IO RB_UBF_DFL
+ #endif
+ #else
+- #define EmSelect rb_fd_select
++ #define EmSelect select
+ #endif
+
+ class EventableDescriptor;
+ class InotifyDescriptor;
+
+-#ifndef rb_fd_max
++#if defined(BUILD_FOR_RUBY) && !defined(rb_fd_max)
+ #define fd_check(n) (((n) < FD_SETSIZE) ? 1 : 0*fprintf(stderr, "fd %d too large for select\n", (n)))
+ // These definitions are cribbed from include/ruby/intern.h in Ruby 1.9.3,
+ // with this change: any macros that read or write the nth element of an
diff --git a/debian/patches/0010-use-rb_thread_fd_select-whenever-possible.patch b/debian/patches/0010-use-rb_thread_fd_select-whenever-possible.patch
new file mode 100644
index 0000000..3c3242f
--- /dev/null
+++ b/debian/patches/0010-use-rb_thread_fd_select-whenever-possible.patch
@@ -0,0 +1,35 @@
+From d0f66631518907e4b10437fc046543ae99ffa2bb Mon Sep 17 00:00:00 2001
+From: Aman Gupta <aman at tmm1.net>
+Date: Mon, 9 Feb 2015 23:24:32 -0800
+Subject: [PATCH 10/12] use rb_thread_fd_select whenever possible
+
+Conflicts:
+ ext/em.cpp
+---
+ ext/em.cpp | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/ext/em.cpp
++++ b/ext/em.cpp
+@@ -791,7 +791,7 @@
+ _SelectDataSelect
+ *****************/
+
+-#ifdef HAVE_TBR
++#if !defined(HAVE_RB_THREAD_FD_SELECT) && defined(HAVE_TBR)
+ static VALUE _SelectDataSelect (void *v)
+ {
+ SelectData_t *sd = (SelectData_t*)v;
+@@ -806,7 +806,11 @@
+
+ int SelectData_t::_Select()
+ {
+- #ifdef HAVE_TBR
++ #if defined(HAVE_RB_THREAD_FD_SELECT)
++ // added in ruby 1.9.2
++ return rb_thread_fd_select (maxsocket+1, &fdreads, &fdwrites, &fderrors, &tv);
++ #elif defined(HAVE_TBR)
++ // added in ruby 1.9.1, deprecated in ruby 2.0.0
+ rb_thread_blocking_region (_SelectDataSelect, (void*)this, RUBY_UBF_IO, 0);
+ return nSockets;
+ #endif
diff --git a/debian/patches/0011-fix-build-on-ruby-1.9.1.patch b/debian/patches/0011-fix-build-on-ruby-1.9.1.patch
new file mode 100644
index 0000000..3acb9d2
--- /dev/null
+++ b/debian/patches/0011-fix-build-on-ruby-1.9.1.patch
@@ -0,0 +1,68 @@
+From 8b656c4f9b77f0674f28d32d5fe4644c8e655b67 Mon Sep 17 00:00:00 2001
+From: Aman Gupta <aman at tmm1.net>
+Date: Mon, 9 Feb 2015 23:45:00 -0800
+Subject: [PATCH 11/12] fix build on ruby 1.9.1
+
+Conflicts:
+ ext/extconf.rb
+---
+ ext/em.cpp | 2 +-
+ ext/em.h | 9 +++++++--
+ ext/extconf.rb | 5 ++++-
+ 3 files changed, 12 insertions(+), 4 deletions(-)
+
+--- a/ext/em.cpp
++++ b/ext/em.cpp
+@@ -795,7 +795,7 @@
+ static VALUE _SelectDataSelect (void *v)
+ {
+ SelectData_t *sd = (SelectData_t*)v;
+- sd->nSockets = select (sd->maxsocket+1, &(sd->fdreads), &(sd->fdwrites), &(sd->fderrors), &(sd->tv));
++ sd->nSockets = select (sd->maxsocket+1, rb_fd_ptr(&(sd->fdreads)), rb_fd_ptr(&(sd->fdwrites)), rb_fd_ptr(&(sd->fderrors)), &(sd->tv));
+ return Qnil;
+ }
+ #endif
+--- a/ext/em.h
++++ b/ext/em.h
+@@ -32,7 +32,12 @@
+
+ #ifdef BUILD_FOR_RUBY
+ #include <ruby.h>
+- #define EmSelect rb_thread_fd_select
++ #ifdef HAVE_RB_THREAD_FD_SELECT
++ #define EmSelect rb_thread_fd_select
++ #else
++ // ruby 1.9.1 and below
++ #define EmSelect rb_thread_select
++ #endif
+
+ #if defined(HAVE_RBTRAP)
+ #include <rubysig.h>
+@@ -60,7 +65,7 @@
+ class EventableDescriptor;
+ class InotifyDescriptor;
+
+-#if defined(BUILD_FOR_RUBY) && !defined(rb_fd_max)
++#if defined(BUILD_FOR_RUBY) && !defined(HAVE_RB_FDSET_T)
+ #define fd_check(n) (((n) < FD_SETSIZE) ? 1 : 0*fprintf(stderr, "fd %d too large for select\n", (n)))
+ // These definitions are cribbed from include/ruby/intern.h in Ruby 1.9.3,
+ // with this change: any macros that read or write the nth element of an
+--- a/ext/extconf.rb
++++ b/ext/extconf.rb
+@@ -19,6 +19,9 @@
+ add_define "HAVE_OLD_INOTIFY" if !inotify && have_macro('__NR_inotify_init', 'sys/syscall.h')
+ add_define 'HAVE_WRITEV' if have_func('writev', 'sys/uio.h')
+ have_func('rb_thread_check_ints')
++add_define 'HAVE_RB_THREAD_FD_SELECT' if have_func('rb_thread_fd_select')
++add_define 'HAVE_RB_FDSET_T' if have_type('rb_fdset_t', 'ruby/intern.h')
++
+ have_func('rb_time_new')
+
+ # Minor platform details between *nix and Windows:
+@@ -147,4 +150,4 @@
+ SRC
+ TRY_LINK.sub!('$(CXX)', '$(CC)')
+
+-create_makefile "rubyeventmachine"
+\ No newline at end of file
++create_makefile "rubyeventmachine"
diff --git a/debian/patches/0012-allocate-one-SelectData_t-per-reactor-to-avoid-heap-.patch b/debian/patches/0012-allocate-one-SelectData_t-per-reactor-to-avoid-heap-.patch
new file mode 100644
index 0000000..086571f
--- /dev/null
+++ b/debian/patches/0012-allocate-one-SelectData_t-per-reactor-to-avoid-heap-.patch
@@ -0,0 +1,158 @@
+From b5dc0f5675d501e3371a2a061f9b7b0aab3b8093 Mon Sep 17 00:00:00 2001
+From: Aman Gupta <aman at tmm1.net>
+Date: Mon, 9 Feb 2015 23:59:11 -0800
+Subject: [PATCH 12/12] allocate one SelectData_t per reactor to avoid heap
+ allocation on every tick
+
+Conflicts:
+ ext/em.cpp
+ ext/em.h
+---
+ ext/em.cpp | 60 +++++++++++++++++++-----------------------------------------
+ ext/em.h | 4 +++-
+ 2 files changed, 22 insertions(+), 42 deletions(-)
+
+--- a/ext/em.cpp
++++ b/ext/em.cpp
+@@ -100,6 +100,7 @@
+ #endif
+
+ _InitializeLoopBreaker();
++ SelectData = new SelectData_t();
+ }
+
+
+@@ -129,6 +130,8 @@
+ close (epfd);
+ if (kqfd != -1)
+ close (kqfd);
++
++ delete SelectData;
+ }
+
+
+@@ -838,43 +841,18 @@
+ // epoll will be effective if we provide it as an alternative,
+ // however it has the same problem interoperating with Ruby
+ // threads that select does.
+-
+- //cerr << "X";
+-
+- /* This protection is now obsolete, because we will ALWAYS
+- * have at least one descriptor (the loop-breaker) to read.
+- */
+- /*
+- if (Descriptors.size() == 0) {
+- #ifdef OS_UNIX
+- timeval tv = {0, 200 * 1000};
+- EmSelect (0, NULL, NULL, NULL, &tv);
+- return true;
+- #endif
+- #ifdef OS_WIN32
+- Sleep (200);
+- return true;
+- #endif
+- }
+- */
+-
+- SelectData_t SelectData;
+- /*
+- fd_set fdreads, fdwrites;
+- FD_ZERO (&fdreads);
+- FD_ZERO (&fdwrites);
+-
+- int maxsocket = 0;
+- */
++ rb_fd_zero (&SelectData->fdreads);
++ rb_fd_zero (&SelectData->fdwrites);
++ rb_fd_zero (&SelectData->fderrors);
+
+ // Always read the loop-breaker reader.
+ // Changed 23Aug06, provisionally implemented for Windows with a UDP socket
+ // running on localhost with a randomly-chosen port. (*Puke*)
+ // Windows has a version of the Unix pipe() library function, but it doesn't
+ // give you back descriptors that are selectable.
+- rb_fd_set (LoopBreakerReader, &(SelectData.fdreads));
+- if (SelectData.maxsocket < LoopBreakerReader)
+- SelectData.maxsocket = LoopBreakerReader;
++ rb_fd_set (LoopBreakerReader, &(SelectData->fdreads));
++ if (SelectData->maxsocket < LoopBreakerReader)
++ SelectData->maxsocket = LoopBreakerReader;
+
+ // prepare the sockets for reading and writing
+ size_t i;
+@@ -887,27 +865,27 @@
+ assert (sd != INVALID_SOCKET);
+
+ if (ed->SelectForRead())
+- rb_fd_set (sd, &(SelectData.fdreads));
++ rb_fd_set (sd, &(SelectData->fdreads));
+ if (ed->SelectForWrite())
+- rb_fd_set (sd, &(SelectData.fdwrites));
++ rb_fd_set (sd, &(SelectData->fdwrites));
+
+ #ifdef OS_WIN32
+ /* 21Sep09: on windows, a non-blocking connect() that fails does not come up as writable.
+ Instead, it is added to the error set. See http://www.mail-archive.com/openssl-users@openssl.org/msg58500.html
+ */
+- rb_fd_set (sd, &(SelectData.fderrors));
++ rb_fd_set (sd, &(SelectData->fderrors));
+ #endif
+
+- if (SelectData.maxsocket < sd)
+- SelectData.maxsocket = sd;
++ if (SelectData->maxsocket < sd)
++ SelectData->maxsocket = sd;
+ }
+
+
+ { // read and write the sockets
+ //timeval tv = {1, 0}; // Solaris fails if the microseconds member is >= 1000000.
+ //timeval tv = Quantum;
+- SelectData.tv = _TimeTilNextEvent();
+- int s = SelectData._Select();
++ SelectData->tv = _TimeTilNextEvent();
++ int s = SelectData->_Select();
+ //rb_thread_blocking_region(xxx,(void*)&SelectData,RUBY_UBF_IO,0);
+ //int s = EmSelect (SelectData.maxsocket+1, &(SelectData.fdreads), &(SelectData.fdwrites), NULL, &(SelectData.tv));
+ //int s = SelectData.nSockets;
+@@ -930,15 +908,15 @@
+ continue;
+ assert (sd != INVALID_SOCKET);
+
+- if (rb_fd_isset (sd, &(SelectData.fdwrites)))
++ if (rb_fd_isset (sd, &(SelectData->fdwrites)))
+ ed->Write();
+- if (rb_fd_isset (sd, &(SelectData.fdreads)))
++ if (rb_fd_isset (sd, &(SelectData->fdreads)))
+ ed->Read();
+- if (rb_fd_isset (sd, &(SelectData.fderrors)))
++ if (rb_fd_isset (sd, &(SelectData->fderrors)))
+ ed->HandleError();
+ }
+
+- if (rb_fd_isset (LoopBreakerReader, &(SelectData.fdreads)))
++ if (rb_fd_isset (LoopBreakerReader, &(SelectData->fdreads)))
+ _ReadLoopBreaker();
+ }
+ else if (s < 0) {
+--- a/ext/em.h
++++ b/ext/em.h
+@@ -89,6 +89,8 @@
+ rb_thread_select(fd_check((n)-1) ? (n) : FD_SETSIZE, (rfds), (wfds), (efds), (timeout))
+ #endif
+
++struct SelectData_t;
++
+ /********************
+ class EventMachine_t
+ ********************/
+@@ -228,6 +230,8 @@
+ #endif
+
+ private:
++ SelectData_t *SelectData;
++
+ bool bEpoll;
+ int epfd; // Epoll file-descriptor
+ #ifdef HAVE_EPOLL
diff --git a/debian/patches/series b/debian/patches/series
index b867e29..487433c 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -3,3 +3,10 @@
0003-add-stubs-with-warnings-for-1.8.7-and-1.9.0.patch
0004-add-comment-about-where-the-macros-came-from.patch
0005-Back-port-em_test_helper.rb-for-test_many_fds.rb.patch
+0006-must-call-raw-select-from-thread_blocking_region.patch
+0007-epoll-kqueue-on-older-rubies-without-rb_wait_for_sin.patch
+0008-make-sure-to-clean-up-rb_fd_init-memory-during-shutd.patch
+0009-keep-BUILD_FOR_RUBY-compat.patch
+0010-use-rb_thread_fd_select-whenever-possible.patch
+0011-fix-build-on-ruby-1.9.1.patch
+0012-allocate-one-SelectData_t-per-reactor-to-avoid-heap-.patch
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-eventmachine.git
More information about the Pkg-ruby-extras-commits
mailing list