Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 10 Jan 2013 14:42:51 +0000 (UTC)
From:      Jimmy Olgeni <olgeni@FreeBSD.org>
To:        ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org
Subject:   svn commit: r310183 - in head/lang/erlang: . files
Message-ID:  <201301101442.r0AEgpjM024601@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: olgeni
Date: Thu Jan 10 14:42:50 2013
New Revision: 310183
URL: http://svnweb.freebsd.org/changeset/ports/310183

Log:
  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)

Added:
  head/lang/erlang/files/patch-erts_emulator_drivers_common_efile__drv.c   (contents, props changed)
  head/lang/erlang/files/patch-lib_kernel_test_file__SUITE.erl   (contents, props changed)
  head/lang/erlang/files/patch-lib_ssl_src_ssl__manager.erl   (contents, props changed)
Modified:
  head/lang/erlang/Makefile

Modified: head/lang/erlang/Makefile
==============================================================================
--- head/lang/erlang/Makefile	Thu Jan 10 14:34:07 2013	(r310182)
+++ head/lang/erlang/Makefile	Thu Jan 10 14:42:50 2013	(r310183)
@@ -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	\

Added: head/lang/erlang/files/patch-erts_emulator_drivers_common_efile__drv.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lang/erlang/files/patch-erts_emulator_drivers_common_efile__drv.c	Thu Jan 10 14:42:50 2013	(r310183)
@@ -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);

Added: head/lang/erlang/files/patch-lib_kernel_test_file__SUITE.erl
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lang/erlang/files/patch-lib_kernel_test_file__SUITE.erl	Thu Jan 10 14:42:50 2013	(r310183)
@@ -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) ->

Added: head/lang/erlang/files/patch-lib_ssl_src_ssl__manager.erl
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lang/erlang/files/patch-lib_ssl_src_ssl__manager.erl	Thu Jan 10 14:42:50 2013	(r310183)
@@ -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.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201301101442.r0AEgpjM024601>