[m-rev.] For review: ensure proper initialisation of pretty_printer
Ralph Becket
rafe at csse.unimelb.edu.au
Tue Apr 27 14:25:01 AEST 2010
Julien Fischer, Friday, 23 April 2010:
>
> You will also need to provide Erlang and Java implementations (or at the
> very least add Mercury definitions for the new foriegn_procs you have
> added, so that the java and erlang grades still compile.)
Okay, here's an up-to-date diff:
Index: pretty_printer.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/pretty_printer.m,v
retrieving revision 1.9
diff -u -r1.9 pretty_printer.m
--- pretty_printer.m 18 May 2009 05:55:13 -0000 1.9
+++ pretty_printer.m 27 Apr 2010 04:11:48 -0000
@@ -884,24 +884,160 @@
%-----------------------------------------------------------------------------%
% Convenience predicates.
-:- mutable(io_formatter_map, formatter_map, initial_formatter_map, ground,
- [attach_to_io_state, untrailed, thread_local]).
-
+ % This is where we keep the display parameters (line width etc.).
+ % The formatter map is handled separately because it *has* to
+ % be initialised immediately (i.e., before any other module's
+ % initialisation directive can update the default formatter map).
+ %
:- mutable(io_pp_params, pp_params, pp_params(78, 100, triangular(100)),
- ground, [attach_to_io_state, untrailed, thread_local]).
+ ground, [attach_to_io_state, untrailed]).
+
+%-----------------------------------------------------------------------------%
+
+ % Because there is no guaranteed order of module initialisation, we need
+ % to ensure that we do the right thing if other modules try to update the
+ % default formatter_map before this module has been initialised.
+ %
+ % All of this machinery is needed to avoid a race condition between
+ % initialise directives and initialisation of mutables.
+ %
+:- pragma foreign_decl("C",
+"
+ extern MR_Bool pretty_printer_is_initialised;
+ extern MR_Word pretty_printer_default_formatter_map;
+").
+:- pragma foreign_code("C",
+"
+ MR_Bool pretty_printer_is_initialised = MR_FALSE;
+ MR_Word pretty_printer_default_formatter_map = NULL;
+").
+
+:- pragma foreign_decl("Java",
+"
+ class PrettyPrinterDefaultFormatterMap {
+ static bool.Bool_0 isInitialised = bool.NO;
+ static tree234.Tree234_2<java.lang.String,
+ tree234.Tree234_2<java.lang.Integer,
+ /* closure */ java.lang.Object[]>> defaultFormatterMap =
+ null;
+ }
+").
+
+%-----------------------------------------------------------------------------%
+
+:- pred pretty_printer_is_initialised(bool::out, io::di, io::uo)
+ is det.
+
+:- pragma foreign_proc("C",
+ pretty_printer_is_initialised(Okay::out, _IO0::di, _IO::uo),
+ [promise_pure, will_not_call_mercury, thread_safe],
+"
+ Okay = pretty_printer_is_initialised;
+").
+
+:- pragma foreign_proc("Java",
+ pretty_printer_is_initialised(Okay::out, _IO0::di, _IO::uo),
+ [promise_pure, will_not_call_mercury, thread_safe],
+"
+ Okay = PrettyPrinterDefaultFormatterMap.isInitialised;
+").
+
+:- pragma foreign_proc("Erlang",
+ pretty_printer_is_initialised(Okay::out, _IO0::di, _IO::uo),
+ [promise_pure, will_not_call_mercury, thread_safe],
+"
+pretty_printer_is_initialised() ->
+ 'ML_erlang_global_server' !
+ {get_mutable, pretty_printer_is_initialised, self()},
+ receive
+ {get_mutable_ack, undefined} -> {no};
+ {get_mutable_ack, Okay} -> Okay
+ end.
+").
+
+%-----------------------------------------------------------------------------%
+
+ % This predicate must not be called unless pretty_printer_is_initialised ==
+ % MR_TRUE, which occurs when set_default_formatter_map has been called at
+ % least once.
+ %
+:- pred unsafe_get_default_formatter_map(formatter_map::out, io::di, io::uo)
+ is det.
+
+:- pragma foreign_proc("C",
+ unsafe_get_default_formatter_map(FMap::out, _IO0::di, _IO::uo),
+ [promise_pure, will_not_call_mercury, thread_safe],
+"
+ FMap = pretty_printer_default_formatter_map;
+").
+
+:- pragma foreign_proc("Java",
+ unsafe_get_default_formatter_map(FMap::out, _IO0::di, _IO::uo),
+ [promise_pure, will_not_call_mercury, thread_safe],
+"
+ FMap = PrettyPrinterDefaultFormatterMap.defaultFormatterMap;
+").
+
+:- pragma foreign_proc("Erlang",
+ unsafe_get_default_formatter_map(FMap::out, _IO0::di, _IO::uo),
+ [promise_pure, will_not_call_mercury, thread_safe],
+"
+unsafe_get_default_formatter_map() ->
+ 'ML_erlang_global_server' !
+ {get_mutable, pretty_printer_formatter_map, self()},
+ receive
+ {get_mutable_ack, FMap} -> FMap
+ end.
+").
%-----------------------------------------------------------------------------%
get_default_formatter_map(FMap, !IO) :-
- get_io_formatter_map(FMap, !IO).
+ pretty_printer_is_initialised(Okay, !IO),
+ (
+ Okay = no,
+ FMap = initial_formatter_map,
+ set_default_formatter_map(FMap, !IO)
+ ;
+ Okay = yes,
+ unsafe_get_default_formatter_map(FMap, !IO)
+ ).
+
+%-----------------------------------------------------------------------------%
-set_default_formatter_map(FMap, !IO) :-
- set_io_formatter_map(FMap, !IO).
+:- pragma foreign_proc("C",
+ set_default_formatter_map(FMap::in, _IO0::di, _IO::uo),
+ [promise_pure, will_not_call_mercury],
+"
+ pretty_printer_default_formatter_map = FMap;
+ pretty_printer_is_initialised = MR_TRUE;
+").
+
+:- pragma foreign_proc("Java",
+ set_default_formatter_map(FMap::in, _IO0::di, _IO::uo),
+ [promise_pure, will_not_call_mercury],
+"
+ PrettyPrinterDefaultFormatterMap.isInitialised = bool.YES;
+ PrettyPrinterDefaultFormatterMap.defaultFormatterMap = FMap;
+").
+
+:- pragma foreign_proc("Erlang",
+ set_default_formatter_map(FMap::in, _IO0::di, _IO::uo),
+ [promise_pure, will_not_call_mercury, thread_safe],
+"
+unsafe_get_default_formatter_map(FMap) ->
+ 'ML_erlang_global_server' !
+ {set_mutable, pretty_printer_is_initialised, {yes}},
+ 'ML_erlang_global_server' !
+ {set_mutable, pretty_printer_default_formatter_map, FMap}.
+").
+
+%-----------------------------------------------------------------------------%
set_default_formatter(ModuleName, TypeName, Arity, Formatter, !IO) :-
- get_io_formatter_map(FMap0, !IO),
+ get_default_formatter_map(FMap0, !IO),
FMap = set_formatter(ModuleName, TypeName, Arity, Formatter, FMap0),
- set_io_formatter_map(FMap, !IO).
+ set_default_formatter_map(FMap, !IO).
%-----------------------------------------------------------------------------%
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list