Allow disabling off-heap messages

Off-heap messages is an Erlang 19 feature:

http://erlang.org/doc/man/erlang.html#process_flag_message_queue_data

It is adviseable to use that setting for processes which expect to receive a
lot of messages. CouchDB sets it for couch_server, couch_log_server and bunch
of others as well.

In some cases the off-heap behavior could alter the timing of message receives
and expose subtle bugs that have been lurking in the code for years. Or could
slightly reduce performance, so a safety measure allow disabling it.
diff --git a/src/couch/src/couch_server.erl b/src/couch/src/couch_server.erl
index 7210520..50c8cae 100644
--- a/src/couch/src/couch_server.erl
+++ b/src/couch/src/couch_server.erl
@@ -211,7 +211,7 @@
 
 
 init([]) ->
-    couch_util:set_mqd_off_heap(),
+    couch_util:set_mqd_off_heap(?MODULE),
 
     % Mark pluggable storage engines as a supported feature
     config:enable_feature('pluggable-storage-engines'),
diff --git a/src/couch/src/couch_util.erl b/src/couch/src/couch_util.erl
index 936b562..8f25edc 100644
--- a/src/couch/src/couch_util.erl
+++ b/src/couch/src/couch_util.erl
@@ -37,7 +37,7 @@
 -export([unique_monotonic_integer/0]).
 -export([check_config_blacklist/1]).
 -export([check_md5/2]).
--export([set_mqd_off_heap/0]).
+-export([set_mqd_off_heap/1]).
 
 -include_lib("couch/include/couch_db.hrl").
 
@@ -670,12 +670,17 @@
 check_md5(_, _) -> throw(md5_mismatch).
 
 
-set_mqd_off_heap() ->
-    try
-        erlang:process_flag(message_queue_data, off_heap),
-        ok
-    catch error:badarg ->
-        ok
+set_mqd_off_heap(Module) ->
+    case config:get_boolean("off_heap_mqd", atom_to_list(Module), true) of
+        true ->
+            try
+                erlang:process_flag(message_queue_data, off_heap),
+                ok
+            catch error:badarg ->
+                    ok
+            end;
+        false ->
+            ok
     end.
 
 
diff --git a/src/couch_log/src/couch_log_server.erl b/src/couch_log/src/couch_log_server.erl
index ea5def8..8432b9a 100644
--- a/src/couch_log/src/couch_log_server.erl
+++ b/src/couch_log/src/couch_log_server.erl
@@ -58,7 +58,7 @@
 
 
 init(_) ->
-    couch_util:set_mqd_off_heap(),
+    couch_util:set_mqd_off_heap(?MODULE),
     process_flag(trap_exit, true),
     {ok, #st{
         writer = couch_log_writer:init()
diff --git a/src/ddoc_cache/src/ddoc_cache_lru.erl b/src/ddoc_cache/src/ddoc_cache_lru.erl
index 248a76d..28a8a64 100644
--- a/src/ddoc_cache/src/ddoc_cache_lru.erl
+++ b/src/ddoc_cache/src/ddoc_cache_lru.erl
@@ -87,7 +87,7 @@
 
 
 init(_) ->
-    couch_util:set_mqd_off_heap(),
+    couch_util:set_mqd_off_heap(?MODULE),
     process_flag(trap_exit, true),
     BaseOpts = [public, named_table],
     CacheOpts = [
diff --git a/src/mem3/src/mem3_shards.erl b/src/mem3/src/mem3_shards.erl
index da3b69a..183f28f 100644
--- a/src/mem3/src/mem3_shards.erl
+++ b/src/mem3/src/mem3_shards.erl
@@ -184,7 +184,7 @@
     erlang:send_after(?RELISTEN_DELAY, whereis(?MODULE), restart_config_listener).
 
 init([]) ->
-    couch_util:set_mqd_off_heap(),
+    couch_util:set_mqd_off_heap(?MODULE),
     ets:new(?SHARDS, [
         bag,
         public,
diff --git a/src/rexi/src/rexi_server.erl b/src/rexi/src/rexi_server.erl
index 954ca88..58a510b 100644
--- a/src/rexi/src/rexi_server.erl
+++ b/src/rexi/src/rexi_server.erl
@@ -39,7 +39,7 @@
     gen_server:start_link({local, ServerId}, ?MODULE, [], []).
 
 init([]) ->
-    couch_util:set_mqd_off_heap(),
+    couch_util:set_mqd_off_heap(?MODULE),
     {ok, #st{}}.
 
 handle_call(get_errors, _From, #st{errors = Errors} = St) ->