Next: , Previous: thread.closeable_channel, Up: Top   [Contents]


106 thread.future

%--------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%--------------------------------------------------%
% Copyright (C) 2014-2015, 2018, 2020-2022 The Mercury Team.
% This file is distributed under the terms specified in COPYING.LIB.
%--------------------------------------------------%
%
% File: thread.future.m.
% Authors: pbone.
% Stability: low.
%
% This module defines the data types future_io/1 and future/1 which are
% useful for parallel and concurrent programming.
%
% A future represents a value that might not exist yet.  A value for a
% future may be provided exactly once, but can be read any number of times.
% In these situations futures can be faster than mvars as their
% implementation is simpler: they need only one semaphore and they can avoid
% using it in some cases.
%
% There are two kinds of futures:
%
%   + future(T) is a value that will be evaluated by another thread.  The
%     function future/1 will spawn a new thread to evaluate its argument
%     whose result can be retrieved later by calling the function wait/1.
%     For example:
%
%       Future = future(SomeFunction),
%       ... do something in the meantime ...
%       Value = wait(Future).
%
%   + future_io(T) provides more flexibility, allowing the caller to control
%     the creation of the thread that provides its value.  It can be used
%     as follows:
%
%       First:
%           future(Future, !IO),
%
%       Then in a separate thread:
%           signal(Future, Value0, !IO),
%
%       Finally, in the original thread:
%           wait(Future, Value, !IO),
%
%     This is more flexible because the thread can be used to signal
%     multiple futures or do other things, but it requires the I/O state.
%
%--------------------------------------------------%
%--------------------------------------------------%

:- module thread.future.
:- interface.

%--------------------------------------------------%

    % future/1 represents a value that will be computed by another thread.
    %
:- type future(T).

    % Create a future which has the value that the argument, when evaluated,
    % will produce.  This function will create a thread to evaluate the
    % argument using spawn/3.
    %
    % If the argument throws an exception, that exception will be rethrown by
    % wait/1.
    %
:- func future((func) = T) = future(T).

    % Return the value of the future, blocking until the value is available.
    %
:- func wait(future(T)) = T.

%--------------------------------------------------%

    % future_io/1 represents a value that may not have been computed yet.
    % Future values are intended to be computed by separate threads (using
    % spawn/3).
    %
    % Generally in computer science and in some other languages this is
    % known as a promise.  We called it future_io because promise is a
    % reserved word in Mercury.
    %
:- type future_io(T).

    % Create a new empty future_io.
    %
:- pred init(future_io(T)::uo, io::di, io::uo) is det.

    % Provide a value for the future_io and signal any waiting threads.  Any
    % further calls to wait will return immediately.
    %
    % Calling signal multiple times will result in undefined behaviour.
    %
:- pred signal(future_io(T)::in, T::in, io::di, io::uo) is det.

    % Return the future_io's value, potentially blocking until it is
    % signaled.
    %
:- pred wait(future_io(T)::in, T::out, io::di, io::uo) is det.

%--------------------------------------------------%
%--------------------------------------------------%

Next: , Previous: thread.closeable_channel, Up: Top   [Contents]