aboutsummaryrefslogtreecommitdiffstats
path: root/lang
diff options
context:
space:
mode:
authorolgeni <olgeni@FreeBSD.org>2013-01-10 22:42:50 +0800
committerolgeni <olgeni@FreeBSD.org>2013-01-10 22:42:50 +0800
commit60c4464f77cc93ce61e67802827198e873123683 (patch)
tree1ddb8d39d1bc2eddcdfef1bfedfd9ebb27aa6dca /lang
parent15aa680d9a4b1966c9148282a0a8a826434eff06 (diff)
downloadfreebsd-ports-gnome-60c4464f77cc93ce61e67802827198e873123683.tar.gz
freebsd-ports-gnome-60c4464f77cc93ce61e67802827198e873123683.tar.zst
freebsd-ports-gnome-60c4464f77cc93ce61e67802827198e873123683.zip
Fix a couple of issues, using patches from erlang-patches:
- When using an async thread pool, terminating a process that uses the file:open/2 that specify the "compressed" option causes a crash. (by Filipe David Manana) - Due to a bug in ssl_manager:clean_cert_db, very time a tcp connection was upgraded the certificates would be leaked and never removed from the 'ssl_otp_cacertificate_db' table. (by Daniel Barney)
Diffstat (limited to 'lang')
-rw-r--r--lang/erlang/Makefile2
-rw-r--r--lang/erlang/files/patch-erts_emulator_drivers_common_efile__drv.c337
-rw-r--r--lang/erlang/files/patch-lib_kernel_test_file__SUITE.erl83
-rw-r--r--lang/erlang/files/patch-lib_ssl_src_ssl__manager.erl14
4 files changed, 435 insertions, 1 deletions
diff --git a/lang/erlang/Makefile b/lang/erlang/Makefile
index e60b914d19b0..8e31c0a6f522 100644
--- a/lang/erlang/Makefile
+++ b/lang/erlang/Makefile
@@ -7,7 +7,7 @@
PORTNAME= erlang
PORTVERSION= 15.b.03.1
-PORTEPOCH= 2
+PORTEPOCH= 3
CATEGORIES= lang parallel java
MASTER_SITES= http://www.erlang.org/download/:erlangorg \
http://erlang.stacken.kth.se/download/:erlangorg \
diff --git a/lang/erlang/files/patch-erts_emulator_drivers_common_efile__drv.c b/lang/erlang/files/patch-erts_emulator_drivers_common_efile__drv.c
new file mode 100644
index 000000000000..dedf69150029
--- /dev/null
+++ b/lang/erlang/files/patch-erts_emulator_drivers_common_efile__drv.c
@@ -0,0 +1,337 @@
+
+$FreeBSD$
+
+--- erts/emulator/drivers/common/efile_drv.c.orig
++++ erts/emulator/drivers/common/efile_drv.c
+@@ -311,6 +311,18 @@
+ unsigned flags; /* Original flags from FILE_OPEN. */
+ void (*invoke)(void *);
+ struct t_data *d;
++ /*
++ * If an operation against a compressed file is being executed
++ * by an async thread, ensure the stop callback doesn't close
++ * the fd (gzFile) while the async thread doesn't finish using
++ * the fd (gzFile) - otherwise it accesses a dangling pointer.
++ * The following comp_op_* variables are used to coordinate the
++ * driver stop callback with the ongoing async operation.
++ */
++ int comp_op_in_progress;
++ volatile int comp_op_done;
++ erts_mtx_t comp_op_mtx;
++ erts_cnd_t comp_op_cnd;
+ void (*free)(void *);
+ struct t_data *cq_head; /* Queue of incoming commands */
+ struct t_data *cq_tail; /* -""- */
+@@ -426,6 +438,9 @@
+ struct t_data *next;
+ int command;
+ int level;
++ int volatile *comp_op_done;
++ erts_mtx_t *comp_op_mtx;
++ erts_cnd_t *comp_op_cnd;
+ void (*invoke)(void *);
+ void (*free)(void *);
+ int again;
+@@ -714,6 +729,14 @@
+ return d;
+ }
+
++static void signal_comp_op_done(struct t_data *d) {
++ if (d->comp_op_done != NULL) {
++ erts_mtx_lock(d->comp_op_mtx);
++ *(d->comp_op_done) = 1;
++ erts_cnd_signal(d->comp_op_cnd);
++ erts_mtx_unlock(d->comp_op_mtx);
++ }
++}
+
+ /*********************************************************************
+ * Driver entry point -> init
+@@ -757,6 +780,8 @@
+ desc->key = (unsigned int) (UWord) port;
+ desc->flags = 0;
+ desc->invoke = NULL;
++ desc->comp_op_in_progress = 0;
++ desc->comp_op_done = 0;
+ desc->d = NULL;
+ desc->free = NULL;
+ desc->cq_head = NULL;
+@@ -800,6 +825,7 @@
+ DTRACE_INVOKE_SETUP(FILE_CLOSE);
+ d->again = 0;
+ do_close(d->flags, d->fd);
++ signal_comp_op_done(d);
+ DTRACE_INVOKE_RETURN(FILE_CLOSE);
+ }
+
+@@ -814,9 +840,20 @@
+ TRACE_C('p');
+
+ if (desc->fd != FILE_FD_INVALID) {
++ if (desc->comp_op_in_progress) {
++ erts_mtx_lock(&desc->comp_op_mtx);
++ while (!desc->comp_op_done) {
++ erts_cnd_wait(&desc->comp_op_cnd, &desc->comp_op_mtx);
++ }
++ erts_mtx_unlock(&desc->comp_op_mtx);
++ }
+ do_close(desc->flags, desc->fd);
+ desc->fd = FILE_FD_INVALID;
+ desc->flags = 0;
++ if (sys_info.async_threads > 0 && (desc->flags & EFILE_COMPRESSED)) {
++ erts_cnd_destroy(&desc->comp_op_cnd);
++ erts_mtx_destroy(&desc->comp_op_mtx);
++ }
+ }
+ if (desc->read_binp) {
+ driver_free_binary(desc->read_binp);
+@@ -1032,6 +1069,7 @@
+ {
+ DTRACE_INVOKE_SETUP_BY_NAME(FILE_MKDIR);
+ invoke_name(data, efile_mkdir);
++ signal_comp_op_done((struct t_data *) data);
+ DTRACE_INVOKE_RETURN(FILE_MKDIR);
+ }
+
+@@ -1039,6 +1077,7 @@
+ {
+ DTRACE_INVOKE_SETUP_BY_NAME(FILE_RMDIR);
+ invoke_name(data, efile_rmdir);
++ signal_comp_op_done((struct t_data *) data);
+ DTRACE_INVOKE_RETURN(FILE_RMDIR);
+ }
+
+@@ -1046,6 +1085,7 @@
+ {
+ DTRACE_INVOKE_SETUP_BY_NAME(FILE_DELETE);
+ invoke_name(data, efile_delete_file);
++ signal_comp_op_done((struct t_data *) data);
+ DTRACE_INVOKE_RETURN(FILE_DELETE);
+ }
+
+@@ -1053,6 +1093,7 @@
+ {
+ DTRACE_INVOKE_SETUP_BY_NAME(FILE_CHDIR);
+ invoke_name(data, efile_chdir);
++ signal_comp_op_done((struct t_data *) data);
+ DTRACE_INVOKE_RETURN(FILE_CHDIR);
+ }
+
+@@ -1064,6 +1105,7 @@
+
+ d->again = 0;
+ d->result_ok = efile_fdatasync(&d->errInfo, fd);
++ signal_comp_op_done(d);
+ DTRACE_INVOKE_RETURN(FILE_FDATASYNC);
+ }
+
+@@ -1075,6 +1117,7 @@
+
+ d->again = 0;
+ d->result_ok = efile_fsync(&d->errInfo, fd);
++ signal_comp_op_done(d);
+ DTRACE_INVOKE_RETURN(FILE_FSYNC);
+ }
+
+@@ -1086,6 +1129,7 @@
+
+ d->again = 0;
+ d->result_ok = efile_truncate_file(&d->errInfo, &fd, d->flags);
++ signal_comp_op_done(d);
+ DTRACE_INVOKE_RETURN(FILE_TRUNCATE);
+ }
+
+@@ -1129,6 +1173,7 @@
+ } else {
+ d->again = 0;
+ }
++ signal_comp_op_done(d);
+ DTRACE_INVOKE_RETURN(FILE_READ);
+ }
+
+@@ -1238,6 +1283,7 @@
+ break;
+ }
+ } while (local_loop);
++ signal_comp_op_done(d);
+ DTRACE_INVOKE_RETURN(FILE_READ_LINE);
+ }
+
+@@ -1298,6 +1344,7 @@
+ done:
+ d->again = 0;
+ chop_done:
++ signal_comp_op_done(d);
+ DTRACE_INVOKE_RETURN(FILE_READ_FILE);
+ }
+
+@@ -1363,6 +1410,7 @@
+ }
+ d->again = 0;
+ done:
++ signal_comp_op_done(d);
+ DTRACE_INVOKE_RETURN(FILE_PREADV);
+ }
+
+@@ -1434,6 +1482,7 @@
+ done:
+ d->result_ok = !0;
+ d->again = 0;
++ signal_comp_op_done(d);
+ DTRACE_INVOKE_RETURN(FILE_IPREAD);
+ }
+
+@@ -1531,6 +1580,7 @@
+ TRACE_F(("w%lu", (unsigned long)size));
+
+ }
++ signal_comp_op_done(d);
+ DTRACE_INVOKE_RETURN(FILE_WRITE);
+ }
+
+@@ -1550,6 +1600,7 @@
+ d->again = 0;
+ d->result_ok = efile_getdcwd(&d->errInfo,d->drive, d->b+1,
+ RESBUFSIZE-1);
++ signal_comp_op_done(d);
+ DTRACE_INVOKE_RETURN(FILE_PWD);
+ }
+
+@@ -1564,6 +1615,7 @@
+ RESBUFSIZE-1);
+ if (d->result_ok != 0)
+ FILENAME_COPY((char *) d->b + 1, resbuf+1);
++ signal_comp_op_done(d);
+ DTRACE_INVOKE_RETURN(FILE_READLINK);
+ }
+
+@@ -1578,6 +1630,7 @@
+ RESBUFSIZE-1);
+ if (d->result_ok != 0)
+ FILENAME_COPY((char *) d->b + 1, resbuf+1);
++ signal_comp_op_done(d);
+ DTRACE_INVOKE_RETURN(FILE_ALTNAME);
+ }
+
+@@ -1670,6 +1723,7 @@
+ }
+ }
+ done:
++ signal_comp_op_done(d);
+ EF_FREE(iov); /* Free our copy of the vector, nothing to restore */
+ DTRACE_INVOKE_RETURN(FILE_PWRITEV);
+ }
+@@ -1695,6 +1749,7 @@
+ DTRACE3(efile_drv_int_entry, d->sched_i1, d->sched_i2,
+ d->command == FILE_LSTAT ? FILE_LSTAT : FILE_FSTAT);
+ gcc_optimizer_hack++;
++ signal_comp_op_done(d);
+ }
+
+ static void invoke_link(void *data)
+@@ -1707,6 +1762,7 @@
+ d->again = 0;
+ new_name = name+FILENAME_BYTELEN(name)+FILENAME_CHARSIZE;
+ d->result_ok = efile_link(&d->errInfo, name, new_name);
++ signal_comp_op_done(d);
+ DTRACE_INVOKE_RETURN(FILE_LINK);
+ }
+
+@@ -1720,6 +1776,7 @@
+ d->again = 0;
+ new_name = name+FILENAME_BYTELEN(name)+FILENAME_CHARSIZE;
+ d->result_ok = efile_symlink(&d->errInfo, name, new_name);
++ signal_comp_op_done(d);
+ DTRACE_INVOKE_RETURN(FILE_SYMLINK);
+ }
+
+@@ -1733,6 +1790,7 @@
+ d->again = 0;
+ new_name = name+FILENAME_BYTELEN(name)+FILENAME_CHARSIZE;
+ d->result_ok = efile_rename(&d->errInfo, name, new_name);
++ signal_comp_op_done(d);
+ DTRACE_INVOKE_RETURN(FILE_RENAME);
+ }
+
+@@ -1743,6 +1801,7 @@
+
+ d->again = 0;
+ d->result_ok = efile_write_info(&d->errInfo, &d->info, d->b);
++ signal_comp_op_done(d);
+ DTRACE_INVOKE_RETURN(FILE_WRITE_INFO);
+ }
+
+@@ -1775,6 +1834,7 @@
+ &d->c.lseek.location);
+ }
+ d->result_ok = status;
++ signal_comp_op_done(d);
+ DTRACE_INVOKE_RETURN(FILE_LSEEK);
+ }
+
+@@ -1822,6 +1882,7 @@
+ } while(res);
+
+ d->result_ok = (d->errInfo.posix_errno == 0);
++ signal_comp_op_done(d);
+ DTRACE_INVOKE_RETURN(FILE_READDIR);
+ }
+
+@@ -1876,6 +1937,7 @@
+
+ d->again = 0;
+ d->result_ok = efile_fadvise(&d->errInfo, fd, offset, length, advise);
++ signal_comp_op_done(d);
+ DTRACE_INVOKE_RETURN(FILE_FADVISE);
+ }
+
+@@ -1906,6 +1968,7 @@
+ } else {
+ d->result_ok = -1;
+ }
++ signal_comp_op_done(d);
+ }
+
+ static void free_sendfile(void *data) {
+@@ -2023,6 +2086,21 @@
+ return;
+ TRACE_F(("x%i", (int) d->command));
+ d->again = sys_info.async_threads == 0;
++
++ if ((desc->flags & EFILE_COMPRESSED) && (sys_info.async_threads > 0) &&
++ (desc->fd != FILE_FD_INVALID)) {
++
++ desc->comp_op_in_progress = 1;
++ desc->comp_op_done = 0;
++ d->comp_op_done = &desc->comp_op_done;
++ d->comp_op_mtx = &desc->comp_op_mtx;
++ d->comp_op_cnd = &desc->comp_op_cnd;
++ } else {
++ d->comp_op_done = NULL;
++ d->comp_op_mtx = NULL;
++ d->comp_op_cnd = NULL;
++ }
++
+ DRIVER_ASYNC(d->level, desc, d->invoke, void_ptr=d, d->free);
+ }
+
+@@ -2247,6 +2325,8 @@
+ return;
+ }
+
++ desc->comp_op_in_progress = 0;
++
+ switch (d->command)
+ {
+ case FILE_READ:
+@@ -2375,6 +2455,10 @@
+ } else {
+ desc->fd = d->fd;
+ desc->flags = d->flags;
++ if (sys_info.async_threads > 0 && (desc->flags & EFILE_COMPRESSED)) {
++ erts_mtx_init(&desc->comp_op_mtx, "efile_drv comp op mutex");
++ erts_cnd_init(&desc->comp_op_cnd);
++ }
+ reply_Uint(desc, d->fd);
+ }
+ free_data(data);
diff --git a/lang/erlang/files/patch-lib_kernel_test_file__SUITE.erl b/lang/erlang/files/patch-lib_kernel_test_file__SUITE.erl
new file mode 100644
index 000000000000..1037f72737eb
--- /dev/null
+++ b/lang/erlang/files/patch-lib_kernel_test_file__SUITE.erl
@@ -0,0 +1,83 @@
+
+$FreeBSD$
+
+--- lib/kernel/test/file_SUITE.erl.orig
++++ lib/kernel/test/file_SUITE.erl
+@@ -60,7 +60,8 @@
+ -export([ read_not_really_compressed/1,
+ read_compressed_cooked/1, read_compressed_cooked_binary/1,
+ read_cooked_tar_problem/1,
+- write_compressed/1, compress_errors/1, catenated_gzips/1]).
++ write_compressed/1, compress_errors/1, catenated_gzips/1,
++ compress_async_crash/1]).
+
+ -export([ make_link/1, read_link_info_for_non_link/1, symlinks/1]).
+
+@@ -133,7 +134,8 @@
+ {compression, [],
+ [read_compressed_cooked, read_compressed_cooked_binary,
+ read_cooked_tar_problem, read_not_really_compressed,
+- write_compressed, compress_errors, catenated_gzips]},
++ write_compressed, compress_errors, catenated_gzips,
++ compress_async_crash]},
+ {links, [],
+ [make_link, read_link_info_for_non_link, symlinks]}].
+
+@@ -2271,6 +2273,57 @@
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
++compress_async_crash(suite) -> [];
++compress_async_crash(doc) -> [];
++compress_async_crash(Config) when is_list(Config) ->
++ ?line DataDir = ?config(data_dir, Config),
++ ?line Path = filename:join(DataDir, "test.gz"),
++ ExpectedData = <<"qwerty">>,
++
++ ?line _ = ?FILE_MODULE:delete(Path),
++ ?line {ok, Fd} = ?FILE_MODULE:open(Path, [write, binary, compressed]),
++ ?line ok = ?FILE_MODULE:write(Fd, ExpectedData),
++ ?line ok = ?FILE_MODULE:close(Fd),
++
++ % Test that when using async thread pool, the emulator doesn't crash
++ % when the efile port driver is stopped while a compressed file operation
++ % is in progress (being carried by an async thread).
++ ?line ok = compress_async_crash_loop(10000, Path, ExpectedData),
++ ?line ok = ?FILE_MODULE:delete(Path),
++ ok.
++
++compress_async_crash_loop(0, _Path, _ExpectedData) ->
++ ok;
++compress_async_crash_loop(N, Path, ExpectedData) ->
++ Parent = self(),
++ {Pid, Ref} = spawn_monitor(
++ fun() ->
++ ?line {ok, Fd} = ?FILE_MODULE:open(
++ Path, [read, compressed, raw, binary]),
++ Len = byte_size(ExpectedData),
++ Parent ! {self(), continue},
++ ?line {ok, ExpectedData} = ?FILE_MODULE:read(Fd, Len),
++ ?line ok = ?FILE_MODULE:close(Fd),
++ receive foobar -> ok end
++ end),
++ receive
++ {Pid, continue} ->
++ exit(Pid, shutdown),
++ receive
++ {'DOWN', Ref, _, _, Reason} ->
++ ?line shutdown = Reason
++ end;
++ {'DOWN', Ref, _, _, Reason2} ->
++ test_server:fail({worker_exited, Reason2})
++ after 60000 ->
++ exit(Pid, shutdown),
++ erlang:demonitor(Ref, [flush]),
++ test_server:fail(worker_timeout)
++ end,
++ compress_async_crash_loop(N - 1, Path, ExpectedData).
++
++%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
++
+ altname(doc) ->
+ "Test the file:altname/1 function";
+ altname(suite) ->
diff --git a/lang/erlang/files/patch-lib_ssl_src_ssl__manager.erl b/lang/erlang/files/patch-lib_ssl_src_ssl__manager.erl
new file mode 100644
index 000000000000..4d7a6ca8871b
--- /dev/null
+++ b/lang/erlang/files/patch-lib_ssl_src_ssl__manager.erl
@@ -0,0 +1,14 @@
+
+$FreeBSD$
+
+--- lib/ssl/src/ssl_manager.erl.orig
++++ lib/ssl/src/ssl_manager.erl
+@@ -145,7 +145,7 @@
+ call({new_session_id, Port}).
+
+ clean_cert_db(Ref, File) ->
+- erlang:send_after(?CLEAN_CERT_DB, self(), {clean_cert_db, Ref, File}).
++ erlang:send_after(?CLEAN_CERT_DB, get(ssl_manager), {clean_cert_db, Ref, File}).
+
+ %%--------------------------------------------------------------------
+ -spec register_session(inet:port_number(), #session{}) -> ok.