blob: 00cf74f76c81de8cc6baa34b85ec1a9bcbdf06c5 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
/* task.vala
*
* Copyright (C) 2013 Maciej Piechotka
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Author:
* Maciej Piechotka <uzytkownik2@gmail.com>
*/
namespace Gee {
[CCode (scope = "async")]
public delegate G Task<G>();
/**
* Schedules a task to execute asynchroniously. Internally one
* of threads from pool will execute the task.
*
* Note: There is limited number of threads unless environment variable
* ``GEE_NUM_THREADS`` is set to -1. It is not advised to call I/O or
* block inside the taks. If necessary it is possible to create a new one
* by anyther call.
*
* @param task Task to be executed
* @return Future value returned by task
* @see async_task
* @since 0.11.0
*/
public Future<G> task<G>(owned Task<G> task) throws GLib.ThreadError {
TaskData<G> tdata = new TaskData<G>();
tdata.function = (owned)task;
tdata.promise = new Promise<G>();
Future<G> result = tdata.promise.future;
TaskData.get_async_pool ().add ((owned)tdata);
return result;
}
/**
* Continues the execution asynchroniously in helper thread. Internally
* one of threads from pool will execute the task.
*
* Note: There is limited number of threads unless environment variable
* ``GEE_NUM_THREADS`` is set to -1. It is not advised to call I/O or
* block inside the taks. If necessary it is possible to create a new one
* by anyther call.
*
* @see task
* @since 0.11.0
*/
public async void async_task() throws GLib.ThreadError {
task<bool>(async_task.callback);
}
[Compact]
internal class TaskData<G> {
public Task<G> function;
public Promise<G> promise;
public void run() {
promise.set_value(function());
}
private static GLib.Once<ThreadPool<TaskData>> async_pool;
internal static unowned ThreadPool<TaskData> get_async_pool () {
return async_pool.once(() => {
int num_threads = (int)GLib.get_num_processors ();
string? gee_num_threads_str = Environment.get_variable("GEE_NUM_THREADS");
if (gee_num_threads_str != null) {
int64 result;
if (int64.try_parse (gee_num_threads_str, out result)) {
num_threads = (int)result;
}
}
try {
return new ThreadPool<TaskData>.with_owned_data((tdata) => {
tdata.run();
}, num_threads, false);
} catch (ThreadError err) {
Process.abort ();
}
});
}
}
}
|