author | Junio C Hamano <gitster@pobox.com> | |
Tue, 22 Jun 2010 16:45:22 +0000 (09:45 -0700) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Tue, 22 Jun 2010 16:45:22 +0000 (09:45 -0700) |
* jn/gitweb-return-or-exit-cleanup:
gitweb: Return or exit after done serving request
Conflicts:
gitweb/gitweb.perl
gitweb: Return or exit after done serving request
Conflicts:
gitweb/gitweb.perl
1 | 2 | |||
---|---|---|---|---|
gitweb/gitweb.perl | patch | | diff1 | | diff2 | | blob | history |
diff --cc gitweb/gitweb.perl
index 9e5e0bf3ee6a86df6329da145f7f597e7abf491f,9d2b8c3b64fc50b96c7eb75c09520f3903d4845c..9446376535b1790c2400cd5bbc1e12f1a8b8f7c9
--- 1/gitweb/gitweb.perl
--- 2/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
set_message(\&handle_errors_html);
# dispatch
-if (!defined $action) {
- if (defined $hash) {
- $action = git_get_type($hash);
- } elsif (defined $hash_base && defined $file_name) {
- $action = git_get_type("$hash_base:$file_name");
- } elsif (defined $project) {
- $action = 'summary';
- } else {
- $action = 'project_list';
+sub dispatch {
+ if (!defined $action) {
+ if (defined $hash) {
+ $action = git_get_type($hash);
+ } elsif (defined $hash_base && defined $file_name) {
+ $action = git_get_type("$hash_base:$file_name");
+ } elsif (defined $project) {
+ $action = 'summary';
+ } else {
+ $action = 'project_list';
+ }
}
+ if (!defined($actions{$action})) {
+ die_error(400, "Unknown action");
+ }
+ if ($action !~ m/^(?:opml|project_list|project_index)$/ &&
+ !$project) {
+ die_error(400, "Project needed");
+ }
+ $actions{$action}->();
}
-if (!defined($actions{$action})) {
- die_error(400, "Unknown action");
+
+sub run_request {
+ our $t0 = [Time::HiRes::gettimeofday()]
+ if defined $t0;
+
+ evaluate_uri();
+ evaluate_gitweb_config();
+ evaluate_git_version();
+ check_loadavg();
+
+ # $projectroot and $projects_list might be set in gitweb config file
+ $projects_list ||= $projectroot;
+
+ evaluate_query_params();
+ evaluate_path_info();
+ evaluate_and_validate_params();
+ evaluate_git_dir();
+
+ configure_gitweb_features();
+
+ dispatch();
}
-if ($action !~ m/^(?:opml|project_list|project_index)$/ &&
- !$project) {
- die_error(400, "Project needed");
+
+our $is_last_request = sub { 1 };
+our ($pre_dispatch_hook, $post_dispatch_hook, $pre_listen_hook);
+our $CGI = 'CGI';
+our $cgi;
+sub configure_as_fcgi {
+ require CGI::Fast;
+ our $CGI = 'CGI::Fast';
+
+ my $request_number = 0;
+ # let each child service 100 requests
+ our $is_last_request = sub { ++$request_number > 100 };
}
-$actions{$action}->();
+sub evaluate_argv {
+ my $script_name = $ENV{'SCRIPT_NAME'} || $ENV{'SCRIPT_FILENAME'} || __FILE__;
+ configure_as_fcgi()
+ if $script_name =~ /\.fcgi$/;
+
+ return unless (@ARGV);
+
+ require Getopt::Long;
+ Getopt::Long::GetOptions(
+ 'fastcgi|fcgi|f' => \&configure_as_fcgi,
+ 'nproc|n=i' => sub {
+ my ($arg, $val) = @_;
+ return unless eval { require FCGI::ProcManager; 1; };
+ my $proc_manager = FCGI::ProcManager->new({
+ n_processes => $val,
+ });
+ our $pre_listen_hook = sub { $proc_manager->pm_manage() };
+ our $pre_dispatch_hook = sub { $proc_manager->pm_pre_dispatch() };
+ our $post_dispatch_hook = sub { $proc_manager->pm_post_dispatch() };
+ },
+ );
+}
+
+sub run {
+ evaluate_argv();
+
+ $pre_listen_hook->()
+ if $pre_listen_hook;
+
+ REQUEST:
+ while ($cgi = $CGI->new()) {
+ $pre_dispatch_hook->()
+ if $pre_dispatch_hook;
+
+ run_request();
+
+ $pre_dispatch_hook->()
+ if $post_dispatch_hook;
+
+ last REQUEST if ($is_last_request->());
+ }
+
+ DONE_GITWEB:
+ 1;
+}
+
+run();
-DONE_GITWEB:
+ if (defined caller) {
+ # wrapped in a subroutine processing requests,
+ # e.g. mod_perl with ModPerl::Registry, or PSGI with Plack::App::WrapCGI
+ return;
+ } else {
+ # pure CGI script, serving single request
+ exit;
+ }
+
## ======================================================================
## action links