mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-01-15 13:52:16 -08:00
The list of packages to be created is now thread-local and its manipulation is thus thread safe.
This commit is contained in:
parent
f5da73b361
commit
89ad07fefc
5 changed files with 59 additions and 32 deletions
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
24
src/c/read.d
24
src/c/read.d
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue