Merge: Actors upgrade and fixes
authorJean Privat <jean@pryen.org>
Tue, 6 Jun 2017 15:37:33 +0000 (11:37 -0400)
committerJean Privat <jean@pryen.org>
Tue, 6 Jun 2017 15:37:33 +0000 (11:37 -0400)
`BlockingQueue` and `ReverseBlockingQueue` classes have been removed from  `lib/actors`  and are now in `lib/pthreads/concurrent_collections` because it's a better fit for them.
Also, since the implementation of `BlockingQueue` was too coupled with actors, the actor-specific implementation was kept in `lib/actors` and renamed as `Mailbox`.

`ReverseBlockingQueue` is a fun name and could be useful for some specific cases (as it was used in `lib/actors` or for synchronization on a list of dynamic tasks for example), but was too heavy for it's purpose in the `lib/actors` module. It's been replaced with a `SynchronizedCounter`. The `wait` method of this counter is blocking until the counter value equals 0.

There was multiple synchronization problems with the actor library :
* The creation of `async`, aka the proxy wasn't synchronized, which means we could create multiple instances of an actor if multiple threads called `async` on an object simultaneously
* Due to the asynchronous start of an actor (a new on a Nit Thread can return before the actual underlying C pthread started running), there was some cases where the mecanism used to wait for every actors to be idle before exiting a program was broken.

This PR adresses theses 2 bugs. The first one is just adding a mutex used for the creation of the `async` object.

The second one was adressed by moving the logic dealing with the idle state of an actor directly into his mailbox.

This PR also makes it possible to redefine an actor class. `lib/actors/agent_simulation` provides an example of this feature:
* `agent_simulation.nit` defines a simple api to which defines a Multi-agent simulation. The `ClockWorker` is in charge of the simulation and executes every steps, waiting for one to be finished before launching the other. the list of `Agent` it manages are all the agents of the simulation, which are actors too.
* `simple_simulation.nit` redefine the `Agent` class to add specific services for a specific simulation. Here, each agent knows every other one in the simluation and greets them, wait to be greeted back by everyone, then signals the clock that it finished the step.

This feature can be useful, but hasn't been fully tested yet. Furthermore, the Nit actor model still doesn't support subclassing an actor, which could also be really useful.

Well, that's pretty much it, enjoy reading :p

Pull-Request: #2425
Reviewed-by: Alexis Laferrière <alexis.laf@xymus.net>
Reviewed-by: Jean-Christophe Beaupré <jcbrinfo.public@gmail.com>
Reviewed-by: Jean Privat <jean@pryen.org>


Trivial merge