Giter Club home page Giter Club logo

concurrency-ts's People

Contributors

alasdair-mackintosh avatar arturl avatar austern avatar jyasskin avatar k-ballo avatar viboes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

concurrency-ts's Issues

Missing std::experimental::async

As async returns a std::future and we are adding a std::experimental::future it seems to me that we need to add an async function in std::experimental that returns a std::experimental::future.

Maybe it is worth changing the semantics of async and return a future that doesn't block on destruction.

Find a better name for when_any_swapped, allow reorder

Two things here:

[Straw poll] Have the wording for when_any_swapped (perhaps named differently) allow implementations to reorder the array of futures, and put more than one ready future at the end?

SF F N A SA 
4  4 1 0 0

[Straw poll] Should we use a different name from “when_any_swapped”?

SF F N A SA 
5  3 0 0 0

Unclear description for 2.6.4 §2

The following paragraph is unclear

2.6.4
Header <serial_executor> synopsis
2 The number of add() calls on the underlying executor is unspecified, and if the underlying executor guarantees an ordering on its closures, that ordering won't necessarily extend to closures added through a serial_executor. [ Note: this is because serial_executor can batch add() calls to the underlying executor. — end note ]

I don't see how a serial executor can batch add() calls if it needs to preserve the sequence of task as specified in

1 ... If e.add(c1) happens before e.add(c2), then c1 is executed before c2.

IMO, the add() calls to the underlying executor must be synchronized with the end of execution of the previous submitted task.

Maybe some clarifications are needed.

valid() clarifications

I would add the same kind of clarifications i have requested for is_ready #24 as the result is not stable.

Clarifications to .then() Effects clause

The following doesn't seems to be an effect of the call to then()

The continuation is called when the object's shared state is ready (has a value or exception stored).

It is not this function that do this but the internal function that is called by the thread.

Clarification on .then() postconditions

Postconditions:
The future object is moved to the parameter of the continuation function.

It is not clear to me what this means. The future will be moved to the shared state of the returned future and only when it becomes ready it will be moved on the call to the continuation.

clarifications on when_all() effects

The Effects clause states
Each future and shared_future is waited upon and then copied into the collection of the output (returned) future, maintaining the order of the futures in the input collection.

I don't think that the futures are waited in this function. IMO the future are moved and the shared_future is copied to the shared state of the new future.
It is only internal function used for the new created thread that will wait on all the futures/shared_futures.

Resuming this is not a blocking function.

Maybe, make clearer that closure are executed completly on the same thread

2.4 Class executor 2
All closures are defined to execute on some thread, but which thread is largely unspecified.

++ Once the thread is chosen, the closure executes completely on this thread.

As such accessing a thread_local variable is defined behavior, though it is unspecified which thread's thread_local will be accessed.

Typo in 3.2 Changes to class template future §10

The continuation takes future as parameter

When result_of_t<decay_t<F>()> is future<R>, the function returns future<R>.
Otherwise, the function returns future<result_of_t<decay_t<F>()>>.

must be replaced with

When result_of_t<decay_t<F>(future<R>)> is future<R2>, the function returns future<R2>.
Otherwise, the function returns future<result_of_t<decay_t<F>(future<R>)>>.

§2.4 2 Missing <class InputIterator>

template
see below when_all(InputIterator first, InputIterator last);

should be

template
see below when_all(InputIterator first, InputIterator last);

When the result of when_all/when_any becomes ready?

It is not clear when the result of when_all/when_any becomes ready.

I see two possibilities:

  1. When the last/first future becomes ready for when_all/when_any respectively.
  2. When the user call to wait/get and all/one future are/is ready for when_all/when_any respectively.

Boost.Thread implements option 2, but I suspect that only option 1 is correct.

Why the variadic versions of when_all/when_any could return a future vector?

Both when_all/when_any returns a future<tuple<>> when there is no argument.
It seems to me that the variadic version should return future<tuple<Ts...>> instead of a future<vector<T...>> even when all T in Ts are the same.

Having a tuple helps to preserve the static information and would allow to pass a continuation that uses apply to call a function that has exactly the same types.

Compare

when_all(f1, f2).then([](future<tuple<future<int>, future<int>> f) { 
  return apply(fct, f.get()); 
}

to the more verbose

when_all(f1, f2).then([](future<vector<future<int>> f) { 
  vector<future<int> v = f.get();
  return fct(v[0], v[1]); 
}

So future<vector<F>> will be reserved for the dynamic version having iterators as parameters, which seems coherent.

If the user prefers a dynamic version even when it has a static number of futures it could always push the futures on a vector and use the dynamic version.

Replace function<void> by a specific class work/job

It would be great if the specification make use of a typedef for function<void()>.

This would allow to move in other version to a function wrapping class that can be initialized by moving the function.

when_ missing precondition

Add a precondition to when_all/when_any/when_any_back

    All input future<T>s valid() == true.
    All input shared_future<T> valid() == true.

when_all/when_any result type.

It seems to me that we must return future<vector<shared_future>> when the typename InputIterator::value_type is shared_future

I suggest to replace future<vector<future<R>>> by future<vector<typename InputIterator::value_type>> if the input cardinality is unknown at compile. typename InputIterator::value_type::value_type may be void. The order of the futures in the output vector will be the same as given by the input iterator.

Replace future<tuple<F0<R0>, F1<R1>, F2<R2>...>> by future<tuple<T...>>

As there is not too much trouble with the result type, I suggest also to remove the see below.

template <class InputIterator>
future<vector<typename InputIterator::value_type>> when_all(InputIterator first, InputIterator last);

template <typename... T>
future<tuple<T...>> when_all(T&&... futures);

The same could be applied to when_any.

Need better name for thread_executor

[straw poll] Prefer a longer, more descriptive name for thread_executor? (e.g. thread_per_closure_executor, but not necessarily that name)

SF F N A SA 
4  3 2 0 0

Typo in 2.6.2 §4

In 2.6.2 Header <thread_pool> synopsis

4 Throws:
system_error if the threads can't be created and started.thread_pool::~thread_pool()

The thread_pool::~thread_pool() part seems to be a typo.

is_ready clarifications

What is the result if the future is invalid? I guess it is false or does is_ready has as precondition that the future is valid.

In addition I will add a Remark to state clearly that the result of this function is not stable and that the future could become not ready even if the function returned true or vice-versa.

Specify validity of implicitly unwrapped future

The original observation was made by Anthony Williams in N4032 regarding the explicit unwrap, which is no longer part of the proposal. However, even without the explicit unwrap we still have an issue. Consider the following code:

bool func();

void f()
{
    future<int> f1 = async([]() { return 123; });

    future<std::string> f2 = f1.then([](future<int> f) {

        future<std::string> inner_valid = async([]() {
            return std::string("fred");
        });

        future<std::string> inner_invalid;

        future<std::string> result;

        result = func() ? std::move(inner_valid) : std::move(inner_invalid);

        return result; // implicit unwrap
    });

    auto v = f2.valid(); // valid or not?
}

It is not possible to determine if f2 should be valid or not before the functor passed into then has completed. The proposal is to make the future valid, but if the inner future ends up as not valid, the outer future (f2) becomes ready with an exception of type std::future_error, with an error code of std::future_errc::broken_promise.

clarifications on when_all() effects second

The Effects clause
The future returned by when_all will not throw an exception, but the futures held in the output collection may.

I would say

The future returned by when_all will not throw an exception when calling wait() or get(), but the futures held in the output collection may.

Replace thrid by second

There are yet some "the third function" that should be replaced by "the second function" or the function with a launch parameter.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.