line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Apache::BabyConnect; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
our @ISA = qw(); |
4
|
|
|
|
|
|
|
our $VERSION = '0.93'; |
5
|
|
|
|
|
|
|
|
6
|
1
|
|
|
1
|
|
44637
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
118
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
die " |
9
|
|
|
|
|
|
|
Apache::BabyConnect cannot start without setting the environment |
10
|
|
|
|
|
|
|
variable BABYCONNECT. You may have forgotten to set BABYCONNECT |
11
|
|
|
|
|
|
|
environment variable prior to loading the Apache::BabyConnect |
12
|
|
|
|
|
|
|
module. |
13
|
|
|
|
|
|
|
In the /etc/httpd/conf.d/perl.conf you need to setup the environment |
14
|
|
|
|
|
|
|
variable before loading the Apache::BabyConnect module. For instance, |
15
|
|
|
|
|
|
|
if you have loaded the Apache::BabyConnect from a startup script |
16
|
|
|
|
|
|
|
using the PerlRequire directive, you can setup the BABYCONNECT |
17
|
|
|
|
|
|
|
environment variable simply by using the directive PerlSetEnv prior |
18
|
|
|
|
|
|
|
to loading the startup script: |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
PerlSetEnv BABYCONNECT /opt/DBI-BabyConnect-$VERSION/configuration |
21
|
|
|
|
|
|
|
PerlRequire /opt/DBI-BabyConnect-$VERSION/startupscripts/babystartup.pl |
22
|
|
|
|
|
|
|
Alias /perl /var/www/perl |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
SetHandler perl-script |
25
|
|
|
|
|
|
|
PerlResponseHandler ModPerl::Registry |
26
|
|
|
|
|
|
|
PerlOptions +ParseHeaders |
27
|
|
|
|
|
|
|
Options +ExecCGI |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
" unless $ENV{BABYCONNECT}; |
31
|
1
|
50
|
33
|
|
|
289
|
use constant MP2 => (exists $ENV{MOD_PERL_API_VERSION} && |
32
|
1
|
|
|
1
|
|
6
|
$ENV{MOD_PERL_API_VERSION} == 2) ? 1 : 0; |
|
1
|
|
|
|
|
2
|
|
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
BEGIN { |
35
|
1
|
50
|
|
1
|
|
25
|
if (MP2) { |
36
|
|
|
|
|
|
|
require mod_perl2; |
37
|
|
|
|
|
|
|
require Apache2::Module; |
38
|
|
|
|
|
|
|
require Apache2::ServerUtil; |
39
|
|
|
|
|
|
|
} |
40
|
0
|
50
|
33
|
|
|
0
|
elsif (defined $modperl::VERSION && $modperl::VERSION > 1 && |
41
|
|
|
|
|
|
|
$modperl::VERSION < 1.99) { |
42
|
0
|
|
|
|
|
0
|
require Apache; |
43
|
|
|
|
|
|
|
} |
44
|
|
|
|
|
|
|
} |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
######################################################################################## |
47
|
|
|
|
|
|
|
# DBI::BabyConnect needs to be called with caching and persistence enabled |
48
|
1
|
|
|
1
|
|
692
|
use DBI::BabyConnect(1,1); |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
use Carp (); |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
$Apache::BabyConnect::VERSION = '1.00'; |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
$Apache::BabyConnect::DEBUG = 3; |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
my @ChildConnect; # connections to be established with each httpd child |
57
|
|
|
|
|
|
|
my $parent_pid; |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
######################################################################################## |
60
|
|
|
|
|
|
|
######################################################################################## |
61
|
|
|
|
|
|
|
sub debug { |
62
|
|
|
|
|
|
|
print STDERR "$_[1]\n" if $Apache::BabyConnect::DEBUG >= $_[0]; |
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
######################################################################################## |
66
|
|
|
|
|
|
|
######################################################################################## |
67
|
|
|
|
|
|
|
# connect_on_init is called in the script babystartup.pl to provide a PerlChildInitHandler |
68
|
|
|
|
|
|
|
# that will be hooked to a DBI::BabyConnect instance. |
69
|
|
|
|
|
|
|
# |
70
|
|
|
|
|
|
|
# The connect_on_init will request a DBI::BabyConnect instance to manage a DBI connection whose |
71
|
|
|
|
|
|
|
# parameters are being described with the database descriptor. Each child |
72
|
|
|
|
|
|
|
# is hooked to such an instance, and the instance is being persisted during the |
73
|
|
|
|
|
|
|
# life time of the child. |
74
|
|
|
|
|
|
|
# Because all childs are being started with the same database descriptor, therefore |
75
|
|
|
|
|
|
|
# they can access the database concurrently. You should be careful on how to use |
76
|
|
|
|
|
|
|
# the connection. Refer to Apache::BabyConnect documentation, and the script testbaby.pl |
77
|
|
|
|
|
|
|
# to understand how the pool of connections work. |
78
|
|
|
|
|
|
|
# You can request new connection from any Perl script, and the connection will be cached |
79
|
|
|
|
|
|
|
# only if the database descriptor cannot be found within the child (httpd child) own |
80
|
|
|
|
|
|
|
# DBI::BabyConnect instance cache. |
81
|
|
|
|
|
|
|
# The caching of connection per each httpd child (or its hooked instance DBI::BabyConnect instance) |
82
|
|
|
|
|
|
|
# is maintained within the DBI::BabyConnect itself, and each entry in the cache is |
83
|
|
|
|
|
|
|
# identified with the concatenation of the child kernel process ID and the database descriptor. |
84
|
|
|
|
|
|
|
# |
85
|
|
|
|
|
|
|
sub connect_on_init { |
86
|
|
|
|
|
|
|
if (MP2) { |
87
|
|
|
|
|
|
|
if (!@ChildConnect) { |
88
|
|
|
|
|
|
|
my $s = Apache2::ServerUtil->server; |
89
|
|
|
|
|
|
|
debug(1, "\n***!!!!!!!!! $$ connect_on_init / MP2 Apache2::ServerUtil->server NOT ChildConnect === @ChildConnect\n\n"); |
90
|
|
|
|
|
|
|
$s-> push_handlers(PerlChildInitHandler => \&childinit); |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
} |
93
|
|
|
|
|
|
|
else { |
94
|
|
|
|
|
|
|
Carp::carp("Apache.pm was not loaded\n") |
95
|
|
|
|
|
|
|
and return unless $INC{'Apache.pm'}; |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
if (!@ChildConnect and Apache->can('push_handlers')) { |
98
|
|
|
|
|
|
|
Apache->push_handlers(PerlChildInitHandler => \&childinit); |
99
|
|
|
|
|
|
|
} |
100
|
|
|
|
|
|
|
} |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
debug(1, "\n*** connect_on_init / store connections === $$ @_\n\n"); |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
# store connections |
105
|
|
|
|
|
|
|
$parent_pid = $$; |
106
|
|
|
|
|
|
|
push @ChildConnect, [@_]; |
107
|
|
|
|
|
|
|
#foreach (@ChildConnect) { print STDERR "************** Childconnect: @$_\n"; #} |
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
######################################################################################## |
111
|
|
|
|
|
|
|
######################################################################################## |
112
|
|
|
|
|
|
|
# The PerlChildInitHandler creates all connections during server startup. |
113
|
|
|
|
|
|
|
# Note: this handler runs in every child server, but not in the main server. |
114
|
|
|
|
|
|
|
sub childinit { |
115
|
|
|
|
|
|
|
my $prefix = " $$ Apache::BabyConnect "; |
116
|
|
|
|
|
|
|
debug(2, "$prefix PerlChildInitHandler"); |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
while (@ChildConnect) { |
119
|
|
|
|
|
|
|
for my $aref (@ChildConnect) { |
120
|
|
|
|
|
|
|
debug(2, "\n\n************** Childconnect: @$aref"); |
121
|
|
|
|
|
|
|
my @da = @$aref; |
122
|
|
|
|
|
|
|
shift @da; |
123
|
|
|
|
|
|
|
my %da; |
124
|
|
|
|
|
|
|
while (my($l,$r)=splice @da, 0, 2) { |
125
|
|
|
|
|
|
|
$da{$l} = $r; |
126
|
|
|
|
|
|
|
} |
127
|
|
|
|
|
|
|
my ($arg_iconf,$arg_errlog,$arg_tralog,$arg_tralev) = |
128
|
|
|
|
|
|
|
@{ %da } { qw(DESCRIPTOR ERROR_FILE TRACE_FILE TRACE_LEVEL) }; |
129
|
|
|
|
|
|
|
$arg_errlog ||= ""; |
130
|
|
|
|
|
|
|
$arg_tralog ||= ""; |
131
|
|
|
|
|
|
|
$arg_tralev ||= ""; |
132
|
|
|
|
|
|
|
#my $arg_iconf = ${@$aref}[1]; |
133
|
|
|
|
|
|
|
#my $arg_errlog = ${@$aref}[2] || ""; |
134
|
|
|
|
|
|
|
#my $arg_tralog = ${@$aref}[3] || ""; |
135
|
|
|
|
|
|
|
#my $arg_tralev = ${@$aref}[4] || ""; |
136
|
|
|
|
|
|
|
debug(2, " Child / ${@$aref}[0] requesting an instance of Apache::BabyConnect($arg_iconf) "); |
137
|
|
|
|
|
|
|
debug(2, " HookError($arg_errlog)"); |
138
|
|
|
|
|
|
|
debug(2, " HookTracing($arg_tralog) with TraceLevel=$arg_tralev) "); |
139
|
|
|
|
|
|
|
my $cnn = DBI::BabyConnect->new($arg_iconf); |
140
|
|
|
|
|
|
|
# this redirection seems to work, but the need need debugging because it is altering the args!!!!!!!! |
141
|
|
|
|
|
|
|
length($arg_errlog) > 2 && $cnn ->HookError(">>$arg_errlog"); |
142
|
|
|
|
|
|
|
#${@$aref}[2] && $cnn ->HookError(">>$arg_errlog"); |
143
|
|
|
|
|
|
|
$arg_tralev ||= 1; # if trace level not specified then assume 1 |
144
|
|
|
|
|
|
|
length($arg_tralog) > 2 && $cnn ->HookTracing(">>$arg_tralog",$arg_tralev); |
145
|
|
|
|
|
|
|
#${@$aref}[3] && $cnn ->HookTracing(">>$arg_tralog",$arg_tralev); |
146
|
|
|
|
|
|
|
} |
147
|
|
|
|
|
|
|
shift @ChildConnect; |
148
|
|
|
|
|
|
|
# fudge this for now, need debugging!!!!!!!! |
149
|
|
|
|
|
|
|
last if @ChildConnect == 1; |
150
|
|
|
|
|
|
|
} |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
1; |
153
|
|
|
|
|
|
|
} |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
######################################################################################## |
156
|
|
|
|
|
|
|
######################################################################################## |
157
|
|
|
|
|
|
|
# The cleanup phase from within mod_perl will execute some code immediately after the |
158
|
|
|
|
|
|
|
# request has been served (the client went away) and before the request object is destroyed. |
159
|
|
|
|
|
|
|
# |
160
|
|
|
|
|
|
|
# The PerlCleanupHandler does nothing since Apache::BabyConnect relies on DBI::BabyConnect |
161
|
|
|
|
|
|
|
# to handle all DBI functions such as rollback when AutoCommit is off |
162
|
|
|
|
|
|
|
sub cleanup { |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
1; |
165
|
|
|
|
|
|
|
} |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
######################################################################################## |
168
|
|
|
|
|
|
|
######################################################################################## |
169
|
|
|
|
|
|
|
# ref: http://perl.apache.org/docs/2.0/api/Apache2/ServerUtil.html |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
sub get_child_init_handlers { |
172
|
|
|
|
|
|
|
my $s = Apache2::ServerUtil->server; |
173
|
|
|
|
|
|
|
my $handlers_list = $s-> get_handlers('PerlChildInitHandler'); |
174
|
|
|
|
|
|
|
#a list of references to the handler subroutines |
175
|
|
|
|
|
|
|
return $handlers_list; |
176
|
|
|
|
|
|
|
} |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
sub get_child_exit_handlers { |
179
|
|
|
|
|
|
|
my $s = Apache2::ServerUtil->server; |
180
|
|
|
|
|
|
|
my $handlers_list = $s-> get_handlers('PerlChildExitHandler') || []; |
181
|
|
|
|
|
|
|
return $handlers_list; |
182
|
|
|
|
|
|
|
} |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
sub parent_pid { |
185
|
|
|
|
|
|
|
return $parent_pid; |
186
|
|
|
|
|
|
|
} |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
sub cpids { |
189
|
|
|
|
|
|
|
my @a = split(/\n/,`ps --ppid $parent_pid`); |
190
|
|
|
|
|
|
|
my @cpid; |
191
|
|
|
|
|
|
|
foreach (@a) { |
192
|
|
|
|
|
|
|
if ($_ =~ m/^(\d+)/) { |
193
|
|
|
|
|
|
|
push(@cpid,$1); |
194
|
|
|
|
|
|
|
} |
195
|
|
|
|
|
|
|
} |
196
|
|
|
|
|
|
|
return @cpid; |
197
|
|
|
|
|
|
|
} |
198
|
|
|
|
|
|
|
######################################################################################## |
199
|
|
|
|
|
|
|
######################################################################################## |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
if (MP2) { |
202
|
|
|
|
|
|
|
if (Apache2::Module::loaded('Apache2::Status')) { |
203
|
|
|
|
|
|
|
Apache2::Status->menu_item( |
204
|
|
|
|
|
|
|
'BabyConnect' => 'BabyConnet for DBI connections', |
205
|
|
|
|
|
|
|
); |
206
|
|
|
|
|
|
|
} |
207
|
|
|
|
|
|
|
} |
208
|
|
|
|
|
|
|
else { |
209
|
|
|
|
|
|
|
if ($INC{'Apache.pm'} # is Apache loaded? |
210
|
|
|
|
|
|
|
and Apache->can('module') # really loaded? |
211
|
|
|
|
|
|
|
and Apache->module('Apache::Status')) { # and has an Apache::Status? |
212
|
|
|
|
|
|
|
Apache::Status->menu_item( |
213
|
|
|
|
|
|
|
'BabyConnect' => 'BabyConnect for DBI connections', |
214
|
|
|
|
|
|
|
); |
215
|
|
|
|
|
|
|
} |
216
|
|
|
|
|
|
|
} |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
1; |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
__END__ |