// 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(); } } }