summaryrefslogtreecommitdiff
path: root/src/lib/once.go
blob: 2a09a179bc1e7b14822b5129318d47214ba8a476 (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
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// For one-time initialization that is not done during init.
// Wrap the initialization in a niladic function f() and call
//	once.Do(f)
// If multiple processes call once.Do(f) simultaneously
// with the same f argument, only one will call f, and the
// others will block until f finishes running.

package once

import "sync"

type job struct {
	done bool;
	sync.Mutex;	// should probably be sync.Notification or some such
}

var jobs = make(map[func()]*job)
var joblock sync.Mutex;

func Do(f func()) {
	joblock.Lock();
	j, present := jobs[f];
	if !present {
		// run it
		j = new(job);
		j.Lock();
		jobs[f] = j;
		joblock.Unlock();
		f();
		j.done = true;
		j.Unlock();
	} else {
		// wait for it
		joblock.Unlock();
		if j.done != true {
			j.Lock();
			j.Unlock();
		}
	}
}