Skip to content

Commit 803a4f4

Browse files
committed
libcore: Remove mutable fields from the task builder API
1 parent 226ee7d commit 803a4f4

File tree

8 files changed

+87
-131
lines changed

8 files changed

+87
-131
lines changed

src/libcore/task/mod.rs

+60-118
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ pub struct SchedOpts {
156156
pub struct TaskOpts {
157157
linked: bool,
158158
supervised: bool,
159-
mut notify_chan: Option<Chan<TaskResult>>,
159+
notify_chan: Option<Chan<TaskResult>>,
160160
sched: SchedOpts
161161
}
162162

@@ -176,9 +176,9 @@ pub struct TaskOpts {
176176
// FIXME (#3724): Replace the 'consumed' bit with move mode on self
177177
pub struct TaskBuilder {
178178
opts: TaskOpts,
179-
mut gen_body: Option<~fn(v: ~fn()) -> ~fn()>,
179+
gen_body: Option<~fn(v: ~fn()) -> ~fn()>,
180180
can_not_copy: Option<util::NonCopyable>,
181-
mut consumed: bool,
181+
consumed: bool,
182182
}
183183

184184
/**
@@ -191,13 +191,13 @@ pub fn task() -> TaskBuilder {
191191
opts: default_task_opts(),
192192
gen_body: None,
193193
can_not_copy: None,
194-
mut consumed: false,
194+
consumed: false,
195195
}
196196
}
197197

198198
#[doc(hidden)] // FIXME #3538
199199
priv impl TaskBuilder {
200-
fn consume(&self) -> TaskBuilder {
200+
fn consume(&mut self) -> TaskBuilder {
201201
if self.consumed {
202202
fail!(~"Cannot copy a task_builder"); // Fake move mode on self
203203
}
@@ -219,57 +219,23 @@ priv impl TaskBuilder {
219219
}
220220
221221
pub impl TaskBuilder {
222-
/**
223-
* Decouple the child task's failure from the parent's. If either fails,
224-
* the other will not be killed.
225-
*/
226-
fn unlinked(&self) -> TaskBuilder {
227-
let notify_chan = replace(&mut self.opts.notify_chan, None);
228-
TaskBuilder {
229-
opts: TaskOpts {
230-
linked: false,
231-
supervised: self.opts.supervised,
232-
notify_chan: notify_chan,
233-
sched: self.opts.sched
234-
},
235-
can_not_copy: None,
236-
.. self.consume()
237-
}
222+
/// Decouple the child task's failure from the parent's. If either fails,
223+
/// the other will not be killed.
224+
fn unlinked(&mut self) {
225+
self.opts.linked = false;
238226
}
239-
/**
240-
* Unidirectionally link the child task's failure with the parent's. The
241-
* child's failure will not kill the parent, but the parent's will kill
242-
* the child.
243-
*/
244-
fn supervised(&self) -> TaskBuilder {
245-
let notify_chan = replace(&mut self.opts.notify_chan, None);
246-
TaskBuilder {
247-
opts: TaskOpts {
248-
linked: false,
249-
supervised: true,
250-
notify_chan: notify_chan,
251-
sched: self.opts.sched
252-
},
253-
can_not_copy: None,
254-
.. self.consume()
255-
}
227+
228+
/// Unidirectionally link the child task's failure with the parent's. The
229+
/// child's failure will not kill the parent, but the parent's will kill
230+
/// the child.
231+
fn supervised(&mut self) {
232+
self.opts.supervised = true;
256233
}
257-
/**
258-
* Link the child task's and parent task's failures. If either fails, the
259-
* other will be killed.
260-
*/
261-
fn linked(&self) -> TaskBuilder {
262-
let notify_chan = replace(&mut self.opts.notify_chan, None);
263-
TaskBuilder {
264-
opts: TaskOpts {
265-
linked: true,
266-
supervised: false,
267-
notify_chan: notify_chan,
268-
sched: self.opts.sched
269-
},
270-
can_not_copy: None,
271-
.. self.consume()
272-
}
234+
235+
/// Link the child task's and parent task's failures. If either fails, the
236+
/// other will be killed.
237+
fn linked(&mut self) {
238+
self.opts.linked = true;
273239
}
274240
275241
/**
@@ -289,7 +255,7 @@ pub impl TaskBuilder {
289255
* # Failure
290256
* Fails if a future_result was already set for this task.
291257
*/
292-
fn future_result(&self, blk: &fn(v: Port<TaskResult>)) -> TaskBuilder {
258+
fn future_result(&mut self, blk: &fn(v: Port<TaskResult>)) {
293259
// FIXME (#3725): Once linked failure and notification are
294260
// handled in the library, I can imagine implementing this by just
295261
// registering an arbitrary number of task::on_exit handlers and
@@ -305,30 +271,12 @@ pub impl TaskBuilder {
305271
blk(notify_pipe_po);
306272
307273
// Reconfigure self to use a notify channel.
308-
TaskBuilder {
309-
opts: TaskOpts {
310-
linked: self.opts.linked,
311-
supervised: self.opts.supervised,
312-
notify_chan: Some(notify_pipe_ch),
313-
sched: self.opts.sched
314-
},
315-
can_not_copy: None,
316-
.. self.consume()
317-
}
274+
self.opts.notify_chan = Some(notify_pipe_ch);
318275
}
276+
319277
/// Configure a custom scheduler mode for the task.
320-
fn sched_mode(&self, mode: SchedMode) -> TaskBuilder {
321-
let notify_chan = replace(&mut self.opts.notify_chan, None);
322-
TaskBuilder {
323-
opts: TaskOpts {
324-
linked: self.opts.linked,
325-
supervised: self.opts.supervised,
326-
notify_chan: notify_chan,
327-
sched: SchedOpts { mode: mode, foreign_stack_size: None}
328-
},
329-
can_not_copy: None,
330-
.. self.consume()
331-
}
278+
fn sched_mode(&mut self, mode: SchedMode) {
279+
self.opts.sched.mode = mode;
332280
}
333281
334282
/**
@@ -343,7 +291,7 @@ pub impl TaskBuilder {
343291
* generator by applying the task body which results from the
344292
* existing body generator to the new body generator.
345293
*/
346-
fn add_wrapper(&self, wrapper: ~fn(v: ~fn()) -> ~fn()) -> TaskBuilder {
294+
fn add_wrapper(&mut self, wrapper: ~fn(v: ~fn()) -> ~fn()) {
347295
let prev_gen_body = replace(&mut self.gen_body, None);
348296
let prev_gen_body = match prev_gen_body {
349297
Some(gen) => gen,
@@ -360,18 +308,7 @@ pub impl TaskBuilder {
360308
};
361309
f
362310
};
363-
let notify_chan = replace(&mut self.opts.notify_chan, None);
364-
TaskBuilder {
365-
opts: TaskOpts {
366-
linked: self.opts.linked,
367-
supervised: self.opts.supervised,
368-
notify_chan: notify_chan,
369-
sched: self.opts.sched
370-
},
371-
gen_body: Some(next_gen_body),
372-
can_not_copy: None,
373-
.. self.consume()
374-
}
311+
self.gen_body = Some(next_gen_body);
375312
}
376313
377314
/**
@@ -386,7 +323,7 @@ pub impl TaskBuilder {
386323
* When spawning into a new scheduler, the number of threads requested
387324
* must be greater than zero.
388325
*/
389-
fn spawn(&self, f: ~fn()) {
326+
fn spawn(&mut self, f: ~fn()) {
390327
let gen_body = replace(&mut self.gen_body, None);
391328
let notify_chan = replace(&mut self.opts.notify_chan, None);
392329
let x = self.consume();
@@ -406,8 +343,9 @@ pub impl TaskBuilder {
406343
};
407344
spawn::spawn_raw(opts, f);
408345
}
346+
409347
/// Runs a task, while transfering ownership of one argument to the child.
410-
fn spawn_with<A:Owned>(&self, arg: A, f: ~fn(v: A)) {
348+
fn spawn_with<A:Owned>(&mut self, arg: A, f: ~fn(v: A)) {
411349
let arg = Cell(arg);
412350
do self.spawn {
413351
f(arg.take());
@@ -427,16 +365,16 @@ pub impl TaskBuilder {
427365
* # Failure
428366
* Fails if a future_result was already set for this task.
429367
*/
430-
fn try<T:Owned>(&self, f: ~fn() -> T) -> Result<T,()> {
368+
fn try<T:Owned>(&mut self, f: ~fn() -> T) -> Result<T,()> {
431369
let (po, ch) = stream::<T>();
432370
let mut result = None;
433371
434-
let fr_task_builder = self.future_result(|+r| {
435-
result = Some(r);
436-
});
437-
do fr_task_builder.spawn || {
372+
self.future_result(|+r| { result = Some(r); });
373+
374+
do self.spawn {
438375
ch.send(f());
439376
}
377+
440378
match result.unwrap().recv() {
441379
Success => result::Ok(po.recv()),
442380
Failure => result::Err(())
@@ -468,26 +406,23 @@ pub fn default_task_opts() -> TaskOpts {
468406
469407
/* Spawn convenience functions */
470408
409+
/// Creates and executes a new child task
410+
///
411+
/// Sets up a new task with its own call stack and schedules it to run
412+
/// the provided unique closure.
413+
///
414+
/// This function is equivalent to `task().spawn(f)`.
471415
pub fn spawn(f: ~fn()) {
472-
/*!
473-
* Creates and executes a new child task
474-
*
475-
* Sets up a new task with its own call stack and schedules it to run
476-
* the provided unique closure.
477-
*
478-
* This function is equivalent to `task().spawn(f)`.
479-
*/
480-
481-
task().spawn(f)
416+
let mut task = task();
417+
task.spawn(f)
482418
}
483419
420+
/// Creates a child task unlinked from the current one. If either this
421+
/// task or the child task fails, the other will not be killed.
484422
pub fn spawn_unlinked(f: ~fn()) {
485-
/*!
486-
* Creates a child task unlinked from the current one. If either this
487-
* task or the child task fails, the other will not be killed.
488-
*/
489-
490-
task().unlinked().spawn(f)
423+
let mut task = task();
424+
task.unlinked();
425+
task.spawn(f)
491426
}
492427
493428
pub fn spawn_supervised(f: ~fn()) {
@@ -497,7 +432,9 @@ pub fn spawn_supervised(f: ~fn()) {
497432
* the child will be killed.
498433
*/
499434
500-
task().supervised().spawn(f)
435+
let mut task = task();
436+
task.supervised();
437+
task.spawn(f)
501438
}
502439
503440
pub fn spawn_with<A:Owned>(arg: A, f: ~fn(v: A)) {
@@ -511,7 +448,8 @@ pub fn spawn_with<A:Owned>(arg: A, f: ~fn(v: A)) {
511448
* This function is equivalent to `task().spawn_with(arg, f)`.
512449
*/
513450
514-
task().spawn_with(arg, f)
451+
let mut task = task();
452+
task.spawn_with(arg, f)
515453
}
516454
517455
pub fn spawn_sched(mode: SchedMode, f: ~fn()) {
@@ -527,7 +465,9 @@ pub fn spawn_sched(mode: SchedMode, f: ~fn()) {
527465
* greater than zero.
528466
*/
529467
530-
task().sched_mode(mode).spawn(f)
468+
let mut task = task();
469+
task.sched_mode(mode);
470+
task.spawn(f)
531471
}
532472
533473
pub fn try<T:Owned>(f: ~fn() -> T) -> Result<T,()> {
@@ -538,7 +478,9 @@ pub fn try<T:Owned>(f: ~fn() -> T) -> Result<T,()> {
538478
* This is equivalent to task().supervised().try.
539479
*/
540480
541-
task().supervised().try(f)
481+
let mut task = task();
482+
task.supervised();
483+
task.try(f)
542484
}
543485
544486
@@ -822,7 +764,7 @@ fn test_run_basic() {
822764
823765
#[cfg(test)]
824766
struct Wrapper {
825-
mut f: Option<Chan<()>>
767+
f: Option<Chan<()>>
826768
}
827769
828770
#[test]

src/libcore/task/spawn.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ fn spawn_raw_newsched(_opts: TaskOpts, f: ~fn()) {
580580
sched.schedule_new_task(task);
581581
}
582582
583-
fn spawn_raw_oldsched(opts: TaskOpts, f: ~fn()) {
583+
fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) {
584584
585585
let (child_tg, ancestors, is_main) =
586586
gen_child_taskgroup(opts.linked, opts.supervised);

src/libcore/unstable/at_exit.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ fn exit_runner(exit_fns: *ExitFunctions) {
7070
while !exit_fns_vec.is_empty() {
7171
match exit_fns_vec.pop() {
7272
~f => {
73-
task::task().supervised().spawn(f);
73+
let mut task = task::task();
74+
task.supervised();
75+
task.spawn(f);
7476
}
7577
}
7678
}

src/libcore/unstable/weak_task.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ fn create_global_service() -> ~WeakTaskService {
7272
let chan = SharedChan::new(chan);
7373
let chan_clone = chan.clone();
7474

75-
do task().unlinked().spawn {
75+
let mut task = task();
76+
task.unlinked();
77+
do task.spawn {
7678
debug!("running global weak task service");
7779
let port = Cell(port.take());
7880
do (|| {

src/libstd/task_pool.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ pub impl<T> TaskPool<T> {
7070
task::spawn(task_body);
7171
}
7272
Some(sched_mode) => {
73-
task::task().sched_mode(sched_mode).spawn(task_body);
73+
let mut task = task::task();
74+
task.sched_mode(sched_mode);
75+
task.spawn(task_body);
7476
}
7577
}
7678

src/libstd/test.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -556,9 +556,12 @@ pub fn run_test(force_ignore: bool,
556556
let testfn_cell = ::core::cell::Cell(testfn);
557557
do task::spawn {
558558
let mut result_future = None; // task::future_result(builder);
559-
task::task().unlinked().future_result(|+r| {
560-
result_future = Some(r);
561-
}).spawn(testfn_cell.take());
559+
560+
let mut task = task::task();
561+
task.unlinked();
562+
task.future_result(|+r| { result_future = Some(r) });
563+
task.spawn(testfn_cell.take());
564+
562565
let task_result = result_future.unwrap().recv();
563566
let test_result = calc_result(&desc,
564567
task_result == task::Success);

0 commit comments

Comments
 (0)