stas 2004/07/09 17:36:19
Modified: lib/ModPerl MapUtil.pm StructureMap.pm TypeMap.pm WrapXS.pm src/modules/perl mod_perl.c mod_perl.h Log: supports a new type of struct accessor, which is just like read/write one, but doesn't allow write access starting at the ChildInit phase under threaded mpm (to avoid thread-safely issues) Revision Changes Path 1.8 +2 -0 modperl-2.0/lib/ModPerl/MapUtil.pm Index: MapUtil.pm =================================================================== RCS file: /home/cvs/modperl-2.0/lib/ModPerl/MapUtil.pm,v retrieving revision 1.7 retrieving revision 1.8 diff -u -u -r1.7 -r1.8 --- MapUtil.pm 23 Jun 2004 03:30:15 -0000 1.7 +++ MapUtil.pm 10 Jul 2004 00:36:19 -0000 1.8 @@ -25,8 +25,10 @@ our @ISA = qw(Exporter); +# the mapping happens in lib/ModPerl/StructureMap.pm # '<' => 'auto-generated but gives only a read-only access' # '&' => 'RDWR accessor to a char* field, supporting undef arg' +# '$' => 'RONLY accessor, with WRITE accessor before child_init' my %disabled_map = ( '!' => 'disabled or not yet implemented', '~' => 'implemented but not auto-generated', 1.7 +3 -0 modperl-2.0/lib/ModPerl/StructureMap.pm Index: StructureMap.pm =================================================================== RCS file: /home/cvs/modperl-2.0/lib/ModPerl/StructureMap.pm,v retrieving revision 1.6 retrieving revision 1.7 diff -u -u -r1.6 -r1.7 --- StructureMap.pm 28 May 2004 01:35:15 -0000 1.6 +++ StructureMap.pm 10 Jul 2004 00:36:19 -0000 1.7 @@ -125,6 +125,9 @@ elsif ($1 eq '&') { $map->{$class}->{$_} = 'rw_char_undef'; } + elsif ($1 eq '$') { + $map->{$class}->{$_} = 'r+w_startup'; + } } else { $map->{$class}->{$_} = undef; 1.22 +1 -1 modperl-2.0/lib/ModPerl/TypeMap.pm Index: TypeMap.pm =================================================================== RCS file: /home/cvs/modperl-2.0/lib/ModPerl/TypeMap.pm,v retrieving revision 1.21 retrieving revision 1.22 diff -u -u -r1.21 -r1.22 --- TypeMap.pm 17 May 2004 22:57:21 -0000 1.21 +++ TypeMap.pm 10 Jul 2004 00:36:19 -0000 1.22 @@ -293,7 +293,7 @@ my($name, $type) = ($e->{name}, $e->{type}); my $rtype; - # ro/rw/undef(disabled) + # ro/rw/r+w_startup/undef(disabled) my $access_mode = $self->structure_map->{$stype}->{$name}; next unless $access_mode; next unless $rtype = $self->map_type($type); 1.78 +7 -1 modperl-2.0/lib/ModPerl/WrapXS.pm Index: WrapXS.pm =================================================================== RCS file: /home/cvs/modperl-2.0/lib/ModPerl/WrapXS.pm,v retrieving revision 1.77 retrieving revision 1.78 diff -u -u -r1.77 -r1.78 --- WrapXS.pm 25 Jun 2004 15:29:25 -0000 1.77 +++ WrapXS.pm 10 Jul 2004 00:36:19 -0000 1.78 @@ -227,7 +227,12 @@ EOF } - elsif ($access_mode eq 'rw') { + elsif ($access_mode eq 'rw' or $access_mode eq 'r+w_startup') { + + my $check_runtime = $access_mode eq 'rw' + ? '' + : qq[MP_CROAK_IF_THREADS_STARTED("setting $name");]; + $code = <<EOF; $type $name(obj, val=$default) @@ -242,6 +247,7 @@ RETVAL = ($cast) obj->$name; if (items > 1) { + $check_runtime obj->$name = ($cast) $val; } 1.218 +34 -0 modperl-2.0/src/modules/perl/mod_perl.c Index: mod_perl.c =================================================================== RCS file: /home/cvs/modperl-2.0/src/modules/perl/mod_perl.c,v retrieving revision 1.217 retrieving revision 1.218 diff -u -u -r1.217 -r1.218 --- mod_perl.c 7 Jul 2004 19:04:52 -0000 1.217 +++ mod_perl.c 10 Jul 2004 00:36:19 -0000 1.218 @@ -24,6 +24,18 @@ #define MP_IS_STARTING (MP_init_status == 1 ? 1 : 0) #define MP_IS_RUNNING (MP_init_status == 2 ? 1 : 0) +/* false while there is only the parent process and may be child + * processes, but no threads around, useful for allowing things that + * don't require locking and won't affect other threads. It should + * become true just before the child_init phase */ +static int MP_threads_started = 0; + +int modperl_threads_started(void) +{ + return MP_threads_started; +} + + #ifndef USE_ITHREADS static apr_status_t modperl_shutdown(void *data) { @@ -31,6 +43,11 @@ PerlInterpreter *perl = (PerlInterpreter *)cdata->data; void **handles; + /* reset for restarts */ + if (scfg->threaded_mpm) { + MP_threads_started = 0; + } + handles = modperl_xs_dl_handles_get(aTHX); MP_TRACE_i(MP_FUNC, "destroying interpreter=0x%lx\n", @@ -613,6 +630,20 @@ return OK; } +static int modperl_hook_post_config_last(apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp, server_rec *s) +{ + MP_dSCFG(s); + + /* in the threaded environment, no server_rec/process_rec + * modifications should be done beyond this point */ + if (scfg->threaded_mpm) { + MP_threads_started = 1; + } + + return OK; +} + static int modperl_hook_create_request(request_rec *r) { MP_dRCFG; @@ -729,6 +760,9 @@ ap_hook_post_config(modperl_hook_post_config, NULL, NULL, APR_HOOK_FIRST); + + ap_hook_post_config(modperl_hook_post_config_last, + NULL, NULL, APR_HOOK_REALLY_LAST); ap_hook_handler(modperl_response_handler, NULL, NULL, APR_HOOK_MIDDLE); 1.68 +8 -0 modperl-2.0/src/modules/perl/mod_perl.h Index: mod_perl.h =================================================================== RCS file: /home/cvs/modperl-2.0/src/modules/perl/mod_perl.h,v retrieving revision 1.67 retrieving revision 1.68 diff -u -u -r1.67 -r1.68 --- mod_perl.h 25 Jun 2004 15:29:25 -0000 1.67 +++ mod_perl.h 10 Jul 2004 00:36:19 -0000 1.68 @@ -93,6 +93,14 @@ #include "modperl_module.h" #include "modperl_debug.h" +int modperl_threads_started(void); + +#define MP_CROAK_IF_THREADS_STARTED(what) \ + if (modperl_threads_started()) { \ + Perl_croak(aTHX_ "Can't run '%s' in the threaded " \ + "environment after server startup", what); \ + } + int modperl_init_vhost(server_rec *s, apr_pool_t *p, server_rec *base_server); void modperl_init(server_rec *s, apr_pool_t *p);