The list of packages to be created is now thread-local and its manipulation is thus thread safe.

This commit is contained in:
Juan Jose Garcia Ripoll 2010-10-24 00:00:22 +02:00
parent f5da73b361
commit 89ad07fefc
5 changed files with 59 additions and 32 deletions

View file

@ -177,6 +177,9 @@ ecl_init_env(cl_env_ptr env)
}
env->trap_fpe_bits = 0;
env->packages_to_be_created = Cnil;
env->packages_to_be_created_p = Cnil;
}
void
@ -382,8 +385,6 @@ struct cl_core_struct cl_core = {
#endif
Cnil, /* mp_package */
Cnil, /* c_package */
Cnil, /* packages_to_be_created */
Cnil, /* packages_to_be_created_p */
Cnil, /* pathname_translations */
Cnil, /* library_pathname */
@ -538,6 +539,7 @@ cl_boot(int argc, char **argv)
cl_core.path_max = MAXPATHLEN;
#endif
env->packages_to_be_created = Cnil;
cl_core.lisp_package =
ecl_make_package(str_common_lisp,
cl_list(2, str_cl, str_LISP),

View file

@ -120,9 +120,41 @@ make_package_hashtable()
Cnil); /* lockable */
}
static cl_object
alloc_package(cl_object name)
{
cl_object p = ecl_alloc_object(t_package);
p->pack.internal = make_package_hashtable();
p->pack.external = make_package_hashtable();
p->pack.name = name;
p->pack.nicknames = Cnil;
p->pack.shadowings = Cnil;
p->pack.uses = Cnil;
p->pack.usedby = Cnil;
p->pack.locked = FALSE;
return p;
}
cl_object
_ecl_package_to_be_created(cl_env_ptr env, cl_object name)
{
cl_object package = ecl_assoc(name, env->packages_to_be_created);
if (Null(package)) {
const cl_env_ptr env = ecl_process_env();
package = alloc_package(name);
env->packages_to_be_created =
cl_acons(name, package, env->packages_to_be_created);
} else {
package = ECL_CONS_CDR(package);
}
return package;
}
cl_object
ecl_make_package(cl_object name, cl_object nicknames, cl_object use_list)
{
const cl_env_ptr env = ecl_process_env();
cl_object x, y, other;
name = cl_string(name);
@ -133,8 +165,8 @@ ecl_make_package(cl_object name, cl_object nicknames, cl_object use_list)
* created and use it.
*/
PACKAGE_OP_LOCK();
{
cl_object l = cl_core.packages_to_be_created;
if (ecl_get_option(ECL_OPT_BOOTED)) {
cl_object l = env->packages_to_be_created;
while (!Null(l)) {
cl_object pair = ECL_CONS_CAR(l);
cl_object other_name = ECL_CONS_CAR(pair);
@ -143,9 +175,9 @@ ecl_make_package(cl_object name, cl_object nicknames, cl_object use_list)
@':test', @'string=') != Cnil)
{
x = ECL_CONS_CDR(pair);
cl_core.packages_to_be_created =
env->packages_to_be_created =
ecl_remove_eq(pair,
cl_core.packages_to_be_created);
env->packages_to_be_created);
goto INTERN;
}
l = ECL_CONS_CDR(l);
@ -160,16 +192,8 @@ ecl_make_package(cl_object name, cl_object nicknames, cl_object use_list)
other, 1, name);
return other;
}
x = ecl_alloc_object(t_package);
x->pack.internal = make_package_hashtable();
x->pack.external = make_package_hashtable();
x = alloc_package(name);
INTERN:
x->pack.name = name;
x->pack.nicknames = Cnil;
x->pack.shadowings = Cnil;
x->pack.uses = Cnil;
x->pack.usedby = Cnil;
x->pack.locked = FALSE;
loop_for_in(nicknames) {
cl_object nick = cl_string(ECL_CONS_CAR(nicknames));
if ((other = ecl_find_package_nolock(nick)) != Cnil) {

View file

@ -252,17 +252,11 @@ LOOP:
all referenced packages have been properly built.
*/
cl_object name = cl_copy_seq(token);
unlikely_if (cl_core.packages_to_be_created_p == Cnil) {
unlikely_if (Null(the_env->packages_to_be_created_p)) {
FEerror("There is no package with the name ~A.",
1, name);
} else if (!Null(p = ecl_assoc(name, cl_core.packages_to_be_created))) {
p = CDR(p);
} else {
p = ecl_make_package(name,Cnil,Cnil);
cl_core.packages = CDR(cl_core.packages);
cl_core.packages_to_be_created =
cl_acons(name, p, cl_core.packages_to_be_created);
}
p = _ecl_package_to_be_created(the_env, name);
}
TOKEN_STRING_FILLP(token) = length = 0;
upcase = count = colon = 0;
@ -2154,7 +2148,7 @@ cl_object
read_VV(cl_object block, void (*entry_point)(cl_object))
{
const cl_env_ptr env = ecl_process_env();
volatile cl_object old_eptbc = cl_core.packages_to_be_created;
volatile cl_object old_eptbc = env->packages_to_be_created;
volatile cl_object x;
cl_index i, len, perm_len, temp_len;
cl_object in;
@ -2188,7 +2182,7 @@ read_VV(cl_object block, void (*entry_point)(cl_object))
cl_object progv_list;
ecl_bds_bind(env, @'si::*cblock*', block);
cl_core.packages_to_be_created_p = Ct;
env->packages_to_be_created_p = Ct;
/* Communicate the library which Cblock we are using, and get
* back the amount of data to be processed.
@ -2266,7 +2260,7 @@ read_VV(cl_object block, void (*entry_point)(cl_object))
"binary file", in, 0);
#endif
NO_DATA_LABEL:
cl_core.packages_to_be_created_p = Cnil;
env->packages_to_be_created_p = Cnil;
for (i = 0; i < block->cblock.cfuns_size; i++) {
const struct ecl_cfun *prototype = block->cblock.cfuns+i;
@ -2290,8 +2284,8 @@ read_VV(cl_object block, void (*entry_point)(cl_object))
}
/* Execute top-level code */
(*entry_point)(MAKE_FIXNUM(0));
x = cl_set_difference(2, cl_core.packages_to_be_created, old_eptbc);
old_eptbc = cl_core.packages_to_be_created;
x = cl_set_difference(2, env->packages_to_be_created, old_eptbc);
old_eptbc = env->packages_to_be_created;
unlikely_if (!Null(x)) {
CEerror(Ct,
Null(ECL_CONS_CDR(x))?
@ -2310,8 +2304,8 @@ read_VV(cl_object block, void (*entry_point)(cl_object))
} CL_UNWIND_PROTECT_EXIT {
if (in != OBJNULL)
cl_close(1,in);
cl_core.packages_to_be_created = old_eptbc;
cl_core.packages_to_be_created_p = Cnil;
env->packages_to_be_created = old_eptbc;
env->packages_to_be_created_p = Cnil;
} CL_UNWIND_PROTECT_END;
return block;

View file

@ -135,6 +135,11 @@ struct cl_env_struct {
/* Old exception filter. Needed by windows. */
void *old_exception_filter;
/* List of packages interned when loading a FASL but which have
* to be explicitely created by the compiled code itself. */
cl_object packages_to_be_created;
cl_object packages_to_be_created_p;
};
#ifndef __GNUC__
@ -173,8 +178,6 @@ struct cl_core_struct {
#endif
cl_object mp_package;
cl_object c_package;
cl_object packages_to_be_created;
cl_object packages_to_be_created_p;
cl_object pathname_translations;
cl_object library_pathname;

View file

@ -341,6 +341,10 @@ extern void cl_write_object(cl_object x, cl_object stream);
#define RTABSIZE CHAR_CODE_LIMIT /* read table size */
#endif
/* package.d */
extern cl_object _ecl_package_to_be_created(const cl_env_ptr env, cl_object name);
/* sequence.d */
typedef struct { cl_index start, end, length; } cl_index_pair;
extern ECL_API cl_index_pair ecl_sequence_start_end(cl_object fun, cl_object s, cl_object start, cl_object end);