Branch: Tag:

2016-09-19

2016-09-19 13:17:39 by Henrik Grubbström (Grubba) <grubba@grubba.org>

Compiler [master]: Improved thread-safety.

Cast to program and cast to object should now be thread-safe.

Fixes some more of [bug 7783].

1080:   {    // When running with trace, this function can get called    // before __INIT has completed. +  // NB: We need to be reasonably thread safe, as the compiler +  // may be running in another thread.    if (!rev_programs) return UNDEFINED;    if (sizeof (rev_programs) < sizeof (programs)) {    foreach (programs; string path; program|NoValue prog)
1094:   program objects_reverse_lookup (object obj)   //! Returns the program for @[obj], if known to the master.   { +  // NB: We need to be reasonably thread safe, as the compiler +  // may be running in another thread.    if (sizeof (rev_objects) < sizeof (objects)) {    foreach (objects; program prog; object|NoValue obj)    if (obj == no_value)
1398:    }   #endif    +  object compiler_lock = DefaultCompilerEnvironment->lock(); +  if(!undefinedp(ret = programs[fname]) && (ret != no_value)) { +  destruct(compiler_lock); +  resolv_debug("low_findprog %s: returning cached (from other thread).\n", +  fname); +  return ret; +  } +     switch(ext)    {    case "":
1447:    }    }    -  object compiler_lock = DefaultCompilerEnvironment->lock(); -  if(!undefinedp(ret = programs[fname]) && (ret != no_value)) { -  destruct(compiler_lock); -  resolv_debug("low_findprog %s: returning cached (from other thread).\n", -  fname); -  return ret; -  } +     resolv_debug ("low_findprog %s: compiling, mkobj: %O\n", fname, mkobj);    INC_RESOLV_MSG_DEPTH();    programs[fname]=ret=__empty_program(0, fname);
1543:   void unregister(program p)   {    // werror("Unregistering %O...\n", p); +  object compiler_lock = DefaultCompilerEnvironment->lock(); +     if(string fname=rev_programs[p] || search(programs,p)) {    resolv_debug("unregister %s\n", fname);    if (m_delete (rev_programs, p))
1618:    ext="";    }    +  // NB: No need to lock the compiler here; findprog() will +  // lock and reprobe on miss in the programs mapping.    if(IS_ABSOLUTE_PATH(pname))    {    program|NoValue prog = programs[pname];
1884:       p = low_cast_to_program(oname, current_file, current_handler, 1);    if(!p) return 0; +  if(!objectp(o = objects[p])) { +  object compiler_lock = DefaultCompilerEnvironment->lock();    // NB: p might be a function in a fake_object... -  if(!objectp (o=objects[p])) o=objects[p]=p(); +  if(!objectp(o = objects[p])) o = objects[p] = p(); +  destruct(compiler_lock); +  }    return o;   }   
2133:    if (!ret->_module_value) {    object o;    // NB: p might be a function in a fake_object... -  if(!objectp (o=objects[ret])) o=objects[ret]=ret(); +  if(!objectp(o = objects[ret])) { +  object compiler_lock = DefaultCompilerEnvironment->lock(); +  if(!objectp(o = objects[ret])) o = objects[ret] = ret(); +  destruct(compiler_lock); +  }    ret = o;    }    if(mixed tmp=ret->_module_value) ret=tmp;
5220:    object __register_new_program(program p)    {    DEC_MSG ("__register_new_program (%O)\n", p); +  // NB: decode_value() has already locked the compiler, so we +  // should not need to lock it here.    if(unregistered && fname)    {    unregistered = 0;