t = reflect.ParseTypeString("*(a int8, b int32)");
s = reflect.ToString(t); print(s, "\n");
- t = reflect.ParseTypeString("struct {c *(? *chan *int32, ? *int8)}");
+ t = reflect.ParseTypeString("struct {c *(? *chan *P.integer, ? *int8)}");
s = reflect.ToString(t); print(s, "\n");
}
// Cache of expanded types keyed by type name.
var types *map[string] *Type // BUG TODO: should be Type not *Type
+
// List of typename, typestring pairs
var typestrings *map[string] string
+
// Map of basic types to prebuilt StubTypes
var basicstubs *map[string] *StubType
var MissingStub *StubType;
+// The database stored in the maps is global; use locking to guarantee safety.
+var lockchan *chan bool // Channel with buffer of 1, used as a mutex
+
+func Lock() {
+ lockchan <- true // block if buffer is full
+}
+
+func Unlock() {
+ <-lockchan // release waiters
+}
+
func init() {
+ lockchan = new(chan bool, 1); // unlocked at creation - buffer is empty
+ Lock(); // not necessary because of init ordering but be safe.
+
types = new(map[string] *Type);
typestrings = new(map[string] string);
basicstubs = new(map[string] *StubType);
basicstubs["float80"] = NewStubType(Float80);
basicstubs["string"] = NewStubType(String);
- typestrings["P.integer"] = "int32";
- return;
- typestrings["P.S"] = "struct {t *P.T}";
- typestrings["P.T"] = "struct {c *(? *chan P.S, *int)}";
+ typestrings["P.integer"] = "int32"; // TODO: for testing; remove
+
+ Unlock();
}
/*
return p.Type().Get();
}
-// Look up type string associated with name.
+// Look up type string associated with name. Lock is held.
func TypeNameToTypeString(name string) string {
s, ok := typestrings[name];
if !ok {
// Type is known by name. Find (and create if necessary) its real type.
func ExpandType(name string) Type {
+ Lock();
t, ok := types[name];
if ok {
+ Unlock();
return *t
}
types[name] = &Missing; // prevent recursion; will overwrite
p := new(Type);
*p = t1;
types[name] = p;
+ Unlock();
return t1;
}