mirror of
https://github.com/golang/go
synced 2024-11-20 11:14:45 -07:00
d90e7cbac6
tests: all.bash passes, gobuild still works, godoc still works. R=rsc OCL=30096 CL=30102
47 lines
1.1 KiB
Go
47 lines
1.1 KiB
Go
// 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.
|
|
|
|
// This package provides a single function, Do, to run a function
|
|
// exactly once, usually used as part of initialization.
|
|
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;
|
|
|
|
// Do is the the only exported piece of the package.
|
|
// For one-time initialization that is not done during init,
|
|
// wrap the initialization in a niladic function f() and call
|
|
// Do(f)
|
|
// If multiple processes call Do(f) simultaneously
|
|
// with the same f argument, only one will call f, and the
|
|
// others will block until f finishes running.
|
|
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();
|
|
}
|
|
}
|
|
}
|